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