Whamcloud - gitweb
branch: HEAD
[fs/lustre-release.git] / lustre / tests / sanity-gss.sh
1 #!/bin/bash
2 # vim:expandtab:shiftwidth=4:softtabstop=4:tabstop=4:
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test:
12 ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-""}
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14 if [ "x$GSS_PIPEFS" != "xy" ]; then
15     ALWAYS_EXCEPT="$ALWAYS_EXCEPT 4"
16 fi
17
18 [ "$SLOW" = "no" ] && EXCEPT="$EXCEPT"
19
20 # Tests that fail on uml, maybe elsewhere, FIXME
21 CPU=`awk '/model/ {print $4}' /proc/cpuinfo`
22 [ "$CPU" = "UML" ] && EXCEPT="$EXCEPT"
23
24 case `uname -r` in
25 2.6*) FSTYPE=${FSTYPE:-ldiskfs}; ALWAYS_EXCEPT="$ALWAYS_EXCEPT " ;;
26 *) error "unsupported kernel (gss only works with 2.6.x)" ;;
27 esac
28
29 SRCDIR=`dirname $0`
30 export PATH=$PWD/$SRCDIR:$SRCDIR:$SRCDIR/../utils:$SRCDIR/../utils/gss:$PATH:/sbin
31
32 TMP=${TMP:-/tmp}
33
34 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
35 CREATETEST=${CREATETEST:-createtest}
36 LFS=${LFS:-lfs}
37 LCTL=${LCTL:-lctl}
38 MEMHOG=${MEMHOG:-memhog}
39 DIRECTIO=${DIRECTIO:-directio}
40 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
41 UMOUNT=${UMOUNT:-"umount -d"}
42
43 if [ $UID -ne 0 ]; then
44     echo "Warning: running as non-root uid $UID"
45     RUNAS_ID="$UID"
46     RUNAS=""
47 else
48     RUNAS_ID=${RUNAS_ID:-500}
49     RUNAS=${RUNAS:-"runas -u $RUNAS_ID"}
50
51     # $RUNAS_ID may get set incorrectly somewhere else
52     if [ $RUNAS_ID -eq 0 ]; then
53         echo "Error: \$RUNAS_ID set to 0, but \$UID is also 0!"
54         exit 1
55     fi
56 fi
57
58 SANITYLOG=${SANITYLOG:-/tmp/sanity-gss.log}
59
60 export NAME=${NAME:-local}
61
62 SAVE_PWD=$PWD
63
64 export SEC=${SEC:-krb5p}
65 export KRB5_CCACHE_DIR=/tmp
66 export KRB5_CRED=$KRB5_CCACHE_DIR/krb5cc_$RUNAS_ID
67 export KRB5_CRED_SAVE=$KRB5_CCACHE_DIR/krb5cc.sanity.save
68
69 #
70 # check pre-set $SEC
71 #
72 case "x$SEC" in
73     xkrb5*)
74         echo "Using ptlrpc security flavor $SEC"
75         ;;
76     *)
77         echo "SEC=$SEC is invalid, it has to be gss/krb5 flavor"
78         exit 1
79         ;;
80 esac
81
82 LUSTRE=${LUSTRE:-`dirname $0`/..}
83 . $LUSTRE/tests/test-framework.sh
84 init_test_env $@
85 . ${CONFIG:=$LUSTRE/tests/cfg/local.sh}
86
87 prepare_krb5_creds() {
88     rm -f $CRED_SAVE
89     $RUNAS krb5_login.sh || exit 1
90     [ -f $KRB5_CRED ] || exit 2
91     cp $KRB5_CRED $KRB5_CRED_SAVE
92 }
93
94 cleanup() {
95     echo -n "cln.."
96     cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
97 }
98 CLEANUP=${CLEANUP:-:}
99
100 setup() {
101     echo -n "mnt.."
102     load_modules
103     setupall || exit 10
104     echo "done"
105 }
106 SETUP=${SETUP:-:}
107
108 trace() {
109     log "STARTING: $*"
110     strace -o $TMP/$1.strace -ttt $*
111     RC=$?
112     log "FINISHED: $*: rc $RC"
113     return 1
114 }
115 TRACE=${TRACE:-""}
116
117 check_kernel_version() {
118     VERSION_FILE=$LPROC/kernel_version
119     WANT_VER=$1
120     [ ! -f $VERSION_FILE ] && echo "can't find kernel version" && return 1
121     GOT_VER=`cat $VERSION_FILE`
122     [ $GOT_VER -ge $WANT_VER ] && return 0
123     log "test needs at least kernel version $WANT_VER, running $GOT_VER"
124     return 1
125 }
126
127 _basetest() {
128     echo $*
129 }
130
131 [ "$SANITYLOG" ] && rm -f $SANITYLOG || true
132
133
134 prepare_krb5_creds
135 build_test_filter
136 umask 077
137
138 # setup filesystem
139 formatall
140 setupall
141 chmod a+rwx $MOUNT
142
143 restore_krb5_cred() {
144     cp $KRB5_CRED_SAVE $KRB5_CRED
145     chown $RUNAS_ID:$RUNAS_ID $KRB5_CRED
146     chmod 0600 $KRB5_CRED
147 }
148
149 test_1() {
150     # access w/o cred
151     $RUNAS kdestroy
152     $RUNAS touch $MOUNT/f1 && error "unexpected success"
153
154     # access w/ cred
155     restore_krb5_cred
156     $RUNAS touch $MOUNT/f1 || error "should not fail"
157     [ -f $MOUNT/f1 ] || error "$MOUNT/f1 not found"
158 }
159 run_test 1 "access with or without krb5 credential"
160
161 test_2() {
162     # current access should be ok
163     $RUNAS touch $MOUNT/f2_1 || error "can't touch $MOUNT/f2_1"
164     [ -f $MOUNT/f2_1 ] || error "$MOUNT/f2_1 not found"
165
166     # cleanup all cred/ctx and touch
167     $RUNAS kdestroy
168     $RUNAS $LFS flushctx || error "can't flush ctx"
169     $RUNAS touch $MOUNT/f2_2 && error "unexpected success"
170
171     # restore and touch
172     restore_krb5_cred
173     $RUNAS touch $MOUNT/f2_2 || error "should not fail"
174     [ -f $MOUNT/f2_2 ] || error "$MOUNT/f2_2 not found"
175 }
176 run_test 2 "lfs flushctx"
177
178 test_3() {
179     local file=$MOUNT/f3
180
181     # create file
182     echo "aaaaaaaaaaaaaaaaa" > $file
183     chmod 0666 $file
184     $CHECKSTAT -p 0666 $file || error "$UID checkstat error"
185     $RUNAS $CHECKSTAT -p 0666 $file || error "$RUNAS_ID checkstat error"
186     $RUNAS cat $file > /dev/null || error "$RUNAS_ID cat error"
187
188     # start multiop
189     $RUNAS multiop $file o_r &
190     OPPID=$!
191     # wait multiop finish its open()
192     sleep 1
193
194     # cleanup all cred/ctx and check
195     # metadata check should fail, but file data check should success
196     # because we always use root credential to OSTs
197     $RUNAS kdestroy
198     $RUNAS $LFS flushctx
199     echo "destroied credentials/contexs for $RUNAS_ID"
200     $RUNAS $CHECKSTAT -p 0666 $file && error "checkstat succeed"
201     kill -s 10 $OPPID
202     wait $OPPID || error "read file data failed"
203     echo "read file data OK"
204
205     # restore and check again
206     restore_krb5_cred
207     echo "restored credentials for $RUNAS_ID"
208     $RUNAS $CHECKSTAT -p 0666 $file || error "$RUNAS_ID checkstat (2) error"
209     echo "$RUNAS_ID checkstat OK"
210     $CHECKSTAT -p 0666 $file || error "$UID checkstat (2) error"
211     echo "$UID checkstat OK"
212     $RUNAS cat $file > /dev/null || error "$RUNAS_ID cat (2) error"
213     echo "$RUNAS_ID read file data OK"
214 }
215 run_test 3 "local cache under DLM lock"
216
217 test_4() {
218     local file1=$MOUNT/f4_1
219     local file2=$MOUNT/f4_2
220
221     # current access should be ok
222     $RUNAS touch $file1 || error "can't touch $file1"
223     [ -f $file1 ] || error "$file1 not found"
224
225     # stop lgssd
226     send_sigint client lgssd
227     sleep 5
228     check_gss_daemon_facet client lgssd && error "lgssd still running"
229
230     # flush context, and touch
231     $RUNAS $LFS flushctx
232     $RUNAS touch $file2 &
233     TOUCHPID=$!
234     echo "waiting touch pid $TOUCHPID"
235     wait $TOUCHPID && error "touch should fail"
236
237     # restart lgssd
238     do_facet client "$LGSSD -v"
239     sleep 5
240     check_gss_daemon_facet client lgssd
241
242     # touch new should succeed
243     $RUNAS touch $file2 || error "can't touch $file2"
244     [ -f $file2 ] || error "$file2 not found"
245 }
246 run_test 4 "lgssd dead, operations should wait timeout and fail"
247
248 test_5() {
249     local file1=$MOUNT/f5_1
250     local file2=$MOUNT/f5_2
251     local wait_time=`expr $TIMEOUT + $TIMEOUT`
252
253     # current access should be ok
254     $RUNAS touch $file1 || error "can't touch $file1"
255     [ -f $file1 ] || error "$file1 not found"
256
257     # stop lsvcgssd
258     send_sigint mds lsvcgssd
259     sleep 5
260     check_gss_daemon_facet mds lsvcgssd && error "lsvcgssd still running"
261
262     # flush context, and touch
263     $RUNAS $LFS flushctx
264     $RUNAS touch $file2 &
265     TOUCHPID=$!
266
267     # wait certain time
268     echo "waiting $wait_time seconds for touch pid $TOUCHPID"
269     sleep $wait_time
270     num=`ps --no-headers -p $TOUCHPID | wc -l`
271     [ $num -eq 1 ] || error "touch already ended ($num)"
272     echo "process $TOUCHPID still hanging there... OK"
273
274     # restart lsvcgssd, expect touch suceed
275     echo "restart lsvcgssd and recovering"
276     do_facet mds "$LSVCGSSD -v"
277     sleep 5
278     check_gss_daemon_facet mds lsvcgssd
279     wait $TOUCHPID || error "touch fail"
280     [ -f $file2 ] || error "$file2 not found"
281 }
282 run_test 5 "lsvcgssd dead, operations lead to recovery"
283
284 test_6() {
285     NPROC=`cat /proc/cpuinfo 2>/dev/null | grep ^processor | wc -l`
286     [ $NPROC -ne 0 ] || NPROC=2
287
288     echo "starting dbench $NPROC"
289     sh rundbench $NPROC &
290     RUNPID=$!
291
292     for ((n=0;;n++)); do
293         sleep 2
294         num=`ps --no-headers -p $RUNPID | wc -l`
295         [ $num -ne 0 ] || break
296         echo "flush ctx ..."
297         $LFS flushctx
298     done
299     wait $RUNPID || error "dbench detect error"
300 }
301 run_test 6 "recoverable from losing context"
302
303 test_7() {
304     local tdir=$MOUNT/dir7
305     local num_osts
306
307     #
308     # for open(), client only reserve space for default stripe count lovea,
309     # and server may return larger lovea in reply (because of larger stripe
310     # count), client need call enlarge_reqbuf() and save the replied lovea
311     # in request for future possible replay.
312     #
313     # Note: current script does NOT guarantee enlarge_reqbuf() will be in
314     # the path, however it does work in local test which has 2 OSTs and
315     # default stripe count is 1.
316     #
317     num_osts=`$LFS getstripe $MOUNT | egrep "^[0-9]*:.*ACTIVE" | wc -l`
318     echo "found $num_osts active OSTs"
319     [ $num_osts -lt 2 ] && echo "skipping $TESTNAME (must have >= 2 OSTs)" && return
320
321     mkdir $tdir || error
322     $LFS setstripe $tdir 0 -1 -1 || error
323
324     echo "creating..."
325     for ((i=0;i<20;i++)); do
326         dd if=/dev/zero of=$tdir/f$i bs=4k count=16 2>/dev/null
327     done
328     echo "reading..."
329     for ((i=0;i<20;i++)); do
330         dd if=$tdir/f$i of=/dev/null bs=4k count=16 2>/dev/null
331     done
332     rm -rf $tdir
333 }
334 run_test 7 "exercise enlarge_reqbuf()"
335
336 check_multiple_gss_daemons() {
337     local facet=$1
338     local gssd=$2
339     local gssd_name=`basename $gssd`
340
341     for ((i=0;i<10;i++)); do
342         do_facet $facet "$gssd -v &"
343     done
344
345     # wait daemons entering "stable" status
346     sleep 5
347
348     num=`do_facet $facet ps -o cmd -C $gssd_name | grep $gssd_name | wc -l`
349     echo "$num instance(s) of $gssd_name are running"
350
351     if [ $num -ne 1 ]; then
352         error "$gssd_name not unique"
353     fi
354 }
355
356 test_100() {
357     local facet=mds
358
359     # cleanup everything at first
360     cleanupall
361
362     echo "bring up gss daemons..."
363     start_gss_daemons
364
365     echo "check with someone already running..."
366     check_multiple_gss_daemons $facet $LSVCGSSD
367     if [ "x$GSS_PIPEFS" == "xy" ]; then
368         check_multiple_gss_daemons $facet $LGSSD
369     fi
370
371     echo "check with someone run & finished..."
372     do_facet $facet killall -q -2 lgssd lsvcgssd || true
373     sleep 5 # wait fully exit
374     check_multiple_gss_daemons $facet $LSVCGSSD
375     if [ "x$GSS_PIPEFS" == "xy" ]; then
376         check_multiple_gss_daemons $facet $LGSSD
377     fi
378
379     echo "check refresh..."
380     do_facet $facet killall -q -2 lgssd lsvcgssd || true
381     sleep 5 # wait fully exit
382     do_facet $facet ipcrm -S 0x3b92d473
383     check_multiple_gss_daemons $facet $LSVCGSSD
384     if [ "x$GSS_PIPEFS" == "xy" ]; then
385         do_facet $facet ipcrm -S 0x3a92d473
386         check_multiple_gss_daemons $facet $LGSSD
387     fi
388
389     stop_gss_daemons
390 }
391 run_test 100 "start multiple gss daemons"
392
393 TMPDIR=$OLDTMPDIR
394 TMP=$OLDTMP
395 HOME=$OLDHOME
396
397 log "cleanup: ======================================================"
398 if [ "`mount | grep ^$NAME`" ]; then
399     rm -rf $DIR/[Rdfs][1-9]*
400 fi
401
402 cleanupall -f || error "cleanup failed"
403
404
405 echo '=========================== finished ==============================='
406 [ -f "$SANITYLOG" ] && cat $SANITYLOG && exit 1 || true