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 # This is a regression test for 6248250. In this test, we will generate
30 # an OPEN_DOWNGRADE operation on a stale file handler. Without the fix, nfs
31 # client code didn't check NFS4ERR_STALE error and re-sent OPEN_DOWNGRADE
32 # again and again. On user level, it could be observed the user process
33 # was hang.
34 #
35
36 . ${STF_SUITE}/include/nfsgen.kshlib
37
38 NAME=$(basename $0)
39
40 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] && set -x
41
42 DIR=$(dirname $0)
43 OPENDG_ASSERTIONS=${OPENDG_ASSERTIONS:-"a"}
44
45 export RECOVERY_EXECUTE_PATH=$DIR
46 export RECOVERY_STAT_PATH=$STF_SUITE/bin/
47
48 # Wait until grace period ends
49 echo "xxx" > $MNTDIR/wait_for_grace
50 rm -rf $MNTDIR/wait_for_grace > /dev/null 2>&1
51
52 TESTFILE=$NAME.$$.test
53 LOGFILE=$STF_TMPDIR/$NAME.$$.err
54
55 function setup
56 {
57 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] && set -x
58
59 # execute $SERVER root \
60 RSH root $SERVER \
61 "cd $SHRDIR; touch $TESTFILE; chmod 666 $TESTFILE" 1>/dev/null \
62 2>$LOGFILE
63 ckresult $? "failed to create $TESTFILE ERROR" $LOGFILE || return 1
64 }
65
66 # Start test assertions here
67 # ----------------------------------------------------------------------
68 # a: generate an OPEN_DOWNGRADE operation on a stale file handler
69 function assertion_a
70 {
71 [[ :$NFSGEN_DEBUG: = *:${NAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] && set -x
72
73 ASSERTION="Client tries to generate an OPEN_DOWNGRADE operation"
74 ASSERTION="$ASSERTION on a stale file handler,"
75 ASSERTION="$ASSERTION expect NFS4ERR_STALE error be handled properly"
76 echo "$NAME{a}: $ASSERTION"
77
78 PROG=$STF_SUITE/bin/open_dg
79 INTERVAL=8
80 STF_WARNING="\tSTF_WARNING: The failure of this case was known to cause"
81 STF_WARNING="$STF_WARNING NFS client kept looping and didn't response to any"
82 STF_WARNING="$STF_WARNING further NFS operations. So you many need to re-setup"
83 STF_WARNING="$STF_WARNING the test environment and continue the rest tests."
84
85 # start test program
86 $PROG $MNTDIR/$TESTFILE 1>$LOGFILE 2>&1 &
87 pid=$!
88 sleep $INTERVAL
89 grep "fd1 and fd2 were opened" $LOGFILE > /dev/null
90 ckresult -n $? "failed to open test file STF_UNRESOLVED" $LOGFILE
91 if (( $? != 0 )); then
92 kill -9 $pid
93 rm -f $LOGFILE
94 return $STF_UNRESOLVED
95 fi
96
97
98 # do the following steps on server to help to generate
99 # NFS4ERR_STALE error when client sends OPEN_DOWNGRADE
100 # below. Note that the step of removing the file is necessary.
101 # Or else server returns NFS4ERR_EXPIRED error, which is
102 # not what we want to test in this case.
103 # execute $SERVER root "rm -f $SHRDIR/$TESTFILE && \
104 RSH root $SERVER "rm -f $SHRDIR/$TESTFILE && \
105 unshare $SHRDIR && share $SHRDIR" 1>/dev/null 2>$STF_TMPDIR/$NAME.$$.rsh
106 ckresult $? "failed to execute commands on server STF_UNRESOLVED" $STF_TMPDIR/$NAME.$$.rsh
107 if (( $? != 0 )); then
108 kill -9 $pid
109 rm -f $LOGFILE $STF_TMPDIR/$NAME.$$.rsh
110 return $STF_UNRESOLVED
111 fi
112
113 # close fd1 to generate OPEN_DOWNGRADE
114 kill -USR1 $pid
115 sleep $INTERVAL
116 grep "NFS4ERR_STALE" $LOGFILE | grep fd1 > /dev/null
117 ckresult -n $? "Unknown error on closing fd1 STF_FAIL" $LOGFILE
118 if (( $? != 0 )); then
119 echo $STF_WARNING
120 kill -9 $pid
121 rm -f $LOGFILE $STF_TMPDIR/$NAME.$$.rsh
122 return $STF_FAIL
123 fi
124
125 # close fd2
126 kill -USR2 $pid
127 sleep $INTERVAL
128 grep "NFS4ERR_STALE" $LOGFILE | grep fd2 > /dev/null
129 ckresult $? "Unknown error on closing fd2 STF_FAIL" $LOGFILE
130 if (( $? != 0 )); then
131 echo $STF_WARNING
132 kill -9 $pid
133 rm -f $LOGFILE $STF_TMPDIR/$NAME.$$.rsh
134 return $STF_FAIL
135 fi
136
137 rm -f $LOGFILE $STF_TMPDIR/$NAME.$$.rsh
138
139 echo "\t Test PASS"
140 return $STF_PASS
141 }
142
143 # Start main program here:
144 # ----------------------------------------------------------------------
145
146 setup || cleanup $STF_UNINITIATED "" "$MNTDIR/$TESTFILE $LOGFILE $STF_TMPDIR/$NAME.$$.rsh"
147
148 retcode=0
149 for t in $OPENDG_ASSERTIONS; do
150 assertion_$t
151 retcode=$(($retcode+$?))
152 done
153
154 (( $retcode == $STF_PASS )) \
155 && cleanup $STF_PASS "" "$MNTDIR/$TESTFILE $LOGFILE $STF_TMPDIR/$NAME.$$.rsh" \
156 || cleanup $STF_FAIL "" "$MNTDIR/$TESTFILE $LOGFILE $STF_TMPDIR/$NAME.$$.rsh"
157