1 #! /usr/bin/ksh -p
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 2009 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
26 #
27
28 #
29 # NFSv4 client recovery:
30 # a: Verify that CLIENT continues to write data after nfs communication (between SERVER and CLIENT)
31 # disable-enable cycle on SERVER
32 # b: Verify that CLIENT continues to read data after nfs communication (between SERVER and CLIENT)
33 # disable-enable cycle on SERVER
34 # c: Verify that CLIENT continues to write data after nfs communication (between SERVER and CLIENT)
35 # disable-enable cycle on SERVER. During the period of communication disabled, CLIENT try to do
36 # IO (will hang)
37 # d: Verify that CLIENT continues to read data after nfs communication (between SERVER and CLIENT)
38 # disable-enable cycle on SERVER. During the period of communication disabled, CLIENT try to do
39 # IO (will hang)
40 #
41
42 . ${STF_SUITE}/include/nfsgen.kshlib
43
44 NAME=$(basename $0)
45
46 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] && set -x
47
48 DIR=$(dirname $0)
49 prog=$STF_SUITE/bin/file_operator
50
51 if [[ ! -x $prog ]]; then
52 echo "$NAME: the executible program '$prog' not found."
53 echo "\t Test FAIL"
54 return $STF_FAIL
55 fi
56
57 function internalCleanup
58 {
59 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
60 && set -x
61 filelist="$STF_TMPDIR/$NAME.out.$$ \
62 $STF_TMPDIR/$NAME.out2.$$"
63 rm -f $filelist $*
64 }
65
66 # For READ test, in order to avoid reading data from cache wrotten by WRITE test
67 # here we intended to prepare a file for read later
68 function internalSetup
69 {
70 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
71 && set -x
72
73 typeset testfile=$1
74 rm -f $testfile
75 $prog -W -c -o 4 -e $RANDOM -B "32768 2048 -1" $testfile > \
76 $STF_TMPDIR/$NAME.out.$$ 2>&1
77 if (( $? != 0 )); then
78 internalCleanup $testfile
79 echo "\tTest FAIL"
80 exit $STF_FAIL
81 fi
82 }
83
84
85 # main function
86 function assertion_func
87 {
88 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
89 && set -x
90
91 if (( $# < 5 )); then
92 echo "Invalid arguments: $*"
93 return $STF_FAIL
94 fi
95
96 typeset testfile=$1
97 typeset iooption=$2
98 typeset testseed=$3
99 typeset buffoption=$4
100 typeset ioduringblock=$5
101 typeset timeout=250
102 typeset pid=""
103 typeset pidnw=""
104 typeset nwret=""
105
106
107 # start to write or read
108 $prog $iooption -c -o 4 -e $testseed "$buffoption" $testfile \
109 > $STF_TMPDIR/$NAME.out.$$ 2>&1 &
110 pid=$!
111
112 # make sure the process is ready
113 wait_now $timeout "grep \"I am ready\" $STF_TMPDIR/$NAME.out.$$" \
114 > $STF_TMPDIR/$NAME.err.$$ 2>&1
115 if (( $? != 0 )); then
116 echo "failed to get 'READY' sign from IO process"
117 cat $STF_TMPDIR/$NAME.err.$$
118 kill -9 $pid
119 internalCleanup $testfile
120 echo "\t Test FAIL"
121 return $STF_FAIL
122 fi
123
124
125 # ipfilter doesn't support shared stack zones, so we can't
126 # set rules locally, and need to rsh to server to set it
127 # on the server.
128 if [[ `zonename` != global ]]; then
129 IPF_DIR=in
130 HOSTOPT="-s $SERVER"
131 else
132 IPF_DIR=out
133 HOSTOPT=""
134 fi
135
136 [[ $IS_IPV6 == 1 ]] && IPOPT="-v ipv6" || IPOPT=""
137 if (( $ioduringblock == 1 )); then
138 # touch block flag for ipfilter
139 $CMD touch $TMPDIR/network_block_flag
140 if (( $? != 0 )); then
141 echo "failed to touch $STF_TMPDIR/network_block_flag"
142 kill -9 $pid
143 internalCleanup $testfile
144 echo "\t Test FAIL"
145 return $STF_FAIL
146 fi
147 # block the nfs communication between CLIENT and SERVER
148 if [[ $IS_ZONE == 0 ]]; then
149 ipf_network $IPOPT \
150 -t $timeout -f $STF_TMPDIR/network_block_flag \
151 -r "block $IPF_DIR from $CLIENT to $SERVER port=2049" \
152 > $STF_TMPDIR/$NAME.reset_nw.$$ 2>&1 &
153 pidnw=$!
154 else
155 # RSH doesn't support to run commands in background
156 ssh root@$SERVER /usr/bin/ksh -c \
157 "'. $TMPDIR/nfs-util.kshlib; \
158 . $TMPDIR/libsmf.shlib; \
159 ipf_network $IPOPT \
160 -t $timeout -f $STF_TMPDIR/network_block_flag \
161 -r \"block $IPF_DIR from $CLIENT to $SERVER port=2049\" \
162 '" > $STF_TMPDIR/$NAME.reset_nw.$$ 2>&1 &
163 pidnw=$!
164 fi
165
166 # make sure the network is blocked before IO.
167 wait_now $timeout "$CMD ipfstat -oi | grep \"port = 2049\" > /dev/null"
168 if (( $? !=0 )); then
169 echo "Failed to block the network"
170 cat $STF_TMPDIR/$NAME.reset_nw.$$
171 kill -9 $pid $pidnw
172 internalCleanup $testfile
173 echo "\t Test FAIL"
174 return $STF_FAIL
175 fi
176
177 # conti to do IO during block perod
178 kill -16 $pid
179
180 # sleep for a while before restore the network communication
181 sleep 10
182
183 # remove block flag file to restore ipfilter settings on $SERVER
184 RUN_CHECK $CMD rm $TMPDIR/network_block_flag
185 wait $pidnw
186 # make sure ipf_network() work well.
187 wait_now 240 "grep \"ipf_network finished\" \
188 $STF_TMPDIR/$NAME.reset_nw.$$ > /dev/null"
189 nwret=$?
190 else
191 if [[ $IS_ZONE == 0 ]]; then
192 ipf_network $IPOPT -t 30 \
193 -r "block $IPF_DIR from $CLIENT to $SERVER port=2049" \
194 > $STF_TMPDIR/$NAME.reset_nw.$$ 2>&1
195 nwret=$?
196 else
197 RSH root $SERVER \
198 "export STF_TMPDIR=$SRV_TMPDIR; \
199 . $TMPDIR/nfs-util.kshlib; \
200 . $TMPDIR/libsmf.shlib; \
201 ipf_network $IPOPT -t 30 \
202 -r \"block $IPF_DIR from $CLIENT to $SERVER port=2049\"" \
203 > $STF_TMPDIR/$NAME.reset_nw.$$ 2>&1
204 nwret=$?
205 fi
206 fi
207
208 if (( $nwret != 0 )); then
209 echo "block nfs communication return failure"
210 RUN_CHECK $CMD rm -f $TMPDIR/network_block_flag
211 kill $pid
212 cat $STF_TMPDIR/$NAME.reset_nw.$$
213 internalCleanup $testfile
214 echo "\t Test FAIL"
215 return $STF_FAIL
216 fi
217
218 (( $ioduringblock == 0 )) && kill -16 $pid
219
220 # wait the io process to finish
221 wait $pid
222
223 internalCleanup $testfile
224 if (( $? == 0 )); then
225 echo "\tTest PASS"
226 return $STF_PASS
227 else
228 echo "\tTest FAIL"
229 return $STF_FAIL
230 fi
231 }
232
233
234 # Start main program here:
235 # ----------------------------------------------------------------------
236
237 # ipfilter doesn't support shared stack zones, so we can't set rules
238 # in non-global zone, we need to set ipfilter rule in the server.
239 # For SETUP=none, we can't execute the command in the server.
240 # So in that case UNSUPPORTED is returned.
241 if [[ `zonename` != global ]]; then
242 if [[ $SETUP == none ]]; then
243 echo "The test doesn't support local zone with SETUP=none config"
244 return $STF_UNSUPPORTED
245 else
246 IS_ZONE=1
247 CMD="RSH root $SERVER"
248 TMPDIR=$SRV_TMPDIR
249 fi
250 else
251 IS_ZONE=0
252 CMD=""
253 TMPDIR=$STF_TMPDIR
254 fi
255
256 internalSetup $MNTDIR/openfile_r.$$
257 retcode=0
258
259 ASSERTION_A="Verify that client continues to write data after network disable-enable \
260 cycle on SERVER, expect success"
261 ASSERTION_B="Verify that client continues to read data after network disable-enable \
262 cycle on SERVER, expect success"
263 ASSERTION_C="Verify that client continues to write data after network disable-enable \
264 cycle on SERVER, expect success. During the period of network disabled, \
265 CLIENT try to do IO"
266 ASSERTION_D="Verify that client continues to read data after network disable-enable \
267 cycle on SERVER, expect success. During the period of network disabled, \
268 CLIENT try to do IO"
269
270 echo "$NAME{a}: $ASSERTION_A"
271 assertion_func $MNTDIR/openfile_w.$$ -W $RANDOM "-B \"32768 2048 0\"" 0
272 retcode=$(($retcode+$?))
273
274 echo "$NAME{b}: $ASSERTION_B"
275 assertion_func $MNTDIR/openfile_r.$$ -R $RANDOM "-B \"32768 2048 0\"" 0
276 retcode=$(($retcode+$?))
277
278 echo "$NAME{c}: $ASSERTION_C"
279 assertion_func $MNTDIR/openfile_w2.$$ -W $RANDOM "-B \"32768 2048 0\"" 1
280 retcode=$(($retcode+$?))
281
282 echo "$NAME{d}: $ASSERTION_D"
283 assertion_func $MNTDIR/openfile_r.$$ -R $RANDOM "-B \"32768 2048 0\"" 1
284 retcode=$(($retcode+$?))
285
286
287 internalCleanup $MNTDIR/openfile_r.$$ $MNTDIR/openfile_w.$$ \
288 $MNTDIR/openfile_w2.$$
289
290 (( $retcode == $STF_PASS )) && cleanup $STF_PASS || cleanup $STF_FAIL