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 SERVER will provide conflicting lock to other
31 # client after the lease expired
32 #
33
34 . ${STF_SUITE}/include/nfsgen.kshlib
35
36 NAME=$(basename $0)
37
38 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] && set -x
39
40 DIR=$(dirname $0)
41
42 prog=$STF_SUITE/bin/file_operator
43 timeout=250
44 locktimeout=$((${LEASE_TIME:-180} + 100))
45 TESTFILE01="rwfile.$$"
46
47 [[ $MNTDIR2 == $SHRDIR ]] && mntdir2="${MNTDIR2}_other" || mntdir2=$MNTDIR2
48
49 # assertion_a
50 # CLIENTA: open a file, lock and write the file
51 # SERVER: cut down the nfs communication between CLIENTA and SERVER during CLIENTA is writing
52 # CLIENTB(SERVER): open the same file, try to lock and write data
53 # CLIENTA: kill the writing process on CLIENTA
54 # SERVER: after the write process on CLIENTB(SERVER) finished, restore the nfs communication
55 # between CLIENTA and SERVER
56 # CLIENTA: start to open the same file, check the data wrotten by CLIENTB(SERVER)
57 #
58 function assertion_a
59 {
60 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
61 && set -x
62
63 typeset pid1=""
64 typeset pid2=""
65 typeset pidnw=""
66 typeset seed=$RANDOM
67
68 # open and write file on CLIENT
69 checkseed=$RANDOM
70 $prog -W -c -u -o 4 -L "1 1 0 0" -B "32768 2048 1024" $MNTDIR/$TESTFILE01 \
71 > $STF_TMPDIR/$NAME.out.$$ 2>&1 &
72 pid1=$!
73
74 # make sure the 1st write process is ready
75 wait_now $timeout "grep \"I am ready\" $STF_TMPDIR/$NAME.out.$$" \
76 > $STF_TMPDIR/$NAME.err.$$ 2>&1
77 if (( $? != 0 )); then
78 echo "1st write process failed to get lock and write 32MB data \
79 in $timeout seconds"
80 cat $STF_TMPDIR/$NAME.err.$$
81 cat $STF_TMPDIR/$NAME.out.$$
82 kill $pid1
83 echo "\t Test FAIL"
84 return $STF_FAIL
85 fi
86
87 # ready to cut the communication between CLIENT and SERVER
88 RUN_CHECK $CMD sync || return $STF_FAIL
89 RUN_CHECK $CMD touch $TMPDIR/network_block_flag \
90 $TMPDIR/network_feedback_file || return $STF_FAIL
91
92 [[ $IS_IPV6 == 1 ]] && IPOPT="-v ipv6" || IPOPT=""
93 if [[ $IS_ZONE == 0 ]]; then
94 ipf_network $IPOPT \
95 -t $timeout \
96 -f $TMPDIR/network_block_flag \
97 -k $TMPDIR/network_feedback_file \
98 -r "block out from $CLIENT to $SERVER port=2049" \
99 > $STF_TMPDIR/$NAME.reset_nw.$$ 2>&1 &
100 pidnw=$!
101 else
102 # RSH doesn't support to run the command in background.
103 ssh root@$SERVER /usr/bin/ksh -c \
104 "'. $TMPDIR/nfs-util.kshlib; \
105 . $TMPDIR/libsmf.shlib; \
106 ipf_network $IPOPT \
107 -t $timeout \
108 -f $TMPDIR/network_block_flag \
109 -k $TMPDIR/network_feedback_file \
110 -r \"block in from $CLIENT to $SERVER port=2049\"' " \
111 > $STF_TMPDIR/$NAME.reset_nw.$$ 2>&1 &
112 pidnw=$!
113 fi
114
115
116 # make sure network already blocked
117 wait_now $timeout "$CMD [[ ! -f $TMPDIR/network_feedback_file ]] \
118 > /dev/null 2>&1"
119 if (( $? != 0 )); then
120 echo "Failed to block the communication between client and server"
121 cat $STF_TMPDIR/$NAME.reset_nw.$$
122 kill $pid1
123 return $STF_FAIL
124 fi
125
126 # start another process on SERVER to write the same file
127 TESTFILEONSERVER="${mntdir2}/$TESTFILE01"
128 wait_now $locktimeout "RSH root $SERVER \
129 \"export LD_LIBRARY_PATH=$SRV_TMPDIR/recovery/bin/:$LD_LIBRARY_PATH; \
130 $SRV_TMPDIR/recovery/bin/file_operator \
131 -W -c -u -o 3 -e $seed -L \\\"1 1 0 0\\\" -B \\\"32768 2048 -1\\\" \
132 $TESTFILEONSERVER \" " > $STF_TMPDIR/$NAME.w2.out.$$ 2>&1
133 if (( $? != 0 )); then
134 echo "file_operator on $SERVER failed"
135 cat $STF_TMPDIR/$NAME.w2.out.$$
136 # restore the network communication between CLIENT and SERVER
137 RUN_CHECK $CMD rm $TMPDIR/network_block_flag
138 wait $pidnw
139 echo "\tTest FAIL"
140 return $STF_FAIL
141 fi
142
143 # before restore the network communication between CLIENT and SERVER
144 # kill the first proccess on CLIENT
145 kill -9 $pid1
146 if (( $? != 0 )) ; then
147 echo "failed to kill pid1($pid1)"
148 cat $STF_TMPDIR/$NAME.out.$$
149 cat $STF_TMPDIR/$NAME.w2.out.$$
150 # restore the network communication between CLIENT and SERVER
151 RUN_CHECK $CMD rm $TMPDIR/network_block_flag
152 wait $pidnw
153 echo "\tTest FAIL"
154 return $STF_FAIL
155 fi
156
157 # ok, restore the network communication between CLIENT and SERVER
158 RUN_CHECK $CMD rm $TMPDIR/network_block_flag
159 wait $pidnw
160 if (( $? != 0 )); then
161 echo "failed to wait ipf_network"
162 kill -9 $pidnw
163 cat $STF_TMPDIR/$NAME.reset_nw.$$
164 echo "\t Test FAIL"
165 return $STF_FAIL
166 fi
167
168 # here, open the same file on CLIENT for read and check
169 $prog -R -c -u -o 0 -e $seed -L "0 1 0 0" -B "32768 2048 2048" \
170 $MNTDIR/$TESTFILE01 > $STF_TMPDIR/$NAME.out2.$$ 2>&1 &
171 pid2=$!
172 wait_now $timeout "grep \"I am ready\" $STF_TMPDIR/$NAME.out2.$$" \
173 > $STF_TMPDIR/$NAME.err.$$ 2>&1
174 if (( $? != 0 )); then
175 echo "failed to get 'READY' signal from pid2 in $timeout seconds"
176 cat $STF_TMPDIR/$NAME.err.$$
177 cat $STF_TMPDIR/$NAME.out2.$$
178 kill $pid2
179 echo "\t Test FAIL"
180 return $STF_FAIL
181 fi
182
183 # signal pid2 to read data back for check
184 kill -16 $pid2
185
186 wait $pid2
187 if (( $? != 0 )); then
188 cat $STF_TMPDIR/$NAME.out2.$$
189 echo "\tTest FAIL"
190 return $STF_FAIL
191 else
192 echo "\tTest PASS"
193 return $STF_PASS
194 fi
195 }
196
197 # setup another mountpoint on SERVER
198 function internalSetup_pos01
199 {
200 RUN_CHECK RSH root $SERVER "\"mkdir -p -m 0777 ${mntdir2}; \
201 mount -o $MNTOPT2 $SERVER:$SHRDIR ${mntdir2}\"" \
202 || exit $STF_UNINITIATED
203 }
204
205 #cleanup mountpoint on SERVER
206 function internalCleanup_pos01
207 {
208 RUN_CHECK RSH root $SERVER "\"umount ${mntdir2}; rm -rf ${mntdir2}\"" \
209 || exit $STF_FAIL
210 }
211
212
213 # Start main program here:
214 # ----------------------------------------------------------------------
215
216 # ipfilter doesn't support shared stack zones, so we can't set rules
217 # in non-global zone, we need to set ipfilter rule in the server.
218 # For SETUP=none, we can't execute the command in the server.
219 # So in that case UNSUPPORTED is returned.
220 if [[ `zonename` != global ]]; then
221 if [[ $SETUP == none ]]; then
222 return $STF_UNSUPPORTED
223 else
224 IS_ZONE=1
225 CMD="RSH root $SERVER"
226 TMPDIR=$SRV_TMPDIR
227 fi
228 else
229 IS_ZONE=0
230 CMD=""
231 TMPDIR=$STF_TMPDIR
232 fi
233
234 internalSetup_pos01
235 retcode=0
236
237 ASSERTION_A="Verify that SERVER will provide conflicting layout and lock to other\
238 client after the lease expiration, expect success"
239
240 echo "$NAME{a}: $ASSERTION_A"
241 assertion_a
242 retcode=$?
243
244 internalCleanup_pos01
245 RUN_CHECK $CMD rm -f $TMPDIR/network_feedback_file $TMPDIR/network_block_flag
246
247 (( $retcode == $STF_PASS )) \
248 && cleanup $STF_PASS "" "$MNTDIR/$TESTFILE01 $STF_TMPDIR/$NAME.*.$$" \
249 || cleanup $retcode "" "$MNTDIR/$TESTFILE01 $STF_TMPDIR/$NAME.*.$$"
250