xref: /illumos-gate/usr/src/cmd/th_tools/th_script.sh (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1#
2# CDDL HEADER START
3#
4# The contents of this file are subject to the terms of the
5# Common Development and Distribution License (the "License").
6# You may not use this file except in compliance with the License.
7#
8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9# or http://www.opensolaris.org/os/licensing.
10# See the License for the specific language governing permissions
11# and limitations under the License.
12#
13# When distributing Covered Code, include this CDDL HEADER in each
14# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15# If applicable, add the following below this CDDL HEADER, with the
16# fields enclosed by brackets "[]" replaced with your own identifying
17# information: Portions Copyright [yyyy] [name of copyright owner]
18#
19# CDDL HEADER END
20#
21#
22# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
24#
25#pragma ident	"%Z%%M%	%I%	%E% SMI"
26
27#
28# usage: force_state_change <path> <target state>
29#
30force_state_change()
31{
32	[[ $2 != "online" && $2 != "offline" ]] && exit 1
33	th_manage $1 getstate | read path state busy
34	[[ $? != 0 ]] && exit 1
35	[[ "$state" = "$2" ]] && return 0
36	th_manage $1 $2
37	[[ $? != 0 ]] && exit 1
38	th_manage $1 getstate | read path state busy
39	[[ $? != 0 ]] && exit 1
40	[[ "$state" != "$2" ]] && exit 1
41	return 0
42}
43
44
45script_pid=0
46trap ' terminate $script_pid ' 1 2 3 15
47terminate()
48{
49	[[ $1 -gt 0 ]] && kill $1 > /dev/null 2>&1
50	exit 1
51}
52
53#
54# usage: control_workload <path> <pid>
55# The following function is called (as a background task) prior to taking a
56# driver instance offline and immediately after it is brought online. If the
57# th_define process which created this script did not specify a script with the
58# -e option then the default action is to run in the background this script
59# which will continuously offline and online the instance until the injected
60# error is detected by the driver or until the errdef is aborted.
61#
62control_workload()
63{
64	fixup_script 1
65	if [ $? == 0 ]; then
66		return
67	fi
68
69	#
70	# Default workload - continuously offline and online the driver instance
71	# while injecting errors
72	#
73
74	if [[ $2 -gt 0 ]]; then
75		kill $2 > /dev/null 2>&1
76	fi
77	if [ $# -lt 2 ]; then
78		echo syntax: $0 path pid
79	elif [ $DRIVER_UNCONFIGURE = 1 ]; then
80		: no unconfigure action required ;
81	elif [ $DRIVER_CONFIGURE = 1 ]; then
82		while [ 1 ]; do
83			sleep 2
84			force_state_change $1 offline
85			force_state_change $1 online
86		done &
87		script_pid=$!
88	fi
89}
90
91#
92# usage: prepare_for_errdef <path> <driver> <instance> <do_unconfigure>
93#
94prepare_for_errdef()
95{
96	export DRIVER_PATH=$1
97	export DRIVER_NAME=$2
98	export DRIVER_INSTANCE=$3
99	export DRIVER_UNCONFIGURE=1
100	export DRIVER_CONFIGURE=0
101	control_workload $1 $script_pid
102	script_pid=0
103
104	th_manage $2 $3 get_handles >/dev/null 2>&1
105	[[ $? != 0 ]] && exit 1
106	force_state_change $1 offline
107	force_state_change $1 online
108
109	export DRIVER_UNCONFIGURE=0
110	export DRIVER_CONFIGURE=1
111	[[ $4 == 1 ]] &&
112		control_workload $1 $script_pid
113}
114
115# usage: monitor_edef <driver> <instance> <nsteps>
116monitor_edef()
117{
118	let aborted=0
119	trap ' (( aborted += 1 )) ' 16
120	sleep 2	# Wait for the errdef to be added
121	th_manage $1 $2 start
122	[[ $? != 0 ]] && exit 1
123
124	let s=0
125	let x=$3
126	set -A stats 0 0 1 0 0 0 0 ""
127
128	#
129	# Loop for x reports unless the error is reported or the access fail
130	# count goes to zero.
131	#
132	while (( (x -= 1) >= 0 ))
133	do
134		(( aborted > 0 )) && break
135		read line
136		[ -z "$line" ] && break
137		set -A stats $(echo "$line" |
138		    /usr/bin/awk -F: '{for (i = 1; i <= NF; i++) print $i}')
139		[ "${stats[6]}" -ne "0" ] && break	# Fault was reported
140		#
141		# If fail count is zero - increment a loop counter 3 times
142		# before aborting this errdef.
143		#
144		[ "${stats[3]}" = "0" ] && (( (s += 1) > 3 )) && break
145	done
146	th_manage $1 $2 clear_errdefs			# Clear errors.
147	[[ $? != 0 ]] && exit 1
148	echo "${stats[@]}"
149}
150
151#
152# Install, activate and monitor some error definitions
153# usage: run_subtest <driver> <instance> < errdefs
154#
155run_subtest()
156{
157	let edefid=0
158	drv=$1
159	inst=$2
160	if [ $devpath = "NULL" ]
161	then
162		path=$(th_manage $1 $2 getpath)
163	else
164		path=$devpath
165	fi
166	while read line
167	do
168		set -- $(echo "$line" | \
169		    /usr/bin/awk '{for (i = 1; i <= NF; i++) print $i}')
170		w=${line##*"-w "}
171		let a=${w%%" "*}
172		let b=${w##*" "}
173		let x='a / b'
174		(( a % b > 0 )) && (( x += 1 ))
175		prepare_for_errdef $path $drv $inst 1
176		set -A status $(th_define $* 2>./elog | \
177		    monitor_edef $drv $inst $x)
178		if [ "${status[2]}" -gt 0 ]; then
179			res="test not triggered"
180		elif [ "${status[1]}" -eq 0 ]; then
181			res="success (error undetected)"
182		elif [ "${status[1]}" -gt 0 ]; then
183			if [ "${status[6]}" -eq 16 ]; then
184				res="failure (no service impact reported)"
185			else
186				res="success (error reported)"
187			fi
188		else
189			res=
190		fi
191		echo "Subtest $edefid: Result: \"$res\""
192		echo $line
193		if [ -n "${status[7]}" ]; then
194			let i=6
195			let l=${#status[@]}
196			echo "	Fail Msg  :\t\c"
197			while (( (i += 1) <= l ))
198			do
199				echo "${status[$i]} \c"
200			done
201			echo ""
202		fi
203		echo "\tFail Time :\t${status[0]}\tMsg Time  :\t${status[1]}"
204		echo "\tAcc count :\t${status[2]}\tFail count:\t${status[3]}"
205		echo "\tAccess Chk:\t${status[4]}\tEmsg count:\t${status[5]}"
206		if [ "${status[6]}" -eq 0 ]; then
207			echo "\tSeverity:\tSERVICE UNAFFECTED"
208		elif [ "${status[6]}" -eq -16 ]; then
209			echo "\tSeverity:\tSERVICE DEGRADED"
210		elif [ "${status[6]}" -eq -32 ]; then
211			echo "\tSeverity:\tSERVICE LOST"
212		fi
213		((edefid += 1))
214	done
215
216	fixup_script 0
217	prepare_for_errdef $path $drv $inst 0
218}
219