1#! /bin/ksh -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or https://opensource.org/licenses/CDDL-1.0. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27 28# 29# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 30# Copyright (c) 2018 by Lawrence Livermore National Security, LLC. 31# 32 33. $STF_SUITE/include/libtest.shlib 34. $STF_SUITE/tests/functional/cli_root/zpool_expand/zpool_expand.cfg 35 36# 37# DESCRIPTION: 38# Once zpool set autoexpand=on poolname, zpool can autoexpand by 39# Dynamic VDEV Expansion 40# 41# 42# STRATEGY: 43# 1) Create three vdevs (loopback, scsi_debug, and file) 44# 2) Create pool by using the different devices and set autoexpand=on 45# 3) Expand each device as appropriate 46# 4) Check that the pool size was expanded 47# 48# NOTE: Three different device types are used in this test to verify 49# expansion of non-partitioned block devices (loopback), partitioned 50# block devices (scsi_debug), and non-disk file vdevs. ZFS volumes 51# are not used in order to avoid a possible lock inversion when 52# layering pools on zvols. 53# 54 55verify_runnable "global" 56 57# We override $org_size and $exp_size from zpool_expand.cfg to make sure we get 58# an expected free space value every time. Otherwise, if we left it 59# configurable, the free space ratio to pool size ratio would diverge too much 60# much at low $org_size values. 61# 62org_size=$((1024 * 1024 * 1024)) 63exp_size=$(($org_size * 2)) 64 65function cleanup 66{ 67 poolexists $TESTPOOL1 && destroy_pool $TESTPOOL1 68 69 if losetup -a | grep -q $DEV1; then 70 losetup -d $DEV1 71 fi 72 73 rm -f $FILE_LO $FILE_RAW 74 75 block_device_wait 76 unload_scsi_debug 77} 78 79# Wait for the size of a pool to autoexpand to $1 and the total free space to 80# expand to $2 (both values allowing a 10% tolerance). 81# 82# Wait for up to 10 seconds for this to happen (typically takes 1-2 seconds) 83# 84function wait_for_autoexpand 85{ 86 typeset exp_new_size=$1 87 typeset exp_new_free=$2 88 89 for i in $(seq 1 10) ; do 90 typeset new_size=$(get_pool_prop size $TESTPOOL1) 91 typeset new_free=$(get_prop avail $TESTPOOL1) 92 # Values need to be within 90% of each other (10% tolerance) 93 if within_percent $new_size $exp_new_size 90 > /dev/null && \ 94 within_percent $new_free $exp_new_free 90 > /dev/null ; then 95 return 96 fi 97 sleep 1 98 done 99 log_fail "$TESTPOOL never expanded to $exp_new_size with $exp_new_free" \ 100 " free space (got $new_size with $new_free free space)" 101} 102 103log_onexit cleanup 104 105log_assert "zpool can be autoexpanded after set autoexpand=on on vdev expansion" 106 107for type in " " mirror raidz draid:1s; do 108 log_note "Setting up loopback, scsi_debug, and file vdevs" 109 log_must truncate -s $org_size $FILE_LO 110 DEV1=$(losetup -f) 111 log_must losetup $DEV1 $FILE_LO 112 113 load_scsi_debug $org_size_mb 1 1 1 '512b' 114 block_device_wait 115 DEV2=$(get_debug_device) 116 117 log_must truncate -s $org_size $FILE_RAW 118 DEV3=$FILE_RAW 119 120 # The -f is required since we're mixing disk and file vdevs. 121 log_must zpool create -f -o autoexpand=on $TESTPOOL1 $type \ 122 $DEV1 $DEV2 $DEV3 123 124 typeset autoexp=$(get_pool_prop autoexpand $TESTPOOL1) 125 if [[ $autoexp != "on" ]]; then 126 log_fail "zpool $TESTPOOL1 autoexpand should be on but is " \ 127 "$autoexp" 128 fi 129 130 typeset prev_size=$(get_pool_prop size $TESTPOOL1) 131 typeset zfs_prev_size=$(get_prop avail $TESTPOOL1) 132 133 # Expand each device as appropriate being careful to add an artificial 134 # delay to ensure we get a single history entry for each. This makes 135 # is easier to verify each expansion for the striped pool case, since 136 # they will not be merged in to a single larger expansion. 137 log_note "Expanding loopback, scsi_debug, and file vdevs" 138 log_must truncate -s $exp_size $FILE_LO 139 log_must losetup -c $DEV1 140 141 echo "2" > /sys/bus/pseudo/drivers/scsi_debug/virtual_gb 142 echo "1" > /sys/class/block/$DEV2/device/rescan 143 block_device_wait 144 145 log_must truncate -s $exp_size $FILE_RAW 146 log_must zpool online -e $TESTPOOL1 $FILE_RAW 147 148 149 # The expected free space values below were observed at the time of 150 # this commit. However, we know ZFS overhead will change over time, 151 # and thus we do not do an exact comparison to these values in 152 # wait_for_autoexpand. Rather, we make sure the free space 153 # is within some small percentage threshold of these values. 154 typeset exp_new_size=$(($prev_size * 2)) 155 if [[ "$type" == " " ]] ; then 156 exp_new_free=6045892608 157 elif [[ "$type" == "mirror" ]] ; then 158 exp_new_free=1945997312 159 elif [[ "$type" == "raidz" ]] ; then 160 exp_new_free=3977637338 161 elif [[ "$type" == "draid:1s" ]] then 162 exp_new_free=1946000384 163 fi 164 165 wait_for_autoexpand $exp_new_size $exp_new_free 166 167 expand_size=$(get_pool_prop size $TESTPOOL1) 168 169 log_note "$TESTPOOL1 '$type' grew from $prev_size -> $expand_size with" \ 170 "free space from $zfs_prev_size -> $(get_prop avail $TESTPOOL1)" 171 172 cleanup 173done 174 175log_pass "zpool can autoexpand if autoexpand=on after vdev expansion" 176