Whamcloud - gitweb
31cfae06494fae517316d42c75d9ffc4e3000e55
[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:-"$SANITY_GSS_EXCEPT"}
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # Tests that fail on uml
16 CPU=`awk '/model/ {print $4}' /proc/cpuinfo`
17 [ "$CPU" = "UML" ] && EXCEPT="$EXCEPT"
18
19 case `uname -r` in
20 2.6*) FSTYPE=${FSTYPE:-ldiskfs}; ALWAYS_EXCEPT="$ALWAYS_EXCEPT " ;;
21 *) error "unsupported kernel (gss only works with 2.6.x)" ;;
22 esac
23
24 SRCDIR=`dirname $0`
25 export PATH=$PWD/$SRCDIR:$SRCDIR:$SRCDIR/../utils:$SRCDIR/../utils/gss:$PATH:/sbin
26 export NAME=${NAME:-local}
27 SAVE_PWD=$PWD
28
29 CLEANUP=${CLEANUP:-""}
30 SETUP=${SETUP:-""}
31
32 LUSTRE=${LUSTRE:-`dirname $0`/..}
33 . $LUSTRE/tests/test-framework.sh
34 init_test_env $@
35 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
36
37 remote_mds_nodsh && skip "remote MDS with nodsh" && exit 0
38
39 [ "$SLOW" = "no" ] && EXCEPT_SLOW="100 101"
40
41 # $RUNAS_ID may get set incorrectly somewhere else
42 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] && error "\$RUNAS_ID set to 0, but \$UID is also 0!"
43
44 # remove $SEC, we'd like to control everything by ourselves
45 unset SEC
46
47 #
48 # global variables of this sanity
49 #
50 KRB5_CCACHE_DIR=/tmp
51 KRB5_CRED=$KRB5_CCACHE_DIR/krb5cc_$RUNAS_ID
52 KRB5_CRED_SAVE=$KRB5_CCACHE_DIR/krb5cc.sanity.save
53 CLICOUNT=2
54 cnt_mdt2ost=0
55 cnt_mdt2mdt=0
56 cnt_cli2ost=0
57 cnt_cli2mdt=0
58 cnt_all2ost=0
59 cnt_all2mdt=0
60 cnt_all2all=0
61 DBENCH_PID=0
62 PROC_CLI="srpc.info"
63 # Escape "." to use lctl
64 PROC_CLI=${PROC_CLI//\./\*} 
65
66 # set manually
67 GSS=true
68 GSS_KRB5=true
69
70 prepare_krb5_creds() {
71     echo prepare krb5 cred
72     rm -f $KRB5_CRED_SAVE
73     echo RUNAS=$RUNAS
74     $RUNAS krb5_login.sh || exit 1
75     [ -f $KRB5_CRED ] || exit 2
76     echo CRED=$KRB5_CRED
77     cp $KRB5_CRED $KRB5_CRED_SAVE
78 }
79
80 prepare_krb5_creds
81
82 # we want double mount
83 MOUNT_2=${MOUNT_2:-"yes"}
84 check_and_setup_lustre
85
86 rm -rf $DIR/[df][0-9]*
87
88 check_runas_id $RUNAS_ID $RUNAS
89
90 build_test_filter
91
92 combination()
93 {
94     local M=$1
95     local N=$2
96     local R=1
97
98     if [ $M -lt $N ]; then
99         R=0
100     else
101         N=$((N + 1))
102         while [ $N -le $M ]; do
103             R=$((R * N))
104             N=$((N + 1))
105         done
106     fi
107
108     echo $R
109     return 0
110 }
111
112 calc_connection_cnt() {
113     # MDT->MDT = 2 * C(M, 2)
114     # MDT->OST = M * O
115     # CLI->OST = C * O
116     # CLI->MDT = C * M
117     comb_m2=$(combination $MDSCOUNT 2)
118
119     cnt_mdt2mdt=$((comb_m2 * 2))
120     cnt_mdt2ost=$((MDSCOUNT * OSTCOUNT))
121     cnt_cli2ost=$((CLICOUNT * OSTCOUNT))
122     cnt_cli2mdt=$((CLICOUNT * MDSCOUNT))
123     cnt_all2ost=$((cnt_mdt2ost + cnt_cli2ost))
124     cnt_all2mdt=$((cnt_mdt2mdt + cnt_cli2mdt))
125     cnt_all2all=$((cnt_mdt2ost + cnt_mdt2mdt + cnt_cli2ost + cnt_cli2mdt))
126 }
127
128 set_rule()
129 {
130     local tgt=$1
131     local net=$2
132     local dir=$3
133     local flavor=$4
134     local cmd="$tgt.srpc.flavor"
135
136     if [ $net == "any" ]; then
137         net="default"
138     fi
139     cmd="$cmd.$net"
140
141     if [ $dir != "any" ]; then
142         cmd="$cmd.$dir"
143     fi
144
145     cmd="$cmd=$flavor"
146     log "Setting sptlrpc rule: $cmd"
147     do_facet mgs "$LCTL conf_param $cmd"
148 }
149
150 count_flvr()
151 {
152     local output=$1
153     local flavor=$2
154     local count=0
155
156     rpc_flvr=`echo $flavor | awk -F - '{ print $1 }'`
157     bulkspec=`echo $flavor | awk -F - '{ print $2 }'`
158
159     count=`echo "$output" | grep "rpc flavor" | grep $rpc_flvr | wc -l`
160
161     if [ "x$bulkspec" != "x" ]; then
162         algs=`echo $bulkspec | awk -F : '{ print $2 }'`
163
164         if [ "x$algs" != "x" ]; then
165             bulk_count=`echo "$output" | grep "bulk flavor" | grep $algs | wc -l`
166         else
167             bulk=`echo $bulkspec | awk -F : '{ print $1 }'`
168             if [ $bulk == "bulkn" ]; then
169                 bulk_count=`echo "$output" | grep "bulk flavor" \
170                             | grep "null/null" | wc -l`
171             elif [ $bulk == "bulki" ]; then
172                 bulk_count=`echo "$output" | grep "bulk flavor" \
173                             | grep "/null" | grep -v "null/" | wc -l`
174             else
175                 bulk_count=`echo "$output" | grep "bulk flavor" \
176                             | grep -v "/null" | grep -v "null/" | wc -l`
177             fi
178         fi
179
180         [ $bulk_count -lt $count ] && count=$bulk_count
181     fi
182
183     echo $count
184 }
185
186 flvr_cnt_cli2mdt()
187 {
188     local flavor=$1
189
190     output=`do_facet client lctl get_param -n mdc.*-MDT*-mdc-*.$PROC_CLI 2>/dev/null`
191     count_flvr "$output" $flavor
192 }
193
194 flvr_cnt_cli2ost()
195 {
196     local flavor=$1
197
198     output=`do_facet client lctl get_param -n osc.*OST*-osc-[^M][^D][^T]*.$PROC_CLI 2>/dev/null`
199     count_flvr "$output" $flavor
200 }
201
202 flvr_cnt_mdt2mdt()
203 {
204     local flavor=$1
205     local cnt=0
206
207     if [ $MDSCOUNT -le 1 ]; then
208         echo 0
209         return
210     fi
211
212     for num in `seq $MDSCOUNT`; do
213         output=`do_facet mds$num lctl get_param -n mdc.*-MDT*-mdc[0-9]*.$PROC_CLI 2>/dev/null`
214         tmpcnt=`count_flvr "$output" $flavor`
215         cnt=$((cnt + tmpcnt))
216     done
217     echo $cnt;
218 }
219
220 flvr_cnt_mdt2ost()
221 {
222     local flavor=$1
223     local cnt=0
224
225     for num in `seq $MDSCOUNT`; do
226         output=`do_facet mds$num lctl get_param -n osc.*OST*-osc-MDT*.$PROC_CLI 2>/dev/null`
227         tmpcnt=`count_flvr "$output" $flavor`
228         cnt=$((cnt + tmpcnt))
229     done
230     echo $cnt;
231 }
232
233 do_check_flavor()
234 {
235     local dir=$1        # from to
236     local flavor=$2     # flavor expected
237     local res=0
238
239     if [ $dir == "cli2mdt" ]; then
240         res=`flvr_cnt_cli2mdt $flavor`
241     elif [ $dir == "cli2ost" ]; then
242         res=`flvr_cnt_cli2ost $flavor`
243     elif [ $dir == "mdt2mdt" ]; then
244         res=`flvr_cnt_mdt2mdt $flavor`
245     elif [ $dir == "mdt2ost" ]; then
246         res=`flvr_cnt_mdt2ost $flavor`
247     elif [ $dir == "all2ost" ]; then
248         res1=`flvr_cnt_mdt2ost $flavor`
249         res2=`flvr_cnt_cli2ost $flavor`
250         res=$((res1 + res2))
251     elif [ $dir == "all2mdt" ]; then
252         res1=`flvr_cnt_mdt2mdt $flavor`
253         res2=`flvr_cnt_cli2mdt $flavor`
254         res=$((res1 + res2))
255     elif [ $dir == "all2all" ]; then
256         res1=`flvr_cnt_mdt2ost $flavor`
257         res2=`flvr_cnt_cli2ost $flavor`
258         res3=`flvr_cnt_mdt2mdt $flavor`
259         res4=`flvr_cnt_cli2mdt $flavor`
260         res=$((res1 + res2 + res3 + res4))
261     fi
262
263     echo $res
264 }
265
266 wait_flavor()
267 {
268     local dir=$1        # from to
269     local flavor=$2     # flavor expected
270     local expect=$3     # number expected
271     local res=0
272
273     for ((i=0;i<20;i++)); do
274         echo -n "checking..."
275         res=$(do_check_flavor $dir $flavor)
276         if [ $res -eq $expect ]; then
277             echo "found $res $flavor connections of $dir, OK"
278             return 0
279         else
280             echo "found $res $flavor connections of $dir, not ready ($expect)"
281             sleep 4
282         fi
283     done
284
285     echo "Error checking $flavor of $dir: expect $expect, actual $res"
286     return 1
287 }
288
289 restore_to_default_flavor()
290 {
291     local proc="mgs.MGS.live.$FSNAME"
292
293     echo "restoring to default flavor..."
294
295     nrule=`do_facet mgs lctl get_param -n $proc 2>/dev/null | grep ".srpc.flavor." | wc -l`
296
297     # remove all existing rules if any
298     if [ $nrule -ne 0 ]; then
299         echo "$nrule existing rules"
300         for rule in `do_facet mgs lctl get_param -n $proc 2>/dev/null | grep ".srpc.flavor."`; do
301             echo "remove rule: $rule"
302             spec=`echo $rule | awk -F = '{print $1}'`
303             do_facet mgs "$LCTL conf_param $spec="
304         done
305     fi
306
307     # verify no rules left
308     nrule=`do_facet mgs lctl get_param -n $proc 2>/dev/null | grep ".srpc.flavor." | wc -l`
309     [ $nrule -ne 0 ] && error "still $nrule rules left"
310
311     # wait for default flavor to be applied
312     # currently default flavor for all connections are 'null'
313     wait_flavor all2all null $cnt_all2all
314     echo "now at default flavor settings"
315 }
316
317 set_flavor_all()
318 {
319     local flavor=$1
320
321     echo "setting all flavor to $flavor"
322
323     res=$(do_check_flavor all2all $flavor)
324     if [ $res -eq $cnt_all2all ]; then
325         echo "already have total $res $flavor connections"
326         return
327     fi
328
329     echo "found $res $flavor out of total $cnt_all2all connections"
330     restore_to_default_flavor
331
332     set_rule $FSNAME any any $flavor
333     wait_flavor all2all $flavor $cnt_all2all
334 }
335
336 start_dbench()
337 {
338     NPROC=`cat /proc/cpuinfo 2>/dev/null | grep ^processor | wc -l`
339     [ $NPROC -gt 2 ] && NPROC=2
340     sh rundbench $NPROC 1>/dev/null &
341     DBENCH_PID=$!
342     sleep 2
343
344     num=`ps --no-headers -p $DBENCH_PID 2>/dev/null | wc -l`
345     if [ $num -ne 1 ]; then
346         error "failed to start dbench $NPROC"
347     else
348         echo "started dbench with $NPROC processes at background"
349     fi
350
351     return 0
352 }
353
354 check_dbench()
355 {
356     num=`ps --no-headers -p $DBENCH_PID 2>/dev/null | wc -l`
357     if [ $num -eq 0 ]; then
358         echo "dbench $DBENCH_PID already finished"
359         wait $DBENCH_PID || error "dbench $PID exit with error"
360         start_dbench
361     elif [ $num -ne 1 ]; then
362         killall -9 dbench
363         error "found $num instance of pid $DBENCH_PID ???"
364     fi
365
366     return 0
367 }
368
369 stop_dbench()
370 {
371     for ((;;)); do
372         killall dbench 2>/dev/null
373         num=`ps --no-headers -p $DBENCH_PID | wc -l`
374         if [ $num -eq 0 ]; then
375             echo "dbench finished"
376             break
377         fi
378         echo "dbench $DBENCH_PID is still running, waiting 2s..."
379         sleep 2
380     done
381
382     wait $DBENCH_PID || true
383     sync || true
384 }
385
386 restore_krb5_cred() {
387     cp $KRB5_CRED_SAVE $KRB5_CRED
388     chown $RUNAS_ID:$RUNAS_ID $KRB5_CRED
389     chmod 0600 $KRB5_CRED
390 }
391
392 check_multiple_gss_daemons() {
393     local facet=$1
394     local gssd=$2
395     local gssd_name=`basename $gssd`
396
397     for ((i=0;i<10;i++)); do
398         do_facet $facet "$gssd -v &"
399     done
400
401     # wait daemons entering "stable" status
402     sleep 5
403
404     num=`do_facet $facet ps -o cmd -C $gssd_name | grep $gssd_name | wc -l`
405     echo "$num instance(s) of $gssd_name are running"
406
407     if [ $num -ne 1 ]; then
408         error "$gssd_name not unique"
409     fi
410 }
411
412 calc_connection_cnt
413 umask 077
414
415 test_0() {
416     local my_facet=mds
417
418     echo "bring up gss daemons..."
419     start_gss_daemons
420
421     echo "check with someone already running..."
422     check_multiple_gss_daemons $my_facet $LSVCGSSD
423     if $GSS_PIPEFS; then
424         check_multiple_gss_daemons $my_facet $LGSSD
425     fi
426
427     echo "check with someone run & finished..."
428     do_facet $my_facet killall -q -2 lgssd lsvcgssd || true
429     sleep 5 # wait fully exit
430     check_multiple_gss_daemons $my_facet $LSVCGSSD
431     if $GSS_PIPEFS; then
432         check_multiple_gss_daemons $my_facet $LGSSD
433     fi
434
435     echo "check refresh..."
436     do_facet $my_facet killall -q -2 lgssd lsvcgssd || true
437     sleep 5 # wait fully exit
438     do_facet $my_facet ipcrm -S 0x3b92d473
439     check_multiple_gss_daemons $my_facet $LSVCGSSD
440     if $GSS_PIPEFS; then
441         do_facet $my_facet ipcrm -S 0x3a92d473
442         check_multiple_gss_daemons $my_facet $LGSSD
443     fi
444 }
445 run_test 0 "start multiple gss daemons"
446
447 set_flavor_all krb5p
448
449 test_1() {
450     local file=$DIR/$tfile
451
452     chmod 0777 $DIR || error "chmod $DIR failed"
453     # access w/o cred
454     $RUNAS kdestroy
455     $RUNAS touch $file && error "unexpected success"
456
457     # access w/ cred
458     restore_krb5_cred
459     $RUNAS touch $file || error "should not fail"
460     [ -f $file ] || error "$file not found"
461 }
462 run_test 1 "access with or without krb5 credential"
463
464 test_2() {
465     local file1=$DIR/$tfile-1
466     local file2=$DIR/$tfile-2
467
468     chmod 0777 $DIR || error "chmod $DIR failed"
469     # current access should be ok
470     $RUNAS touch $file1 || error "can't touch $file1"
471     [ -f $file1 ] || error "$file1 not found"
472
473     # cleanup all cred/ctx and touch
474     $RUNAS kdestroy
475     $RUNAS $LFS flushctx || error "can't flush ctx"
476     $RUNAS touch $file2 && error "unexpected success"
477
478     # restore and touch
479     restore_krb5_cred
480     $RUNAS touch $file2 || error "should not fail"
481     [ -f $file2 ] || error "$file2 not found"
482 }
483 run_test 2 "lfs flushctx"
484
485 test_3() {
486     local file=$DIR/$tfile
487
488     # create file
489     echo "aaaaaaaaaaaaaaaaa" > $file
490     chmod 0666 $file
491     $CHECKSTAT -p 0666 $file || error "$UID checkstat error"
492     $RUNAS $CHECKSTAT -p 0666 $file || error "$RUNAS_ID checkstat error"
493     $RUNAS cat $file > /dev/null || error "$RUNAS_ID cat error"
494
495     # start multiop
496     $RUNAS multiop $file o_r &
497     OPPID=$!
498     # wait multiop finish its open()
499     sleep 1
500
501     # cleanup all cred/ctx and check
502     # metadata check should fail, but file data check should success
503     # because we always use root credential to OSTs
504     $RUNAS kdestroy
505     $RUNAS $LFS flushctx
506     echo "destroied credentials/contexs for $RUNAS_ID"
507     $RUNAS $CHECKSTAT -p 0666 $file && error "checkstat succeed"
508     kill -s 10 $OPPID
509     wait $OPPID || error "read file data failed"
510     echo "read file data OK"
511
512     # restore and check again
513     restore_krb5_cred
514     echo "restored credentials for $RUNAS_ID"
515     $RUNAS $CHECKSTAT -p 0666 $file || error "$RUNAS_ID checkstat (2) error"
516     echo "$RUNAS_ID checkstat OK"
517     $CHECKSTAT -p 0666 $file || error "$UID checkstat (2) error"
518     echo "$UID checkstat OK"
519     $RUNAS cat $file > /dev/null || error "$RUNAS_ID cat (2) error"
520     echo "$RUNAS_ID read file data OK"
521 }
522 run_test 3 "local cache under DLM lock"
523
524 test_4() {
525     local file1=$DIR/$tfile-1
526     local file2=$DIR/$tfile-2
527
528     ! $GSS_PIPEFS && skip "pipefs not used" && return
529
530     chmod 0777 $DIR || error "chmod $DIR failed"
531     # current access should be ok
532     $RUNAS touch $file1 || error "can't touch $file1"
533     [ -f $file1 ] || error "$file1 not found"
534
535     # stop lgssd
536     send_sigint client lgssd
537     sleep 5
538     check_gss_daemon_facet client lgssd && error "lgssd still running"
539
540     # flush context, and touch
541     $RUNAS $LFS flushctx
542     $RUNAS touch $file2 &
543     TOUCHPID=$!
544     echo "waiting touch pid $TOUCHPID"
545     wait $TOUCHPID && error "touch should fail"
546
547     # restart lgssd
548     do_facet client "$LGSSD -v"
549     sleep 5
550     check_gss_daemon_facet client lgssd
551
552     # touch new should succeed
553     $RUNAS touch $file2 || error "can't touch $file2"
554     [ -f $file2 ] || error "$file2 not found"
555 }
556 run_test 4 "lgssd dead, operations should wait timeout and fail"
557
558 test_5() {
559     local file1=$DIR/$tfile-1
560     local file2=$DIR/$tfile-2
561     local wait_time=$((TIMEOUT + TIMEOUT / 2))
562
563     chmod 0777 $DIR || error "chmod $DIR failed"
564     # current access should be ok
565     $RUNAS touch $file1 || error "can't touch $file1"
566     [ -f $file1 ] || error "$file1 not found"
567
568     # stop lsvcgssd
569     send_sigint mds lsvcgssd
570     sleep 5
571     check_gss_daemon_facet mds lsvcgssd && error "lsvcgssd still running"
572
573     # flush context, and touch
574     $RUNAS $LFS flushctx
575     $RUNAS touch $file2 &
576     TOUCHPID=$!
577
578     # wait certain time
579     echo "waiting $wait_time seconds for touch pid $TOUCHPID"
580     sleep $wait_time
581     num=`ps --no-headers -p $TOUCHPID | wc -l`
582     [ $num -eq 1 ] || error "touch already ended ($num)"
583     echo "process $TOUCHPID still hanging there... OK"
584
585     # restart lsvcgssd, expect touch suceed
586     echo "restart lsvcgssd and recovering"
587     do_facet mds "$LSVCGSSD -v"
588     sleep 5
589     check_gss_daemon_facet mds lsvcgssd
590     wait $TOUCHPID || error "touch fail"
591     [ -f $file2 ] || error "$file2 not found"
592 }
593 run_test 5 "lsvcgssd dead, operations lead to recovery"
594
595 test_6() {
596     local nfile=10
597
598     mkdir $DIR/d6 || error "mkdir $DIR/d6 failed"
599     for ((i=0; i<$nfile; i++)); do
600         dd if=/dev/zero of=$DIR/d6/file$i bs=8k count=1 || error "dd file$i failed"
601     done
602     ls -l $DIR/d6/* > /dev/null || error "ls failed"
603     rm -rf $DIR2/d6/* || error "rm failed"
604     rmdir $DIR2/d6/ || error "rmdir failed"
605 }
606 run_test 6 "test basic DLM callback works"
607
608 test_7() {
609     local tdir=$DIR/d7
610     local num_osts
611
612     #
613     # for open(), client only reserve space for default stripe count lovea,
614     # and server may return larger lovea in reply (because of larger stripe
615     # count), client need call enlarge_reqbuf() and save the replied lovea
616     # in request for future possible replay.
617     #
618     # Note: current script does NOT guarantee enlarge_reqbuf() will be in
619     # the path, however it does work in local test which has 2 OSTs and
620     # default stripe count is 1.
621     #
622     num_osts=`$LFS getstripe $MOUNT | egrep "^[0-9]*:.*ACTIVE" | wc -l`
623     echo "found $num_osts active OSTs"
624     [ $num_osts -lt 2 ] && echo "skipping $TESTNAME (must have >= 2 OSTs)" && return
625
626     mkdir $tdir || error
627     $LFS setstripe -c $num_osts $tdir || error
628
629     echo "creating..."
630     for ((i=0;i<20;i++)); do
631         dd if=/dev/zero of=$tdir/f$i bs=4k count=16 2>/dev/null
632     done
633     echo "reading..."
634     for ((i=0;i<20;i++)); do
635         dd if=$tdir/f$i of=/dev/null bs=4k count=16 2>/dev/null
636     done
637     rm -rf $tdir
638 }
639 run_test 7 "exercise enlarge_reqbuf()"
640
641 test_8()
642 {
643     sleep $TIMEOUT
644     $LCTL dk > /dev/null
645     debugsave
646     sysctl -w lnet.debug="+other"
647
648     # sleep sometime in ctx handle
649     do_facet mds lctl set_param fail_val=30
650 #define OBD_FAIL_SEC_CTX_HDL_PAUSE       0x1204
651     do_facet mds lctl set_param fail_loc=0x1204
652
653     $RUNAS $LFS flushctx || error "can't flush ctx"
654
655     $RUNAS df $DIR &
656     DFPID=$!
657     echo "waiting df (pid $TOUCHPID) to finish..."
658     sleep 2 # give df a chance to really trigger context init rpc
659     do_facet mds sysctl -w lustre.fail_loc=0
660     wait $DFPID || error "df should have succeeded"
661
662     $LCTL dk | grep "Early reply #" || error "No early reply"
663     debugrestore
664 }
665 run_test 8 "Early reply sent for slow gss context negotiation"
666
667 #
668 # following tests will manipulate flavors and may end with any flavor set,
669 # so each test should not assume any start flavor.
670 #
671
672 test_50() {
673     local sample=$TMP/sanity-gss-8
674     local tdir=$MOUNT/dir8
675     local iosize="256K"
676     local hash_algs="adler32 crc32 md5 sha1 sha256 sha384 sha512 wp256 wp384 wp512"
677
678     # create sample file with aligned size for direct i/o
679     dd if=/dev/zero of=$sample bs=$iosize count=1 || error
680     dd conv=notrunc if=/etc/termcap of=$sample bs=$iosize count=1 || error
681
682     rm -rf $tdir
683     mkdir $tdir || error "create dir $tdir"
684
685     restore_to_default_flavor
686
687     for alg in $hash_algs; do
688         echo "Testing $alg..."
689         flavor=krb5i-bulki:$alg/null
690         set_rule $FSNAME any cli2ost $flavor
691         wait_flavor cli2ost $flavor $cnt_cli2ost
692
693         dd if=$sample of=$tdir/$alg oflag=direct,dsync bs=$iosize || error "$alg write"
694         diff $sample $tdir/$alg || error "$alg read"
695     done
696
697     rm -rf $tdir
698     rm -f $sample
699 }
700 run_test 50 "verify bulk hash algorithms works"
701
702 test_51() {
703     local s1=$TMP/sanity-gss-9.1
704     local s2=$TMP/sanity-gss-9.2
705     local s3=$TMP/sanity-gss-9.3
706     local s4=$TMP/sanity-gss-9.4
707     local tdir=$MOUNT/dir9
708     local s1_size=4194304   # n * pagesize (4M)
709     local s2_size=512       # n * blksize
710     local s3_size=111       # n * blksize + m
711     local s4_size=5         # m
712     local cipher_algs="arc4 aes128 aes192 aes256 cast128 cast256 twofish128 twofish256"
713
714     # create sample files for each situation
715     rm -f $s1 $s2 $s2 $s4
716     dd if=/dev/urandom of=$s1 bs=1M count=4 || error
717     dd if=/dev/urandom of=$s2 bs=$s2_size count=1 || error
718     dd if=/dev/urandom of=$s3 bs=$s3_size count=1 || error
719     dd if=/dev/urandom of=$s4 bs=$s4_size count=1 || error
720
721     rm -rf $tdir
722     mkdir $tdir || error "create dir $tdir"
723
724     restore_to_default_flavor
725
726     #
727     # different bulk data alignment will lead to different behavior of
728     # the implementation: (n > 0; 0 < m < encryption_block_size)
729     #  - full page i/o
730     #  - partial page, size = n * encryption_block_size
731     #  - partial page, size = n * encryption_block_size + m
732     #  - partial page, size = m
733     #
734     for alg in $cipher_algs; do
735         echo "Testing $alg..."
736         flavor=krb5p-bulkp:sha1/$alg
737         set_rule $FSNAME any cli2ost $flavor
738         wait_flavor cli2ost $flavor $cnt_cli2ost
739
740         # sync write
741         dd if=$s1 of=$tdir/$alg.1 oflag=dsync bs=1M || error "write $alg.1"
742         dd if=$s2 of=$tdir/$alg.2 oflag=dsync || error "write $alg.2"
743         dd if=$s3 of=$tdir/$alg.3 oflag=dsync || error "write $alg.3"
744         dd if=$s4 of=$tdir/$alg.4 oflag=dsync || error "write $alg.4"
745
746         # remount client
747         umount_client $MOUNT
748         umount_client $MOUNT2
749         mount_client $MOUNT
750         mount_client $MOUNT2
751
752         # read & compare
753         diff $tdir/$alg.1 $s1 || error "read $alg.1"
754         diff $tdir/$alg.2 $s2 || error "read $alg.2"
755         diff $tdir/$alg.3 $s3 || error "read $alg.3"
756         diff $tdir/$alg.4 $s4 || error "read $alg.4"
757     done
758
759     rm -rf $tdir
760     rm -f $sample
761 }
762 run_test 51 "bulk data alignment test under encryption mode"
763
764 test_90() {
765     if [ "$SLOW" = "no" ]; then
766         total=10
767     else
768         total=60
769     fi
770
771     restore_to_default_flavor
772     set_rule $FSNAME any any krb5p
773     wait_flavor all2all krb5p $cnt_all2all
774
775     start_dbench
776
777     for ((n=0;n<$total;n++)); do
778         sleep 2
779         check_dbench
780         echo "flush ctx ($n/$total) ..."
781         $LFS flushctx
782     done
783     check_dbench
784     #sleep to let ctxs be re-established
785     sleep 10
786     stop_dbench
787 }
788 run_test 90 "recoverable from losing contexts under load"
789
790 test_99() {
791     local nrule_old=0
792     local nrule_new=0
793     local max=64
794
795     #
796     # general rules
797     #
798     nrule_old=`do_facet mgs lctl get_param -n mgs.MGS.live.$FSNAME 2>/dev/null \
799                | grep "$FSNAME.srpc.flavor." | wc -l`
800     echo "original general rules: $nrule_old"
801
802     for ((i = $nrule_old; i < $max; i++)); do
803         set_rule $FSNAME elan$i any krb5n || error "set rule $i"
804     done
805     for ((i = $nrule_old; i < $max; i++)); do
806         set_rule $FSNAME elan$i any || error "remove rule $i"
807     done
808
809     nrule_new=`do_facet mgs lctl get_param -n mgs.MGS.live.$FSNAME 2>/dev/null \
810                | grep "$FSNAME.srpc.flavor." | wc -l`
811     if [ $nrule_new != $nrule_old ]; then
812         error "general rule: $nrule_new != $nrule_old"
813     fi
814
815     #
816     # target-specific rules
817     #
818     nrule_old=`do_facet mgs lctl get_param -n mgs.MGS.live.$FSNAME 2>/dev/null \
819                | grep "$FSNAME-MDT0000.srpc.flavor." | wc -l`
820     echo "original target rules: $nrule_old"
821
822     for ((i = $nrule_old; i < $max; i++)); do
823         set_rule $FSNAME-MDT0000 elan$i any krb5i || error "set rule $i"
824     done
825     for ((i = $nrule_old; i < $max; i++)); do
826         set_rule $FSNAME-MDT0000 elan$i any || error "remove rule $i"
827     done
828
829     nrule_new=`do_facet mgs lctl get_param -n mgs.MGS.live.$FSNAME 2>/dev/null \
830                | grep "$FSNAME-MDT0000.srpc.flavor." | wc -l`
831     if [ $nrule_new != $nrule_old ]; then
832         error "general rule: $nrule_new != $nrule_old"
833     fi
834 }
835 run_test 99 "set large number of sptlrpc rules"
836
837 error_dbench()
838 {
839     local err_str=$1
840
841     killall -9 dbench
842     sleep 1
843
844     error $err_str
845 }
846
847 test_100() {
848     # started from default flavors
849     restore_to_default_flavor
850
851     # running dbench background
852     start_dbench
853
854     #
855     # all: null -> krb5n -> krb5a -> krb5i -> krb5p -> plain
856     #
857     set_rule $FSNAME any any krb5n
858     wait_flavor all2all krb5n $cnt_all2all || error_dbench "1"
859     check_dbench
860
861     set_rule $FSNAME any any krb5a
862     wait_flavor all2all krb5a $cnt_all2all || error_dbench "2"
863     check_dbench
864
865     set_rule $FSNAME any any krb5i
866     wait_flavor all2all krb5i $cnt_all2all || error_dbench "3"
867     check_dbench
868
869     set_rule $FSNAME any any krb5p
870     wait_flavor all2all krb5p $cnt_all2all || error_dbench "4"
871     check_dbench
872
873     set_rule $FSNAME any any plain
874     wait_flavor all2all plain $cnt_all2all || error_dbench "5"
875     check_dbench
876
877     #
878     # M - M: krb5a
879     # C - M: krb5i
880     # M - O: krb5p
881     # C - O: krb5n
882     #
883     set_rule $FSNAME any mdt2mdt krb5a
884     wait_flavor mdt2mdt krb5a $cnt_mdt2mdt || error_dbench "6"
885     check_dbench
886
887     set_rule $FSNAME any cli2mdt krb5i
888     wait_flavor cli2mdt krb5i $cnt_cli2mdt || error_dbench "7"
889     check_dbench
890
891     set_rule $FSNAME any mdt2ost krb5p
892     wait_flavor mdt2ost krb5p $cnt_mdt2ost || error_dbench "8"
893     check_dbench
894
895     set_rule $FSNAME any cli2ost krb5n
896     wait_flavor cli2ost krb5n $cnt_cli2ost || error_dbench "9"
897     check_dbench
898
899     #
900     # * - MDT0: krb5p
901     # * - OST0: krb5i
902     #
903     # nothing should be changed because they are override by above dir rules
904     #
905     set_rule $FSNAME-MDT0000 any any krb5p
906     set_rule $FSNAME-OST0000 any any krb5i
907     wait_flavor mdt2mdt krb5a $cnt_mdt2mdt || error_dbench "10"
908     wait_flavor cli2mdt krb5i $cnt_cli2mdt || error_dbench "11"
909     check_dbench
910     wait_flavor mdt2ost krb5p $cnt_mdt2ost || error_dbench "12"
911     wait_flavor cli2ost krb5n $cnt_cli2ost || error_dbench "13"
912
913     #
914     # delete all dir-specific rules
915     #
916     set_rule $FSNAME any mdt2mdt
917     set_rule $FSNAME any cli2mdt
918     set_rule $FSNAME any mdt2ost
919     set_rule $FSNAME any cli2ost
920     wait_flavor mdt2mdt krb5p $((MDSCOUNT - 1)) || error_dbench "14"
921     wait_flavor cli2mdt krb5p $CLICOUNT || error_dbench "15"
922     check_dbench
923     wait_flavor mdt2ost krb5i $MDSCOUNT || error_dbench "16"
924     wait_flavor cli2ost krb5i $CLICOUNT || error_dbench "17"
925     check_dbench
926
927     #
928     # remove:
929     #  * - MDT0: krb5p
930     #  * - OST0: krb5i
931     #
932     set_rule $FSNAME-MDT0000 any any
933     set_rule $FSNAME-OST0000 any any || error_dbench "18"
934     wait_flavor all2all plain $cnt_all2all || error_dbench "19"
935     check_dbench
936
937     stop_dbench
938 }
939 run_test 100 "change security flavor on the fly under load"
940
941 switch_sec_test()
942 {
943     local count=$1
944     local flavor0=$2
945     local flavor1=$3
946     local flavor2=$4
947     local df_pid=0
948     local wait_time=$((TIMEOUT + TIMEOUT / 4))
949     local num
950
951     #
952     # stop gss daemon, then switch to flavor1 (which should be a gss flavor),
953     # and run a 'df' which should hanging, wait the request timeout and
954     # resend, then switch the flavor to another one. To exercise the code of
955     # switching ctx/sec for a resend request.
956     #
957     echo ">>>>>>>>>>>>>>> Testing $flavor0 -> $flavor1 -> $flavor2..."
958
959     echo "(0) set base flavor $flavor0"
960     set_rule $FSNAME any cli2mdt $flavor0
961     wait_flavor cli2mdt $flavor0 $count
962     df $MOUNT
963     if [ $? -ne 0 ]; then
964         error "initial df failed"
965     fi
966
967     stop_gss_daemons
968     sleep 1
969
970     echo "(1) $flavor0 -> $flavor1"
971     set_rule $FSNAME any cli2mdt $flavor1
972     wait_flavor cli2mdt $flavor1 $count
973     df $MOUNT &
974     df_pid=$!
975     sleep 1
976
977     echo "waiting $wait_time seconds for df ($df_pid)"
978     sleep $wait_time
979     num=`ps --no-headers -p $df_pid 2>/dev/null | wc -l`
980     [ $num -eq 1 ] || error "df already ended ($num)"
981     echo "process $df_pid is still hanging there... OK"
982
983     echo "(2) set end flavor $flavor2"
984     set_rule $FSNAME any cli2mdt $flavor2
985     wait_flavor cli2mdt $flavor2 $count
986     start_gss_daemons
987     wait $df_pid || error "df returned error"
988 }
989
990 test_101()
991 {
992     # started from default flavors
993     restore_to_default_flavor
994
995     switch_sec_test $cnt_cli2mdt null krb5n null
996     switch_sec_test $cnt_cli2mdt null krb5a null
997     switch_sec_test $cnt_cli2mdt null krb5i null
998     switch_sec_test $cnt_cli2mdt null krb5p null
999     switch_sec_test $cnt_cli2mdt null krb5i plain
1000     switch_sec_test $cnt_cli2mdt plain krb5p plain
1001     switch_sec_test $cnt_cli2mdt plain krb5n krb5a
1002     switch_sec_test $cnt_cli2mdt krb5a krb5i krb5p
1003     switch_sec_test $cnt_cli2mdt krb5p krb5a krb5n
1004     switch_sec_test $cnt_cli2mdt krb5n krb5p krb5i
1005 }
1006 run_test 101 "switch ctx as well as sec for resending request"
1007
1008 error_102()
1009 {
1010     local err_str=$1
1011
1012     killall -9 dbench
1013     sleep 1
1014
1015     error $err_str
1016 }
1017
1018 test_102() {
1019     # started from default flavors
1020     restore_to_default_flavor
1021
1022     # run dbench background
1023     start_dbench
1024
1025     echo "Testing null->krb5n->krb5a->krb5i->krb5p->plain->null"
1026     set_rule $FSNAME any any krb5n
1027     set_rule $FSNAME any any krb5a
1028     set_rule $FSNAME any any krb5i
1029     set_rule $FSNAME any any krb5p
1030     set_rule $FSNAME any any plain
1031     set_rule $FSNAME any any null
1032
1033     check_dbench
1034     wait_flavor all2all null $cnt_all2all || error_dbench "1"
1035     check_dbench
1036
1037     echo "waiting for 15s and check again"
1038     sleep 15
1039     check_dbench
1040
1041     echo "Testing null->krb5i->null->krb5i->null..."
1042     for ((i=0; i<10; i++)); do
1043         set_rule $FSNAME any any krb5i
1044         set_rule $FSNAME any any null
1045     done
1046     set_rule $FSNAME any any krb5i
1047
1048     check_dbench
1049     wait_flavor all2all krb5i $cnt_all2all || error_dbench "2"
1050     check_dbench
1051
1052     echo "waiting for 15s and check again"
1053     sleep 15
1054     check_dbench
1055
1056     stop_dbench
1057 }
1058 run_test 102 "survive from insanely fast flavor switch"
1059
1060 equals_msg `basename $0`: test complete, cleaning up
1061 check_and_cleanup_lustre
1062 [ -f "$TESTSUITELOG" ] && cat $TESTSUITELOG && grep -q FAIL $TESTSUITELOG && exit 1 || true