1#!/usr/bin/ksh 2 3# 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. 8# 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. 12# 13 14# 15# Copyright (c) 2016 by Delphix. All rights reserved. 16# 17 18. $STF_SUITE/include/libtest.shlib 19. $STF_SUITE/tests/functional/cli_root/zpool_import/zpool_import.cfg 20 21# 22# Prototype cleanup function for zpool_import tests. 23# 24function cleanup 25{ 26 # clear any remaining zinjections 27 log_must zinject -c all > /dev/null 28 29 destroy_pool $TESTPOOL1 30 31 log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 $MD5FILE $MD5FILE2 32 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 39} 40 41# 42# Write a bit of data and sync several times. 43# This function is intended to be used by zpool rewind tests. 44# 45function sync_some_data_a_few_times 46{ 47 typeset pool=$1 48 typeset -i a_few_times=${2:-10} 49 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 55 56 return 0 57} 58 59# 60# Just write a moderate amount of data to the pool. 61# 62function write_some_data 63{ 64 typeset pool=$1 65 typeset files10mb=${2:-10} 66 67 typeset ds="$pool/fillerds" 68 zfs create $ds 69 [[ $? -ne 0 ]] && return 1 70 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 77 78 return 0 79} 80 81# 82# Create/overwrite a few datasets with files. 83# Apply md5sum on all the files and store checksums in a file. 84# 85# newdata: overwrite existing files if false. 86# md5file: file where to store md5sums 87# datasetname: base name for datasets 88# 89function _generate_data_common 90{ 91 typeset pool=$1 92 typeset newdata=$2 93 typeset md5file=$3 94 typeset datasetname=$4 95 96 typeset -i datasets=3 97 typeset -i files=5 98 typeset -i blocks=10 99 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 110 111 return 0 112} 113 114function generate_data 115{ 116 typeset pool=$1 117 typeset md5file="$2" 118 typeset datasetname=${3:-ds} 119 120 _generate_data_common $pool true "$md5file" $datasetname 121} 122 123function overwrite_data 124{ 125 typeset pool=$1 126 typeset md5file="$2" 127 typeset datasetname=${3:-ds} 128 129 _generate_data_common $1 false "$md5file" $datasetname 130} 131 132# 133# Verify md5sums of every file in md5sum file $1. 134# 135function verify_data_md5sums 136{ 137 typeset md5file=$1 138 139 if [[ ! -f $md5file ]]; then 140 log_note "md5 sums file '$md5file' doesn't exist" 141 return 1 142 fi 143 144 md5sum -c --quiet $md5file 145 return $? 146} 147 148# 149# Set devices size in DEVICE_DIR to $1. 150# 151function increase_device_sizes 152{ 153 typeset newfilesize=$1 154 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 160} 161 162# 163# Translate vdev names returned by zpool status into more generic names. 164# 165# eg: mirror-2 --> mirror 166# 167function _translate_vdev 168{ 169 typeset vdev=$1 170 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 177 fi 178 done 179 180 [[ $vdev == "logs" ]] && echo "log" && return 0 181 [[ $vdev == "raidz1" ]] && echo "raidz" && return 0 182 183 echo $vdev 184 return 0 185} 186 187# 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. 192# 193# eg: check_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0 log c1t1d0s0" 194# 195function check_pool_config 196{ 197 typeset logfailure=true 198 if [[ $1 == '-q' ]]; then 199 logfailure=false 200 shift 201 fi 202 203 typeset poolname=$1 204 typeset expected=$2 205 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" 211 fi 212 return 1 213 fi 214 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 222 fi 223 ( $began ) && [[ -z $vdev ]] && break; 224 225 if ( $began ); then 226 [[ -z $actual ]] && actual="$vdev" && continue 227 vdev=$(_translate_vdev $vdev) 228 actual="$actual $vdev" 229 fi 230 done 231 232 expected="$poolname $expected" 233 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'" 240 fi 241 return 1 242 fi 243 244 return 0 245} 246 247# 248# Check that pool configuration returned by zpool status matches expected 249# configuration within a given timeout in seconds. See check_pool_config(). 250# 251# eg: wait_for_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0" 60 252# 253function wait_for_pool_config 254{ 255 typeset poolname=$1 256 typeset expectedconfig="$2" 257 typeset -i timeout=${3:-60} 258 259 timeout=$(( $timeout + $(date +%s) )) 260 261 while (( $(date +%s) < $timeout )); do 262 check_pool_config -q $poolname "$expectedconfig" 263 [[ $? -eq 0 ]] && return 0 264 sleep 3 265 done 266 267 check_pool_config $poolname "$expectedconfig" 268 return $? 269} 270 271# 272# Check that pool status is ONLINE 273# 274function check_pool_healthy 275{ 276 typeset pool=$1 277 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 283 fi 284 285 status=$(echo "$status" | grep "$pool" | grep -v "pool:" | \ 286 awk '{print $2}') 287 288 if [[ $status != "ONLINE" ]]; then 289 log_note "Invalid zpool status for '$pool': '$status'" \ 290 "!= 'ONLINE'" 291 return 1 292 fi 293 294 return 0 295} 296 297# 298# Return 0 if a device is currently being replaced in the pool. 299# 300function pool_is_replacing 301{ 302 typeset pool=$1 303 304 zpool status $pool | grep "replacing" | grep "ONLINE" > /dev/null 305 306 return $? 307} 308 309function set_vdev_validate_skip 310{ 311 mdb_set_uint32 "vdev_validate_skip" "$1" 312} 313 314function get_zfs_txg_timeout 315{ 316 echo $(mdb_get_uint32 "zfs_txg_timeout") 317} 318 319function set_zfs_txg_timeout 320{ 321 mdb_set_uint32 "zfs_txg_timeout" "$1" 322} 323 324function set_spa_load_verify_metadata 325{ 326 mdb_set_uint32 "spa_load_verify_metadata" "$1" 327} 328 329function set_spa_load_verify_data 330{ 331 mdb_set_uint32 "spa_load_verify_data" "$1" 332} 333 334function set_zfs_max_missing_tvds 335{ 336 mdb_set_uint32 "zfs_max_missing_tvds" "$1" 337} 338 339# 340# Use mdb to find the last txg that was synced in an active pool. 341# 342function get_last_txg_synced 343{ 344 typeset pool=$1 345 346 typeset spas 347 spas=$(mdb -k -e "::spa") 348 [[ $? -ne 0 ]] && return 1 349 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 357 fi 358 done 359 if [[ -z $spa ]]; then 360 log_fail "Couldn't find pool '$pool'" 361 return 1 362 fi 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 367 368 echo $txg 369 return 0 370} 371