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