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