1# vim: filetype=sh 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 http://www.opensolaris.org/os/licensing. 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 2008 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26 27. $STF_SUITE/include/libtest.kshlib 28. $STF_SUITE/include/libgnop.kshlib 29. $STF_SUITE/tests/hotplug/hotplug.cfg 30 31# 32# create lofi devices 33# 34# $1-n files 35# 36function create_lofi_device 37{ 38 typeset lofi_files="$@" 39 40 typeset file 41 for file in $lofi_files ; do 42 if ! $LOFIADM $file > /dev/null 2>&1 ; then 43 insert_device $file 44 if (($? != 0)); then 45 return 1 46 fi 47 fi 48 49 shift 50 done 51 52 return 0 53} 54 55# 56# Check and destroy lofi devices 57# 58# $1-n lofi files or deviece 59# 60function destroy_lofi_device 61{ 62 typeset -i ret=0 63 typeset dev_file="$@" 64 65 typeset file 66 for file in $dev_file ; do 67 if $LOFIADM $file > /dev/null 2>&1; then 68 $LOFIADM -d $file -f 69 if (($? != 0)); then 70 ((ret += 1)) 71 fi 72 fi 73 done 74 75 return $ret 76} 77 78# 79# Setup test environment using DISKS[1-4] 80# 81# $1 pool type 82# 83function setup_testenv 84{ 85 typeset type=$1 86 87 if [[ -z $type ]]; then 88 log_fail "Usage: setup_testenv <type>" 89 fi 90 91 log_must $ZPOOL create -f \ 92 $TESTPOOL $type ${DISK0}.nop ${DISK1}.nop ${DISK2}.nop ${DISK3}.nop 93} 94 95# 96# Cleanup test envirnment according to pool name 97# 98# $1 pool 99# 100function cleanup_testenv 101{ 102 destroy_pool $TESTPOOL 103} 104 105 106# 107# Start a background process to write file on given pool. 108# 109# $1 pool 110# 111function start_bg_write 112{ 113 typeset pool=$1 114 115 if datasetnonexists $pool; then 116 return 1 117 fi 118 119 typeset mntpnt=$(get_prop mountpoint $pool) 120 121 while true; do 122 $DD if=/dev/random of=$mntpnt/foo count=10 123 $SYNC 124 $SLEEP 1 125 done & 126 BG_PID=$! 127 128 return 0 129} 130 131# 132# Kill the background write process. 133# 134function kill_bg_write 135{ 136 typeset -i ret=0 137 138 if [[ -n $BG_PID ]]; then 139 kill -9 $BG_PID 140 ret=$? 141 142 if ((ret == 0)); then 143 BG_PID='' 144 fi 145 fi 146 147 $SLEEP 10 148 return $ret 149} 150 151# 152# Insert a given file into a given device slot 153# 154# $1 file 155# $2 device 156# 157function insert_device 158{ 159 typeset file=$1 160 typeset device=$2 161 162 if [[ -z $file ]]; then 163 return 1 164 fi 165 166 # 167 # Make sure insert device succeed within 60 seconds 168 # 169 typeset -i i=0 170 while ((i < 6)); do 171 $SLEEP 10 172 173 $LOFIADM -a $file $device -f > /dev/null 2>&1 174 if (($? == 0)); then 175 return 0 176 fi 177 178 ((i += 1)) 179 done 180 181 return 1 182} 183 184# 185# Remove the given lofi device 186# 187# $1 device or file 188# 189function remove_device 190{ 191 typeset devfile=$1 192 193 if [[ -z $devfile ]]; then 194 return 1 195 fi 196 197 # 198 # Make sure remove device succeed within 60 seconds 199 # 200 typeset -i i=0 201 while ((i < 6)); do 202 $SLEEP 10 203 $LOFIADM -d $devfile -f 204 if (($? == 0)); then 205 return 0 206 fi 207 208 ((i += 1)) 209 done 210 211 return 1 212} 213 214# 215# Verify the given devices have expected status in pool 216# 217# $1 pool 218# $2 device 219# $3 expected status 220# 221function verify_device_status 222{ 223 typeset pool=$1 224 typeset device=$2 225 typeset expect_stat=$3 226 227 if [[ -z $pool || -z $expect_stat || -z $device ]]; then 228 log_note "Usage: verify_device_status <pool> <device> <status>" 229 return 1 230 fi 231 232 # 233 # 1.5 minute disk status checking, make sure zpool sync disk status. 234 # 235 typeset -i i=0 236 while ((i < 9)); do 237 $SLEEP 10 238 239 typeset str=$($ZPOOL status $pool | $GREP "lofi" | \ 240 $AWK '{print $1 " " $2}') 241 typeset real_stat=${str##*$device } 242 real_stat=$($ECHO $real_stat | $AWK '{print $1}') 243 244 if [[ "$expect_stat" == "$real_stat" ]]; then 245 return 0 246 fi 247 248 ((i += 1)) 249 done 250 251 log_note "Expected status($expect_stat), " \ 252 "see status($real_stat) for $device" 253 $ZPOOL status -v $pool 254 255 return 1 256} 257 258# 259# Output fma event id to given file, the default output file is $FILE_EVENT_ID 260# 261function getfmri 262{ 263 eval typeset output_file=${1:-$FILE_EVENT_ID} 264# 265# fmadm faulty output include several sections below 266# 267 268# --------------- ------------------------------------ -------------- --------- 269# TIME EVENT-ID MSG-ID SEVERITY 270# --------------- ------------------------------------ -------------- --------- 271# Aug 31 22:34:19 ec648a9e-0c9f-c495-e176-e38ba212e278 ZFS-8000-D3 Major 272# Aug 31 19:44:59 d69cdd12-b0cf-62ea-d0a3-8d2e9ebfeb50 ZFS-8000-D3 273# Aug 31 19:35:16 7213f0d5-00d4-ea32-ddfc-98cdd683c27e ZFS-8000-D3 274# Aug 31 19:29:11 33424bef-a973-4dae-94ef-cb97f2cb0759 ZFS-8000-D3 275# Aug 31 17:07:26 74219b66-ead4-6d2b-bbad-bc40547ca02e ZFS-8000-GH 276# 277# Fault class : fault.fs.zfs.device 278# 279# Description : A ZFS device failed. Refer to http://sun.com/msg/ZFS-8000-D3 for 280# more information. 281# 282# Response : No automated response will occur. 283# 284# Impact : Fault tolerance of the pool may be compromised. 285# 286# Action : Run 'zpool status -x' and replace the bad device. 287# 288 $FMADM faulty | $NAWK ' 289 BEGIN { 290 start = 0 291 } 292 /^---/ && /---$/ { 293 if (start == 0) { 294 start = 1 295 } 296 } 297 /^TIME/ && /SEVERITY$/ { 298 if (start == 1) { 299 start = 2 300 } 301 } 302 /^---/ && /---$/ { 303 if (start == 2) { 304 start = 3 305 continue 306 } 307 } 308 /^$/ { 309 start = 0 310 } 311 (start == 3) {print $4}' > $output_file 312} 313 314# 315# Verify if ZFS FMA faulty error message are generated. 316# 317# $1 TRUE or FALSE 318# 319function fma_faulty 320{ 321 # 322 # 1.5 minute for FMA faulty checking, make sure FMA sync with ZFS status 323 # 324 typeset expect=${1:-TRUE} 325 326 typeset -i fsize 327 typeset -i i=0 328 while ((i < 9)); do 329 $SLEEP 10 330 331 # 332 # try to get fma faulty 333 # 334 getfmri $FILE_EVENT_ID 335 fsize=$($LS -ld $FILE_EVENT_ID | $AWK '{print $5}') 336 337 case $expect in 338 TRUE) 339 if (( fsize != 0 )); then 340 return 0 341 fi 342 ;; 343 FALSE) 344 if (( fsize == 0 )); then 345 return 0 346 fi 347 ;; 348 *) 349 return 1 350 esac 351 352 ((i += 1)) 353 done 354 355 return 1 356} 357 358# 359# Create fresh file 360# 361# $1 file size 362# $2 file name 363# 364function create_file 365{ 366 typeset size=$1 367 typeset file=$2 368 369 if [[ -z $size || -z $file ]]; then 370 log_note "Usage: create_file <size> <file>" 371 return 1 372 fi 373 if [[ -f $file ]]; then 374 $RM -f $file 375 fi 376 $MKFILE $size $file 377 return $? 378} 379 380# 381# Unmount all filesystem, and disable syseventd and fmd piror to 382# unloading ZFS module 383# 384function unload_zfs 385{ 386 # destroy /dev/zvol link 387 log_must $ZFS volfini 388 389 log_must $ZFS unmount -f -a 390 log_must $SVCADM disable -t sysevent fmd 391 $SLEEP 10 392 393 # 394 # 1 minute for ZFS module unload checking 395 # 396 # For example: 397 # 398 # 192 fffffffff7c92000 99858 182 1 zfs (ZFS storage pool version 6) 399 # 400 typeset -i i=0 401 while ((i < 10)); do 402 typeset id=$($MODINFO | $GREP "ZFS storage" | $AWK '{print $1}') 403 404 if [[ -n $id ]]; then 405 $MODUNLOAD -i $id 406 if (($? == 0)) ; then 407 return 0 408 fi 409 else 410 return 0 411 fi 412 413 $SLEEP 6 414 ((i += 1)) 415 done 416 417 return 1 418} 419 420# 421# Load ZFS module and remount all filesystem 422# 423function load_zfs 424{ 425 typeset -i ret=0 426 $SVCADM enable sysevent fmd 427 ((ret |= $?)) 428 429 $SLEEP 10 430 431 $ZFS mount -a 432 ((ret |= $?)) 433 434 # create /dev/zvol link 435 $ZFS volinit 436 ((ret |= $?)) 437 438 return $ret 439} 440 441# 442# Convert file name to device name or reverse. 443# 444# $1-n lofi files or devices 445# 446function convert_lofi 447{ 448 typeset n list 449 450 for n in "$@"; do 451 typeset item=$($LOFIADM $n) 452 list="$list $item" 453 454 shift 455 done 456 457 $ECHO $list 458} 459