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