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 destroy_pool $TESTPOOL1 27 28 log_must rm -f $CPATH $CPATHBKP $CPATHBKP2 $MD5FILE $MD5FILE2 29 30 log_must rm -rf $DEVICE_DIR/* 31 typeset i=0 32 while (( i < $MAX_NUM )); do 33 log_must mkfile $FILE_SIZE ${DEVICE_DIR}/${DEVICE_FILE}$i 34 ((i += 1)) 35 done 36} 37 38# 39# Write a bit of data and sync several times. 40# This function is intended to be used by zpool rewind tests. 41# 42function sync_some_data_a_few_times 43{ 44 typeset pool=$1 45 typeset -i a_few_times=${2:-10} 46 47 typeset file="/$pool/tmpfile" 48 for i in {0..$a_few_times}; do 49 dd if=/dev/urandom of=${file}_$i bs=128k count=10 50 sync 51 done 52 53 return 0 54} 55 56# 57# Just write a moderate amount of data to the pool. 58# 59function write_some_data 60{ 61 typeset pool=$1 62 typeset files10mb=${2:-10} 63 64 typeset ds="$pool/fillerds" 65 zfs create $ds 66 [[ $? -ne 0 ]] && return 1 67 68 # Create 100 MB of data 69 typeset file="/$ds/fillerfile" 70 for i in {1..$files10mb}; do 71 dd if=/dev/urandom of=$file.$i bs=128k count=80 72 [[ $? -ne 0 ]] && return 1 73 done 74 75 return 0 76} 77 78# 79# Create/overwrite a few datasets with files. 80# Apply md5sum on all the files and store checksums in a file. 81# 82# newdata: overwrite existing files if false. 83# md5file: file where to store md5sums 84# datasetname: base name for datasets 85# 86function _generate_data_common 87{ 88 typeset pool=$1 89 typeset newdata=$2 90 typeset md5file=$3 91 typeset datasetname=$4 92 93 typeset -i datasets=3 94 typeset -i files=5 95 typeset -i blocks=10 96 97 [[ -n $md5file ]] && rm -f $md5file 98 for i in {1..$datasets}; do 99 ( $newdata ) && log_must zfs create "$pool/$datasetname$i" 100 for j in {1..$files}; do 101 typeset file="/$pool/$datasetname$i/file$j" 102 dd if=/dev/urandom of=$file bs=128k count=$blocks > /dev/null 103 [[ -n $md5file ]] && md5sum $file >> $md5file 104 done 105 ( $newdata ) && sync 106 done 107 108 return 0 109} 110 111function generate_data 112{ 113 typeset pool=$1 114 typeset md5file="$2" 115 typeset datasetname=${3:-ds} 116 117 _generate_data_common $pool true "$md5file" $datasetname 118} 119 120function overwrite_data 121{ 122 typeset pool=$1 123 typeset md5file="$2" 124 typeset datasetname=${3:-ds} 125 126 _generate_data_common $1 false "$md5file" $datasetname 127} 128 129# 130# Verify md5sums of every file in md5sum file $1. 131# 132function verify_data_md5sums 133{ 134 typeset md5file=$1 135 136 if [[ ! -f $md5file ]]; then 137 log_note "md5 sums file '$md5file' doesn't exist" 138 return 1 139 fi 140 141 md5sum -c --quiet $md5file 142 return $? 143} 144 145# 146# Set devices size in DEVICE_DIR to $1. 147# 148function increase_device_sizes 149{ 150 typeset newfilesize=$1 151 152 typeset -i i=0 153 while (( i < $MAX_NUM )); do 154 log_must mkfile $newfilesize ${DEVICE_DIR}/${DEVICE_FILE}$i 155 ((i += 1)) 156 done 157} 158 159# 160# Translate vdev names returned by zpool status into more generic names. 161# 162# eg: mirror-2 --> mirror 163# 164function _translate_vdev 165{ 166 typeset vdev=$1 167 168 typeset keywords="mirror replacing raidz1 raidz2 raidz3 indirect" 169 for word in $keywords; do 170 echo $vdev | egrep "^${word}-[0-9]+\$" > /dev/null 171 if [[ $? -eq 0 ]]; then 172 vdev=$word 173 break 174 fi 175 done 176 177 [[ $vdev == "logs" ]] && echo "log" && return 0 178 [[ $vdev == "raidz1" ]] && echo "raidz" && return 0 179 180 echo $vdev 181 return 0 182} 183 184# 185# Check that pool configuration returned by zpool status matches expected 186# configuration. Format for the check string is same as the vdev arguments for 187# creating a pool 188# Add -q for quiet mode. 189# 190# eg: check_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0 log c1t1d0s0" 191# 192function check_pool_config 193{ 194 typeset logfailure=true 195 if [[ $1 == '-q' ]]; then 196 logfailure=false 197 shift 198 fi 199 200 typeset poolname=$1 201 typeset expected=$2 202 203 typeset status 204 status=$(zpool status $poolname 2>&1) 205 if [[ $? -ne 0 ]]; then 206 if ( $logfailure ); then 207 log_note "zpool status $poolname failed: $status" 208 fi 209 return 1 210 fi 211 212 typeset actual="" 213 typeset began=false 214 printf "$status\n" | while read line; do 215 typeset vdev=$(echo "$line" | awk '{printf $1}') 216 if ( ! $began ) && [[ $vdev == NAME ]]; then 217 began=true 218 continue 219 fi 220 ( $began ) && [[ -z $vdev ]] && break; 221 222 if ( $began ); then 223 [[ -z $actual ]] && actual="$vdev" && continue 224 vdev=$(_translate_vdev $vdev) 225 actual="$actual $vdev" 226 fi 227 done 228 229 expected="$poolname $expected" 230 231 if [[ "$actual" != "$expected" ]]; then 232 if ( $logfailure ); then 233 log_note "expected pool vdevs:" 234 log_note "> '$expected'" 235 log_note "actual pool vdevs:" 236 log_note "> '$actual'" 237 fi 238 return 1 239 fi 240 241 return 0 242} 243 244# 245# Check that pool configuration returned by zpool status matches expected 246# configuration within a given timeout in seconds. See check_pool_config(). 247# 248# eg: wait_for_pool_config pool1 "mirror c0t0d0s0 c0t1d0s0" 60 249# 250function wait_for_pool_config 251{ 252 typeset poolname=$1 253 typeset expectedconfig="$2" 254 typeset -i timeout=${3:-60} 255 256 timeout=$(( $timeout + $(date +%s) )) 257 258 while (( $(date +%s) < $timeout )); do 259 check_pool_config -q $poolname "$expectedconfig" 260 [[ $? -eq 0 ]] && return 0 261 sleep 3 262 done 263 264 check_pool_config $poolname "$expectedconfig" 265 return $? 266} 267 268# 269# Check that pool status is ONLINE 270# 271function check_pool_healthy 272{ 273 typeset pool=$1 274 275 typeset status 276 status=$(zpool status $pool 2>&1) 277 if [[ $? -ne 0 ]]; then 278 log_note "zpool status $pool failed: $status" 279 return 1 280 fi 281 282 status=$(echo "$status" | grep "$pool" | grep -v "pool:" | \ 283 awk '{print $2}') 284 285 if [[ $status != "ONLINE" ]]; then 286 log_note "Invalid zpool status for '$pool': '$status'" \ 287 "!= 'ONLINE'" 288 return 1 289 fi 290 291 return 0 292} 293 294# 295# Return 0 if a device is currently being replaced in the pool. 296# 297function pool_is_replacing 298{ 299 typeset pool=$1 300 301 zpool status $pool | grep "replacing" | grep "ONLINE" > /dev/null 302 303 return $? 304} 305 306function set_vdev_validate_skip 307{ 308 mdb_set_uint32 "vdev_validate_skip" "$1" 309} 310 311function get_zfs_txg_timeout 312{ 313 echo $(mdb_get_uint32 "zfs_txg_timeout") 314} 315 316function set_zfs_txg_timeout 317{ 318 mdb_set_uint32 "zfs_txg_timeout" "$1" 319} 320 321function set_spa_load_verify_metadata 322{ 323 mdb_set_uint32 "spa_load_verify_metadata" "$1" 324} 325 326function set_spa_load_verify_data 327{ 328 mdb_set_uint32 "spa_load_verify_data" "$1" 329} 330 331function set_zfs_max_missing_tvds 332{ 333 mdb_set_uint32 "zfs_max_missing_tvds" "$1" 334} 335 336# 337# Use mdb to find the last txg that was synced in an active pool. 338# 339function get_last_txg_synced 340{ 341 typeset pool=$1 342 343 typeset spas 344 spas=$(mdb -k -e "::spa") 345 [[ $? -ne 0 ]] && return 1 346 347 typeset spa="" 348 print "$spas\n" | while read line; do 349 typeset poolname=$(echo "$line" | awk '{print $3}') 350 typeset addr=$(echo "$line" | awk '{print $1}') 351 if [[ $poolname == $pool ]]; then 352 spa=$addr 353 break 354 fi 355 done 356 if [[ -z $spa ]]; then 357 log_fail "Couldn't find pool '$pool'" 358 return 1 359 fi 360 typeset mdbcmd="$spa::print spa_t spa_ubsync.ub_txg | ::eval '.=E'" 361 typeset -i txg 362 txg=$(mdb -k -e "$mdbcmd") 363 [[ $? -ne 0 ]] && return 1 364 365 echo $txg 366 return 0 367} 368