xref: /illumos-gate/usr/src/cmd/th_tools/th_script.sh (revision 2a8bcb4e)
17c478bd9Sstevel@tonic-gate#
27c478bd9Sstevel@tonic-gate# CDDL HEADER START
37c478bd9Sstevel@tonic-gate#
47c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the
5*00d0963fSdilpreet# Common Development and Distribution License (the "License").
6*00d0963fSdilpreet# You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate#
87c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate# and limitations under the License.
127c478bd9Sstevel@tonic-gate#
137c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate#
197c478bd9Sstevel@tonic-gate# CDDL HEADER END
207c478bd9Sstevel@tonic-gate#
217c478bd9Sstevel@tonic-gate#
22*00d0963fSdilpreet# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*00d0963fSdilpreet# Use is subject to license terms.
247c478bd9Sstevel@tonic-gate#
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate#
277c478bd9Sstevel@tonic-gate# usage: force_state_change <path> <target state>
287c478bd9Sstevel@tonic-gate#
297c478bd9Sstevel@tonic-gateforce_state_change()
307c478bd9Sstevel@tonic-gate{
317c478bd9Sstevel@tonic-gate	[[ $2 != "online" && $2 != "offline" ]] && exit 1
327c478bd9Sstevel@tonic-gate	th_manage $1 getstate | read path state busy
337c478bd9Sstevel@tonic-gate	[[ $? != 0 ]] && exit 1
347c478bd9Sstevel@tonic-gate	[[ "$state" = "$2" ]] && return 0
357c478bd9Sstevel@tonic-gate	th_manage $1 $2
367c478bd9Sstevel@tonic-gate	[[ $? != 0 ]] && exit 1
377c478bd9Sstevel@tonic-gate	th_manage $1 getstate | read path state busy
387c478bd9Sstevel@tonic-gate	[[ $? != 0 ]] && exit 1
397c478bd9Sstevel@tonic-gate	[[ "$state" != "$2" ]] && exit 1
407c478bd9Sstevel@tonic-gate	return 0
417c478bd9Sstevel@tonic-gate}
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gatescript_pid=0
457c478bd9Sstevel@tonic-gatetrap ' terminate $script_pid ' 1 2 3 15
467c478bd9Sstevel@tonic-gateterminate()
477c478bd9Sstevel@tonic-gate{
487c478bd9Sstevel@tonic-gate	[[ $1 -gt 0 ]] && kill $1 > /dev/null 2>&1
497c478bd9Sstevel@tonic-gate	exit 1
507c478bd9Sstevel@tonic-gate}
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate#
537c478bd9Sstevel@tonic-gate# usage: control_workload <path> <pid>
547c478bd9Sstevel@tonic-gate# The following function is called (as a background task) prior to taking a
557c478bd9Sstevel@tonic-gate# driver instance offline and immediately after it is brought online. If the
567c478bd9Sstevel@tonic-gate# th_define process which created this script did not specify a script with the
577c478bd9Sstevel@tonic-gate# -e option then the default action is to run in the background this script
587c478bd9Sstevel@tonic-gate# which will continuously offline and online the instance until the injected
597c478bd9Sstevel@tonic-gate# error is detected by the driver or until the errdef is aborted.
607c478bd9Sstevel@tonic-gate#
617c478bd9Sstevel@tonic-gatecontrol_workload()
627c478bd9Sstevel@tonic-gate{
637c478bd9Sstevel@tonic-gate	fixup_script 1
647c478bd9Sstevel@tonic-gate	if [ $? == 0 ]; then
657c478bd9Sstevel@tonic-gate		return
667c478bd9Sstevel@tonic-gate	fi
677c478bd9Sstevel@tonic-gate
687c478bd9Sstevel@tonic-gate	#
697c478bd9Sstevel@tonic-gate	# Default workload - continuously offline and online the driver instance
707c478bd9Sstevel@tonic-gate	# while injecting errors
717c478bd9Sstevel@tonic-gate	#
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate	if [[ $2 -gt 0 ]]; then
747c478bd9Sstevel@tonic-gate		kill $2 > /dev/null 2>&1
757c478bd9Sstevel@tonic-gate	fi
767c478bd9Sstevel@tonic-gate	if [ $# -lt 2 ]; then
777c478bd9Sstevel@tonic-gate		echo syntax: $0 path pid
787c478bd9Sstevel@tonic-gate	elif [ $DRIVER_UNCONFIGURE = 1 ]; then
797c478bd9Sstevel@tonic-gate		: no unconfigure action required ;
807c478bd9Sstevel@tonic-gate	elif [ $DRIVER_CONFIGURE = 1 ]; then
817c478bd9Sstevel@tonic-gate		while [ 1 ]; do
827c478bd9Sstevel@tonic-gate			sleep 2
837c478bd9Sstevel@tonic-gate			force_state_change $1 offline
847c478bd9Sstevel@tonic-gate			force_state_change $1 online
857c478bd9Sstevel@tonic-gate		done &
867c478bd9Sstevel@tonic-gate		script_pid=$!
877c478bd9Sstevel@tonic-gate	fi
887c478bd9Sstevel@tonic-gate}
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate#
917c478bd9Sstevel@tonic-gate# usage: prepare_for_errdef <path> <driver> <instance> <do_unconfigure>
927c478bd9Sstevel@tonic-gate#
937c478bd9Sstevel@tonic-gateprepare_for_errdef()
947c478bd9Sstevel@tonic-gate{
957c478bd9Sstevel@tonic-gate	export DRIVER_PATH=$1
967c478bd9Sstevel@tonic-gate	export DRIVER_NAME=$2
977c478bd9Sstevel@tonic-gate	export DRIVER_INSTANCE=$3
987c478bd9Sstevel@tonic-gate	export DRIVER_UNCONFIGURE=1
997c478bd9Sstevel@tonic-gate	export DRIVER_CONFIGURE=0
1007c478bd9Sstevel@tonic-gate	control_workload $1 $script_pid
1017c478bd9Sstevel@tonic-gate	script_pid=0
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate	th_manage $2 $3 get_handles >/dev/null 2>&1
1047c478bd9Sstevel@tonic-gate	[[ $? != 0 ]] && exit 1
1057c478bd9Sstevel@tonic-gate	force_state_change $1 offline
1067c478bd9Sstevel@tonic-gate	force_state_change $1 online
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate	export DRIVER_UNCONFIGURE=0
1097c478bd9Sstevel@tonic-gate	export DRIVER_CONFIGURE=1
1107c478bd9Sstevel@tonic-gate	[[ $4 == 1 ]] &&
1117c478bd9Sstevel@tonic-gate		control_workload $1 $script_pid
1127c478bd9Sstevel@tonic-gate}
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate# usage: monitor_edef <driver> <instance> <nsteps>
1157c478bd9Sstevel@tonic-gatemonitor_edef()
1167c478bd9Sstevel@tonic-gate{
1177c478bd9Sstevel@tonic-gate	let aborted=0
1187c478bd9Sstevel@tonic-gate	trap ' (( aborted += 1 )) ' 16
1197c478bd9Sstevel@tonic-gate	sleep 2	# Wait for the errdef to be added
1207c478bd9Sstevel@tonic-gate	th_manage $1 $2 start
1217c478bd9Sstevel@tonic-gate	[[ $? != 0 ]] && exit 1
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate	let s=0
1247c478bd9Sstevel@tonic-gate	let x=$3
1257c478bd9Sstevel@tonic-gate	set -A stats 0 0 1 0 0 0 0 ""
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate	#
1287c478bd9Sstevel@tonic-gate	# Loop for x reports unless the error is reported or the access fail
1297c478bd9Sstevel@tonic-gate	# count goes to zero.
1307c478bd9Sstevel@tonic-gate	#
1317c478bd9Sstevel@tonic-gate	while (( (x -= 1) >= 0 ))
1327c478bd9Sstevel@tonic-gate	do
1337c478bd9Sstevel@tonic-gate		(( aborted > 0 )) && break
1347c478bd9Sstevel@tonic-gate		read line
1357c478bd9Sstevel@tonic-gate		[ -z "$line" ] && break
1367c478bd9Sstevel@tonic-gate		set -A stats $(echo "$line" |
1377c478bd9Sstevel@tonic-gate		    /usr/bin/awk -F: '{for (i = 1; i <= NF; i++) print $i}')
1387c478bd9Sstevel@tonic-gate		[ "${stats[6]}" -ne "0" ] && break	# Fault was reported
1397c478bd9Sstevel@tonic-gate		#
1407c478bd9Sstevel@tonic-gate		# If fail count is zero - increment a loop counter 3 times
1417c478bd9Sstevel@tonic-gate		# before aborting this errdef.
1427c478bd9Sstevel@tonic-gate		#
1437c478bd9Sstevel@tonic-gate		[ "${stats[3]}" = "0" ] && (( (s += 1) > 3 )) && break
1447c478bd9Sstevel@tonic-gate	done
1457c478bd9Sstevel@tonic-gate	th_manage $1 $2 clear_errdefs			# Clear errors.
1467c478bd9Sstevel@tonic-gate	[[ $? != 0 ]] && exit 1
1477c478bd9Sstevel@tonic-gate	echo "${stats[@]}"
1487c478bd9Sstevel@tonic-gate}
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate#
1517c478bd9Sstevel@tonic-gate# Install, activate and monitor some error definitions
1527c478bd9Sstevel@tonic-gate# usage: run_subtest <driver> <instance> < errdefs
1537c478bd9Sstevel@tonic-gate#
1547c478bd9Sstevel@tonic-gaterun_subtest()
1557c478bd9Sstevel@tonic-gate{
1567c478bd9Sstevel@tonic-gate	let edefid=0
1577c478bd9Sstevel@tonic-gate	drv=$1
1587c478bd9Sstevel@tonic-gate	inst=$2
1597c478bd9Sstevel@tonic-gate	if [ $devpath = "NULL" ]
1607c478bd9Sstevel@tonic-gate	then
1617c478bd9Sstevel@tonic-gate		path=$(th_manage $1 $2 getpath)
1627c478bd9Sstevel@tonic-gate	else
1637c478bd9Sstevel@tonic-gate		path=$devpath
1647c478bd9Sstevel@tonic-gate	fi
1657c478bd9Sstevel@tonic-gate	while read line
1667c478bd9Sstevel@tonic-gate	do
1677c478bd9Sstevel@tonic-gate		set -- $(echo "$line" | \
1687c478bd9Sstevel@tonic-gate		    /usr/bin/awk '{for (i = 1; i <= NF; i++) print $i}')
1697c478bd9Sstevel@tonic-gate		w=${line##*"-w "}
1707c478bd9Sstevel@tonic-gate		let a=${w%%" "*}
1717c478bd9Sstevel@tonic-gate		let b=${w##*" "}
1727c478bd9Sstevel@tonic-gate		let x='a / b'
1737c478bd9Sstevel@tonic-gate		(( a % b > 0 )) && (( x += 1 ))
1747c478bd9Sstevel@tonic-gate		prepare_for_errdef $path $drv $inst 1
1757c478bd9Sstevel@tonic-gate		set -A status $(th_define $* 2>./elog | \
1767c478bd9Sstevel@tonic-gate		    monitor_edef $drv $inst $x)
1777c478bd9Sstevel@tonic-gate		if [ "${status[2]}" -gt 0 ]; then
1787c478bd9Sstevel@tonic-gate			res="test not triggered"
1797c478bd9Sstevel@tonic-gate		elif [ "${status[1]}" -eq 0 ]; then
180*00d0963fSdilpreet			res="success (error undetected)"
1817c478bd9Sstevel@tonic-gate		elif [ "${status[1]}" -gt 0 ]; then
182*00d0963fSdilpreet			if [ "${status[6]}" -eq 16 ]; then
183*00d0963fSdilpreet				res="failure (no service impact reported)"
184*00d0963fSdilpreet			else
185*00d0963fSdilpreet				res="success (error reported)"
186*00d0963fSdilpreet			fi
1877c478bd9Sstevel@tonic-gate		else
1887c478bd9Sstevel@tonic-gate			res=
1897c478bd9Sstevel@tonic-gate		fi
1907c478bd9Sstevel@tonic-gate		echo "Subtest $edefid: Result: \"$res\""
1917c478bd9Sstevel@tonic-gate		echo $line
1927c478bd9Sstevel@tonic-gate		if [ -n "${status[7]}" ]; then
1937c478bd9Sstevel@tonic-gate			let i=6
1947c478bd9Sstevel@tonic-gate			let l=${#status[@]}
1957c478bd9Sstevel@tonic-gate			echo "	Fail Msg  :\t\c"
1967c478bd9Sstevel@tonic-gate			while (( (i += 1) <= l ))
1977c478bd9Sstevel@tonic-gate			do
1987c478bd9Sstevel@tonic-gate				echo "${status[$i]} \c"
1997c478bd9Sstevel@tonic-gate			done
2007c478bd9Sstevel@tonic-gate			echo ""
2017c478bd9Sstevel@tonic-gate		fi
2027c478bd9Sstevel@tonic-gate		echo "\tFail Time :\t${status[0]}\tMsg Time  :\t${status[1]}"
2037c478bd9Sstevel@tonic-gate		echo "\tAcc count :\t${status[2]}\tFail count:\t${status[3]}"
2047c478bd9Sstevel@tonic-gate		echo "\tAccess Chk:\t${status[4]}\tEmsg count:\t${status[5]}"
205*00d0963fSdilpreet		if [ "${status[6]}" -eq 0 ]; then
206*00d0963fSdilpreet			echo "\tSeverity:\tSERVICE UNAFFECTED"
207*00d0963fSdilpreet		elif [ "${status[6]}" -eq -16 ]; then
208*00d0963fSdilpreet			echo "\tSeverity:\tSERVICE DEGRADED"
209*00d0963fSdilpreet		elif [ "${status[6]}" -eq -32 ]; then
210*00d0963fSdilpreet			echo "\tSeverity:\tSERVICE LOST"
211*00d0963fSdilpreet		fi
2127c478bd9Sstevel@tonic-gate		((edefid += 1))
2137c478bd9Sstevel@tonic-gate	done
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate	fixup_script 0
2167c478bd9Sstevel@tonic-gate	prepare_for_errdef $path $drv $inst 0
2177c478bd9Sstevel@tonic-gate}
218