# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #pragma ident "%Z%%M% %I% %E% SMI" # # usage: force_state_change # proc force_state_change { [[ $2 != "online" && $2 != "offline" ]] && exit 1 th_manage $1 getstate | read path state busy [[ $? != 0 ]] && exit 1 [[ "$state" = "$2" ]] && return 0 th_manage $1 $2 [[ $? != 0 ]] && exit 1 th_manage $1 getstate | read path state busy [[ $? != 0 ]] && exit 1 [[ "$state" != "$2" ]] && exit 1 return 0 } setvar script_pid = '0' trap ' terminate $script_pid ' 1 2 3 15 proc terminate { [[ $1 -gt 0 ]] && kill $1 > /dev/null 2>&1 exit 1 } # # usage: control_workload # The following function is called (as a background task) prior to taking a # driver instance offline and immediately after it is brought online. If the # th_define process which created this script did not specify a script with the # -e option then the default action is to run in the background this script # which will continuously offline and online the instance until the injected # error is detected by the driver or until the errdef is aborted. # proc control_workload { fixup_script 1 if test $Status == 0 { return } # # Default workload - continuously offline and online the driver instance # while injecting errors # if [[ $2 -gt 0 ]] { kill $2 > /dev/null 2>&1 } if test $Argc -lt 2 { echo syntax: $0 path pid } elif test $DRIVER_UNCONFIGURE = 1 { : no unconfigure action required ; } elif test $DRIVER_CONFIGURE = 1 { while test 1 { sleep 2 force_state_change $1 offline force_state_change $1 online } & setvar script_pid = "$BgPid" } } # # usage: prepare_for_errdef # proc prepare_for_errdef { export DRIVER_PATH=$1 export DRIVER_NAME=$2 export DRIVER_INSTANCE=$3 export DRIVER_UNCONFIGURE=1 export DRIVER_CONFIGURE=0 control_workload $1 $script_pid setvar script_pid = '0' th_manage $2 $3 get_handles >/dev/null 2>&1 [[ $? != 0 ]] && exit 1 force_state_change $1 offline force_state_change $1 online export DRIVER_UNCONFIGURE=0 export DRIVER_CONFIGURE=1 [[ $4 == 1 ]] && control_workload $1 $script_pid } # usage: monitor_edef proc monitor_edef { let aborted=0 trap ' (( aborted += 1 )) ' 16 sleep 2 # Wait for the errdef to be added th_manage $1 $2 start [[ $? != 0 ]] && exit 1 let s=0 let x=$3 set -A stats 0 0 1 0 0 0 0 "" # # Loop for x reports unless the error is reported or the access fail # count goes to zero. # while (( (x -= 1) >= 0 )) { (( aborted > 0 )) && break read line test -z $line && break set -A stats $(echo "$line" | /usr/bin/awk -F: '{for (i = 1; i <= NF; i++) print $i}') test ${stats[6]} -ne "0" && break # Fault was reported # # If fail count is zero - increment a loop counter 3 times # before aborting this errdef. # test ${stats[3]} = "0" && (( (s += 1) > 3 )) && break } th_manage $1 $2 clear_errdefs # Clear errors. [[ $? != 0 ]] && exit 1 echo ${stats[@]} } # # Install, activate and monitor some error definitions # usage: run_subtest < errdefs # proc run_subtest { let edefid=0 setvar drv = "$1" setvar inst = "$2" if test $devpath = "NULL" { setvar path = $(th_manage $1 $2 getpath) } else { setvar path = "$devpath" } while read line { set -- $(echo "$line" | \ /usr/bin/awk '{for (i = 1; i <= NF; i++) print $i}') setvar w = ${line##*"-w "} let a=${w%%" "*} let b=${w##*" "} let x='a / b' (( a % b > 0 )) && (( x += 1 )) prepare_for_errdef $path $drv $inst 1 set -A status $(th_define $* 2>./elog | \ monitor_edef $drv $inst $x) if test ${status[2]} -gt 0 { setvar res = ""test not triggered"" } elif test ${status[1]} -eq 0 { setvar res = ""success (error undetected)"" } elif test ${status[1]} -gt 0 { if test ${status[6]} -eq 16 { setvar res = ""failure (no service impact reported)"" } else { setvar res = ""success (error reported)"" } } else { setvar res = '' } echo "Subtest $edefid: Result: \"$res\"" echo $line if test -n ${status[7]} { let i=6 let l=${#status[@]} echo " Fail Msg :\t\c" while (( (i += 1) <= l )) { echo "${status[$i]} \c" } echo "" } echo "\tFail Time :\t${status[0]}\tMsg Time :\t${status[1]}" echo "\tAcc count :\t${status[2]}\tFail count:\t${status[3]}" echo "\tAccess Chk:\t${status[4]}\tEmsg count:\t${status[5]}" if test ${status[6]} -eq 0 { echo "\tSeverity:\tSERVICE UNAFFECTED" } elif test ${status[6]} -eq -16 { echo "\tSeverity:\tSERVICE DEGRADED" } elif test ${status[6]} -eq -32 { echo "\tSeverity:\tSERVICE LOST" } ((edefid += 1)) } fixup_script 0 prepare_for_errdef $path $drv $inst 0 }