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