Unleashed v1.4
[unleashed.git] / usr / src / test / zfs-tests / tests / functional / cli_root / zpool_import / zpool_import.kshlib
blobc32f72b504a9376db96800edb7e2430706cb217d
1 #!/usr/bin/ksh
4 # This file and its contents are supplied under the terms of the
5 # Common Development and Distribution License ("CDDL"), version 1.0.
6 # You may only use this file in accordance with the terms of version
7 # 1.0 of the CDDL.
9 # A full copy of the text of the CDDL should have accompanied this
10 # source. A copy of the CDDL is also available via the Internet at
11 # http://www.illumos.org/license/CDDL.
15 # Copyright (c) 2016 by Delphix. All rights reserved.
18 . $STF_SUITE/include/libtest.shlib
19 . $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg
22 # Prototype cleanup function for zpool_import tests.
24 function cleanup
26 # clear any remaining zinjections
27 log_must zinject -c all > /dev/null
29 destroy_pool $TESTPOOL1
31 log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 $MD5FILE $MD5FILE2
33 log_must rm -rf $DEVICE_DIR/*
34 typeset i=0
35 while (( i < $MAX_NUM )); do
36 log_must mkfile $FILE_SIZE ${DEVICE_DIR}/${DEVICE_FILE}$i
37 ((i += 1))
38 done
42 # Write a bit of data and sync several times.
43 # This function is intended to be used by zpool rewind tests.
45 function sync_some_data_a_few_times
47 typeset pool=$1
48 typeset -i a_few_times=${2:-10}
50 typeset file="/$pool/tmpfile"
51 for i in {0..$a_few_times}; do
52 dd if=/dev/urandom of=${file}_$i bs=128k count=10
53 sync
54 done
56 return 0
60 # Just write a moderate amount of data to the pool.
62 function write_some_data
64 typeset pool=$1
65 typeset files10mb=${2:-10}
67 typeset ds="$pool/fillerds"
68 zfs create $ds
69 [[ $? -ne 0 ]] && return 1
71 # Create 100 MB of data
72 typeset file="/$ds/fillerfile"
73 for i in {1..$files10mb}; do
74 dd if=/dev/urandom of=$file.$i bs=128k count=80
75 [[ $? -ne 0 ]] && return 1
76 done
78 return 0
82 # Create/overwrite a few datasets with files.
83 # Apply md5sum on all the files and store checksums in a file.
85 # newdata: overwrite existing files if false.
86 # md5file: file where to store md5sums
87 # datasetname: base name for datasets
89 function _generate_data_common
91 typeset pool=$1
92 typeset newdata=$2
93 typeset md5file=$3
94 typeset datasetname=$4
96 typeset -i datasets=3
97 typeset -i files=5
98 typeset -i blocks=10
100 [[ -n $md5file ]] && rm -f $md5file
101 for i in {1..$datasets}; do
102 ( $newdata ) && log_must zfs create "$pool/$datasetname$i"
103 for j in {1..$files}; do
104 typeset file="/$pool/$datasetname$i/file$j"
105 dd if=/dev/urandom of=$file bs=128k count=$blocks > /dev/null
106 [[ -n $md5file ]] && md5sum $file >> $md5file
107 done
108 ( $newdata ) && sync
109 done
111 return 0
114 function generate_data
116 typeset pool=$1
117 typeset md5file="$2"
118 typeset datasetname=${3:-ds}
120 _generate_data_common $pool true "$md5file" $datasetname
123 function overwrite_data
125 typeset pool=$1
126 typeset md5file="$2"
127 typeset datasetname=${3:-ds}
129 _generate_data_common $1 false "$md5file" $datasetname
133 # Verify md5sums of every file in md5sum file $1.
135 function verify_data_md5sums
137 typeset md5file=$1
139 if [[ ! -f $md5file ]]; then
140 log_note "md5 sums file '$md5file' doesn't exist"
141 return 1
144 md5sum -c --quiet $md5file
145 return $?
149 # Set devices size in DEVICE_DIR to $1.
151 function increase_device_sizes
153 typeset newfilesize=$1
155 typeset -i i=0
156 while (( i < $MAX_NUM )); do
157 log_must mkfile $newfilesize ${DEVICE_DIR}/${DEVICE_FILE}$i
158 ((i += 1))
159 done
163 # Translate vdev names returned by zpool status into more generic names.
165 # eg: mirror-2 --> mirror
167 function _translate_vdev
169 typeset vdev=$1
171 typeset keywords="mirror replacing raidz1 raidz2 raidz3 indirect"
172 for word in $keywords; do
173 echo $vdev | egrep "^${word}-[0-9]+\$" > /dev/null
174 if [[ $? -eq 0 ]]; then
175 vdev=$word
176 break
178 done
180 [[ $vdev == "logs" ]] && echo "log" && return 0
181 [[ $vdev == "raidz1" ]] && echo "raidz" && return 0
183 echo $vdev
184 return 0
188 # Check that pool configuration returned by zpool status matches expected
189 # configuration. Format for the check string is same as the vdev arguments for
190 # creating a pool
191 # Add -q for quiet mode.
193 # eg: check_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0 log c1t1d0s0"
195 function check_pool_config
197 typeset logfailure=true
198 if [[ $1 == '-q' ]]; then
199 logfailure=false
200 shift
203 typeset poolname=$1
204 typeset expected=$2
206 typeset status
207 status=$(zpool status $poolname 2>&1)
208 if [[ $? -ne 0 ]]; then
209 if ( $logfailure ); then
210 log_note "zpool status $poolname failed: $status"
212 return 1
215 typeset actual=""
216 typeset began=false
217 printf "$status\n" | while read line; do
218 typeset vdev=$(echo "$line" | awk '{printf $1}')
219 if ( ! $began ) && [[ $vdev == NAME ]]; then
220 began=true
221 continue
223 ( $began ) && [[ -z $vdev ]] && break;
225 if ( $began ); then
226 [[ -z $actual ]] && actual="$vdev" && continue
227 vdev=$(_translate_vdev $vdev)
228 actual="$actual $vdev"
230 done
232 expected="$poolname $expected"
234 if [[ "$actual" != "$expected" ]]; then
235 if ( $logfailure ); then
236 log_note "expected pool vdevs:"
237 log_note "> '$expected'"
238 log_note "actual pool vdevs:"
239 log_note "> '$actual'"
241 return 1
244 return 0
248 # Check that pool configuration returned by zpool status matches expected
249 # configuration within a given timeout in seconds. See check_pool_config().
251 # eg: wait_for_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0" 60
253 function wait_for_pool_config
255 typeset poolname=$1
256 typeset expectedconfig="$2"
257 typeset -i timeout=${3:-60}
259 timeout=$(( $timeout + $(date +%s) ))
261 while (( $(date +%s) < $timeout )); do
262 check_pool_config -q $poolname "$expectedconfig"
263 [[ $? -eq 0 ]] && return 0
264 sleep 3
265 done
267 check_pool_config $poolname "$expectedconfig"
268 return $?
272 # Check that pool status is ONLINE
274 function check_pool_healthy
276 typeset pool=$1
278 typeset status
279 status=$(zpool status $pool 2>&1)
280 if [[ $? -ne 0 ]]; then
281 log_note "zpool status $pool failed: $status"
282 return 1
285 status=$(echo "$status" | grep "$pool" | grep -v "pool:" | \
286 awk '{print $2}')
288 if [[ $status != "ONLINE" ]]; then
289 log_note "Invalid zpool status for '$pool': '$status'" \
290 "!= 'ONLINE'"
291 return 1
294 return 0
298 # Return 0 if a device is currently being replaced in the pool.
300 function pool_is_replacing
302 typeset pool=$1
304 zpool status $pool | grep "replacing" | grep "ONLINE" > /dev/null
306 return $?
309 function set_vdev_validate_skip
311 mdb_set_uint32 "vdev_validate_skip" "$1"
314 function get_zfs_txg_timeout
316 echo $(mdb_get_uint32 "zfs_txg_timeout")
319 function set_zfs_txg_timeout
321 mdb_set_uint32 "zfs_txg_timeout" "$1"
324 function set_spa_load_verify_metadata
326 mdb_set_uint32 "spa_load_verify_metadata" "$1"
329 function set_spa_load_verify_data
331 mdb_set_uint32 "spa_load_verify_data" "$1"
334 function set_zfs_max_missing_tvds
336 mdb_set_uint32 "zfs_max_missing_tvds" "$1"
340 # Use mdb to find the last txg that was synced in an active pool.
342 function get_last_txg_synced
344 typeset pool=$1
346 typeset spas
347 spas=$(mdb -k -e "::spa")
348 [[ $? -ne 0 ]] && return 1
350 typeset spa=""
351 print "$spas\n" | while read line; do
352 typeset poolname=$(echo "$line" | awk '{print $3}')
353 typeset addr=$(echo "$line" | awk '{print $1}')
354 if [[ $poolname == $pool ]]; then
355 spa=$addr
356 break
358 done
359 if [[ -z $spa ]]; then
360 log_fail "Couldn't find pool '$pool'"
361 return 1
363 typeset mdbcmd="$spa::print spa_t spa_ubsync.ub_txg | ::eval '.=E'"
364 typeset -i txg
365 txg=$(mdb -k -e "$mdbcmd")
366 [[ $? -ne 0 ]] && return 1
368 echo $txg
369 return 0