Whamcloud - gitweb
LU-10997 build: add files to .gitignore
[fs/lustre-release.git] / lustre / tests / sanity-gss.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10 # bug number for skipped test:
11 ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"$SANITY_GSS_EXCEPT"}
12 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
13
14 SRCDIR=`dirname $0`
15
16 export MULTIOP=${MULTIOP:-multiop}
17
18 LUSTRE=${LUSTRE:-`dirname $0`/..}
19 . $LUSTRE/tests/test-framework.sh
20 init_test_env $@
21 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
22 init_logging
23
24 require_dsh_mds || exit 0
25
26 [ "$SLOW" = "no" ] && EXCEPT_SLOW="100 101"
27
28 # $RUNAS_ID may get set incorrectly somewhere else
29 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] && error "\$RUNAS_ID set to 0, but \$UID is also 0!"
30
31 # remove $SEC, we'd like to control everything by ourselves
32 unset SEC
33
34 #
35 # global variables of this sanity
36 #
37 DBENCH_PID=0
38
39 # set manually
40 GSS=true
41
42 # we want double mount
43 MOUNT_2=${MOUNT_2:-"yes"}
44 check_and_setup_lustre
45
46 rm -rf $DIR/[df][0-9]*
47
48 check_runas_id $RUNAS_ID $RUNAS_ID $RUNAS
49
50 build_test_filter
51
52 start_dbench()
53 {
54     NPROC=`cat /proc/cpuinfo 2>/dev/null | grep ^processor | wc -l`
55     [ $NPROC -gt 2 ] && NPROC=2
56     sh rundbench $NPROC 1>/dev/null &
57     DBENCH_PID=$!
58     sleep 2
59
60     num=`ps --no-headers -p $DBENCH_PID 2>/dev/null | wc -l`
61     if [ $num -ne 1 ]; then
62         error "failed to start dbench $NPROC"
63     else
64         echo "started dbench with $NPROC processes at background"
65     fi
66
67     return 0
68 }
69
70 check_dbench()
71 {
72     num=`ps --no-headers -p $DBENCH_PID 2>/dev/null | wc -l`
73     if [ $num -eq 0 ]; then
74         echo "dbench $DBENCH_PID already finished"
75         wait $DBENCH_PID || error "dbench $PID exit with error"
76         start_dbench
77     elif [ $num -ne 1 ]; then
78         killall -9 dbench
79         error "found $num instance of pid $DBENCH_PID ???"
80     fi
81
82     return 0
83 }
84
85 stop_dbench()
86 {
87     for ((;;)); do
88         killall dbench 2>/dev/null
89         num=`ps --no-headers -p $DBENCH_PID | wc -l`
90         if [ $num -eq 0 ]; then
91             echo "dbench finished"
92             break
93         fi
94         echo "dbench $DBENCH_PID is still running, waiting 2s..."
95         sleep 2
96     done
97
98     wait $DBENCH_PID || true
99     sync || true
100 }
101
102 calc_connection_cnt
103 umask 077
104
105 echo "bring up gss daemons..."
106 # start gss daemon with -z flag for gssnull
107 start_gss_daemons $(comma_list $(mdts_nodes)) "$LSVCGSSD -z -vv" ||
108     error "can't start gss daemons on MDTs"
109 start_gss_daemons $(comma_list $(osts_nodes)) "$LSVCGSSD -z -vv" ||
110     error "can't start gss daemons on OSTs"
111
112 lctl set_param sptlrpc.gss.lgss_keyring.debug_level=4
113
114 echo "cat /etc/request-key.d/lgssc.conf"
115 cat /etc/request-key.d/lgssc.conf ||
116     error_noexit "/etc/request-key.d/lgssc.conf does not exist"
117 echo "cat /etc/request-key.conf"
118 cat /etc/request-key.conf ||
119     error_noexit "/etc/request-key.conf does not exist"
120
121 set_flavor_all gssnull
122
123 test_1() {
124         local file=$DIR/$tfile
125
126         chmod 0777 $DIR || error "chmod $DIR failed"
127         # access w/o context
128         $RUNAS $LFS flushctx $MOUNT || error "can't flush context on $MOUNT"
129         $RUNAS touch $DIR
130         $RUNAS touch $file || error "should not fail"
131         [ -f $file ] || error "$file not found"
132 }
133 run_test 1 "create file"
134
135 test_2() {
136     local file1=$DIR/$tfile-1
137     local file2=$DIR/$tfile-2
138
139     chmod 0777 $DIR || error "chmod $DIR failed"
140     # current access should be ok
141     $RUNAS touch $file1 || error "can't touch $file1"
142     [ -f $file1 ] || error "$file1 not found"
143
144         # cleanup all cred/ctx and touch
145         $RUNAS $LFS flushctx $MOUNT || error "can't flush context on $MOUNT"
146         $RUNAS touch $file2 && error "unexpected success"
147 }
148 run_test 2 "lfs flushctx"
149
150 test_3() {
151     local file=$DIR/$tfile
152
153     # create file
154     echo "aaaaaaaaaaaaaaaaa" > $file
155     chmod 0666 $file
156     $CHECKSTAT -p 0666 $file || error "$UID checkstat error"
157     $RUNAS $CHECKSTAT -p 0666 $file || error "$RUNAS_ID checkstat error"
158     $RUNAS cat $file > /dev/null || error "$RUNAS_ID cat error"
159
160     # start multiop
161     $RUNAS $MULTIOP $file o_r &
162     OPPID=$!
163     # wait multiop finish its open()
164     sleep 1
165
166     # cleanup all cred/ctx and check
167     # metadata check should fail, but file data check should success
168     # because we always use root credential to OSTs
169     $RUNAS $LFS flushctx $MOUNT || error "can't flush context on $MOUNT"
170     echo "destroied credentials/contexs for $RUNAS_ID"
171     $RUNAS $CHECKSTAT -p 0666 $file && error "checkstat succeed"
172     kill -s 10 $OPPID
173     wait $OPPID || error "read file data failed"
174     echo "read file data OK"
175 }
176 run_test 3 "local cache under DLM lock"
177
178 test_6() {
179     local nfile=10
180
181     mkdir $DIR/d6 || error "mkdir $DIR/d6 failed"
182     for ((i=0; i<$nfile; i++)); do
183         dd if=/dev/zero of=$DIR/d6/file$i bs=8k count=1 || error "dd file$i failed"
184     done
185     ls -l $DIR/d6/* > /dev/null || error "ls failed"
186     rm -rf $DIR2/d6/* || error "rm failed"
187     rmdir $DIR2/d6/ || error "rmdir failed"
188 }
189 run_test 6 "test basic DLM callback works"
190
191 test_7() {
192         local tdir=$DIR/d7
193         local num_osts
194
195         # for open(), client only reserve space for default stripe count lovea,
196         # and server may return larger lovea in reply (because of larger stripe
197         # count), client need call enlarge_reqbuf() and save the replied lovea
198         # in request for future possible replay.
199         #
200         # Note: current script does NOT guarantee enlarge_reqbuf() will be in
201         # the path, however it does work in local test which has 2 OSTs and
202         # default stripe count is 1.
203         num_osts=$($LFS getstripe $MOUNT | egrep "^[0-9]*:.*ACTIVE" | wc -l)
204         echo "found $num_osts active OSTs"
205         [ $num_osts -lt 2 ] &&
206                 echo "skipping $TESTNAME (must have >= 2 OSTs)" && return
207
208         mkdir $tdir || error "mkdir $tdir failed"
209         $LFS setstripe -c $num_osts $tdir || error "setstripe -c $num_osts"
210
211         echo "creating..."
212         for ((i = 0; i < 20; i++)); do
213                 dd if=/dev/zero of=$tdir/f$i bs=4k count=16 2>/dev/null
214         done
215         echo "reading..."
216         for ((i = 0; i < 20; i++)); do
217                 dd if=$tdir/f$i of=/dev/null bs=4k count=16 2>/dev/null
218         done
219         rm -rf $tdir
220 }
221 run_test 7 "exercise enlarge_reqbuf()"
222
223 test_8()
224 {
225     local ATHISTORY=$(do_facet $SINGLEMDS "find /sys/ -name at_history")
226     local ATOLDBASE=$(do_facet $SINGLEMDS "cat $ATHISTORY")
227     local REQ_DELAY
228     do_facet $SINGLEMDS "echo 8 >> $ATHISTORY"
229
230     mkdir -p $DIR/d8
231     chmod a+w $DIR/d8
232
233     $LCTL dk > /dev/null
234     debugsave
235     sysctl -w lnet.debug="+other"
236
237     # wait for the at estimation come down, this is faster
238     while [ true ]; do
239         REQ_DELAY=`lctl get_param -n mdc.${FSNAME}-MDT0000-mdc-*.timeouts |
240                    awk '/portal 12/ {print $5}' | tail -1`
241         [ $REQ_DELAY -le 5 ] && break
242         echo "current AT estimation is $REQ_DELAY, wait a little bit"
243         sleep 8
244     done
245     REQ_DELAY=$((${REQ_DELAY} + ${REQ_DELAY} / 4 + 5))
246
247     # sleep sometime in ctx handle
248     do_facet $SINGLEMDS lctl set_param fail_val=$REQ_DELAY
249 #define OBD_FAIL_SEC_CTX_HDL_PAUSE       0x1204
250     do_facet $SINGLEMDS lctl set_param fail_loc=0x1204
251
252     $RUNAS $LFS flushctx $MOUNT || error "can't flush context on $MOUNT"
253
254     $RUNAS touch $DIR/d8/f &
255     TOUCHPID=$!
256     echo "waiting for touch (pid $TOUCHPID) to finish..."
257     sleep 2 # give it a chance to really trigger context init rpc
258     do_facet $SINGLEMDS $LCTL set_param fail_loc=0
259     wait $TOUCHPID || error "touch should have succeeded"
260
261     $LCTL dk | grep "Early reply #" || error "No early reply"
262
263     debugrestore
264     do_facet $SINGLEMDS "echo $ATOLDBASE >> $ATHISTORY" || true
265 }
266 run_test 8 "Early reply sent for slow gss context negotiation"
267
268 #
269 # following tests will manipulate flavors and may end with any flavor set,
270 # so each test should not assume any start flavor.
271 #
272
273 test_90() {
274     if [ "$SLOW" = "no" ]; then
275         total=10
276     else
277         total=60
278     fi
279
280     restore_to_default_flavor
281         set_rule $FSNAME any any gssnull
282         wait_flavor all2all gssnull
283
284     start_dbench
285
286     for ((n=0;n<$total;n++)); do
287         sleep 2
288         check_dbench
289         echo "flush ctx ($n/$total) ..."
290         $LFS flushctx $MOUNT || error "can't flush context on $MOUNT"
291     done
292     check_dbench
293     #sleep to let ctxs be re-established
294     sleep 10
295     stop_dbench
296 }
297 run_test 90 "recoverable from losing contexts under load"
298
299 test_99() {
300     local nrule_old=0
301     local nrule_new=0
302     local max=64
303
304     #
305     # general rules
306     #
307     nrule_old=`do_facet mgs lctl get_param -n mgs.MGS.live.$FSNAME 2>/dev/null \
308                | grep "$FSNAME.srpc.flavor." | wc -l`
309     echo "original general rules: $nrule_old"
310
311     for ((i = $nrule_old; i < $max; i++)); do
312         set_rule $FSNAME elan$i any gssnull || error "set rule $i"
313     done
314     for ((i = $nrule_old; i < $max; i++)); do
315         set_rule $FSNAME elan$i any || error "remove rule $i"
316     done
317
318     nrule_new=`do_facet mgs lctl get_param -n mgs.MGS.live.$FSNAME 2>/dev/null \
319                | grep "$FSNAME.srpc.flavor." | wc -l`
320     if [ $nrule_new != $nrule_old ]; then
321         error "general rule: $nrule_new != $nrule_old"
322     fi
323 }
324 run_test 99 "set large number of sptlrpc rules"
325
326 error_dbench()
327 {
328     local err_str=$1
329
330     killall -9 dbench
331     sleep 1
332
333     error $err_str
334 }
335
336 test_100() {
337         # started from default flavors
338         restore_to_default_flavor
339
340         # running dbench background
341         start_dbench
342
343         #
344         # all: null -> gssnull -> plain
345         #
346         set_rule $FSNAME any any gssnull
347         wait_flavor all2all gssnull || error_dbench "1"
348         check_dbench
349
350         set_rule $FSNAME any any plain
351         wait_flavor all2all plain || error_dbench "2"
352         check_dbench
353
354         #
355         # M - M: gssnull
356         # C - M: gssnull
357         # M - O: gssnull
358         # C - O: gssnull
359         #
360         set_rule $FSNAME any mdt2mdt gssnull
361         wait_flavor mdt2mdt gssnull || error_dbench "3"
362         check_dbench
363
364         set_rule $FSNAME any cli2mdt gssnull
365         wait_flavor cli2mdt gssnull || error_dbench "4"
366         check_dbench
367
368         set_rule $FSNAME any mdt2ost gssnull
369         wait_flavor mdt2ost gssnull || error_dbench "5"
370         check_dbench
371
372         set_rule $FSNAME any cli2ost gssnull
373         wait_flavor cli2ost gssnull || error_dbench "6"
374         check_dbench
375
376         #
377         # * - MDT0: plain
378         # * - OST0: plain
379         #
380         # nothing should be changed because they are override by above dir rules
381         #
382         set_rule $FSNAME-MDT0000 any any plain
383         set_rule $FSNAME-OST0000 any any plain
384         wait_flavor mdt2mdt gssnull || error_dbench "7"
385         wait_flavor cli2mdt gssnull || error_dbench "8"
386         check_dbench
387         wait_flavor mdt2ost gssnull || error_dbench "9"
388         wait_flavor cli2ost gssnull || error_dbench "10"
389
390         #
391         # delete all dir-specific rules
392         #
393         set_rule $FSNAME any mdt2mdt
394         set_rule $FSNAME any cli2mdt
395         set_rule $FSNAME any mdt2ost
396         set_rule $FSNAME any cli2ost
397         wait_flavor mdt2mdt gssnull $((MDSCOUNT - 1)) || error_dbench "11"
398         wait_flavor cli2mdt gssnull $(get_clients_mount_count) ||
399                 error_dbench "12"
400         check_dbench
401         wait_flavor mdt2ost gssnull $MDSCOUNT || error_dbench "13"
402         wait_flavor cli2ost gssnull $(get_clients_mount_count) ||
403                 error_dbench "14"
404         check_dbench
405
406         #
407         # remove:
408         #  * - MDT0: gssnull
409         #  * - OST0: gssnull
410         #
411         set_rule $FSNAME-MDT0000 any any
412         set_rule $FSNAME-OST0000 any any || error_dbench "15"
413         wait_flavor all2all plain || error_dbench "16"
414         check_dbench
415
416         stop_dbench
417 }
418 run_test 100 "change security flavor on the fly under load"
419
420 switch_sec_test()
421 {
422     local flavor0=$1
423     local flavor1=$2
424     local filename=$DIR/$tfile
425     local multiop_pid
426     local num
427
428     #
429     # after set to flavor0, start multop which use flavor0 rpc, and let
430     # server drop the reply; then switch to flavor1, the resend should be
431     # completed using flavor1. To exercise the code of switching ctx/sec
432     # for a resend request.
433     #
434     log ">>>>>>>>>>>>>>> Testing $flavor0 -> $flavor1 <<<<<<<<<<<<<<<<<<<"
435
436     set_rule $FSNAME any cli2mdt $flavor0
437     wait_flavor cli2mdt $flavor0
438     rm -f $filename || error "remove old $filename failed"
439
440 #MDS_REINT = 36
441 #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
442     do_facet $SINGLEMDS lctl set_param fail_val=36
443     do_facet $SINGLEMDS lctl set_param fail_loc=0x513
444     log "starting multiop"
445     $MULTIOP $filename m &
446     multiop_pid=$!
447     echo "multiop pid=$multiop_pid"
448     sleep 1
449
450     set_rule $FSNAME any cli2mdt $flavor1
451     wait_flavor cli2mdt $flavor1
452
453     num=`ps --no-headers -p $multiop_pid 2>/dev/null | wc -l`
454     [ $num -eq 1 ] || error "multiop($multiop_pid) already ended ($num)"
455     echo "process $multiop_pid is still hanging there... OK"
456
457     do_facet $SINGLEMDS lctl set_param fail_loc=0
458     log "waiting for multiop ($multiop_pid) to finish"
459     wait $multiop_pid || error "multiop returned error"
460 }
461
462 test_101()
463 {
464         # started from default flavors
465         restore_to_default_flavor
466
467         switch_sec_test null    plain
468         switch_sec_test plain   gssnull
469         switch_sec_test gssnull null
470         switch_sec_test null    gssnull
471         switch_sec_test gssnull plain
472         switch_sec_test plain   gssnull
473 }
474 run_test 101 "switch ctx/sec for resending request"
475
476 error_102()
477 {
478     local err_str=$1
479
480     killall -9 dbench
481     sleep 1
482
483     error $err_str
484 }
485
486 test_102() {
487     # started from default flavors
488     restore_to_default_flavor
489
490     # run dbench background
491     start_dbench
492
493         echo "Testing null->gssnull->plain->null"
494         set_rule $FSNAME any any gssnull
495         set_rule $FSNAME any any plain
496         set_rule $FSNAME any any null
497
498     check_dbench
499     wait_flavor all2all null || error_dbench "1"
500     check_dbench
501
502     echo "waiting for 15s and check again"
503     sleep 15
504     check_dbench
505
506         echo "Testing null->gssnull->null->gssnull->null..."
507         for ((i=0; i<10; i++)); do
508                 set_rule $FSNAME any any gssnull
509                 set_rule $FSNAME any any null
510         done
511         set_rule $FSNAME any any gssnull
512
513         check_dbench
514         wait_flavor all2all gssnull || error_dbench "2"
515         check_dbench
516
517     echo "waiting for 15s and check again"
518     sleep 15
519     check_dbench
520
521     stop_dbench
522 }
523 run_test 102 "survive from insanely fast flavor switch"
524
525 test_150() {
526     local mount_opts
527     local count
528     local clients=$CLIENTS
529
530     [ -z $clients ] && clients=$HOSTNAME
531
532     # started from default flavors
533     restore_to_default_flavor
534
535     # at this time no rules has been set on mgs; mgc use null
536     # flavor connect to mgs.
537     count=`flvr_cnt_mgc2mgs null`
538     [ $count -eq 1 ] || error "$count mgc connection use null flavor"
539
540     zconf_umount_clients $clients $MOUNT || return 1
541
542     # mount client with conflict flavor - should fail
543     mount_opts="${MOUNT_OPTS:+$MOUNT_OPTS,}mgssec=gssnull"
544     zconf_mount_clients $clients $MOUNT $mount_opts &&
545         error "mount with conflict flavor should have failed"
546
547     # mount client with same flavor - should succeed
548     mount_opts="${MOUNT_OPTS:+$MOUNT_OPTS,}mgssec=null"
549     zconf_mount_clients $clients $MOUNT $mount_opts ||
550         error "mount with same flavor should have succeeded"
551     zconf_umount_clients $clients $MOUNT || return 2
552
553     # mount client with default flavor - should succeed
554     zconf_mount_clients $clients $MOUNT || \
555         error "mount with default flavor should have succeeded"
556 }
557 run_test 150 "secure mgs connection: client flavor setting"
558
559 test_151() {
560         local save_opts
561
562         # set mgs only accept gssnull
563         set_rule _mgs any any gssnull
564
565     # umount everything, modules still loaded
566     stopall
567
568     # mount mgs with default flavor, in current framework it means mgs+mdt1.
569     # the connection of mgc of mdt1 to mgs is expected fail.
570     DEVNAME=$(mdsdevname 1)
571     start mds1 $DEVNAME $MDS_MOUNT_OPTS && error "mount with default flavor should have failed"
572
573     # mount with unauthorized flavor should fail
574     save_opts=$MDS_MOUNT_OPTS
575     MDS_MOUNT_OPTS="$MDS_MOUNT_OPTS,mgssec=null"
576     start mds1 $DEVNAME $MDS_MOUNT_OPTS && error "mount with unauthorized flavor should have failed"
577     MDS_MOUNT_OPTS=$save_opts
578
579     # mount with designated flavor should succeed
580     save_opts=$MDS_MOUNT_OPTS
581         MDS_MOUNT_OPTS="$MDS_MOUNT_OPTS,mgssec=gssnull"
582         start mds1 $DEVNAME $MDS_MOUNT_OPTS ||
583                 error "mount with designated flavor should have succeeded"
584         MDS_MOUNT_OPTS=$save_opts
585
586         stop mds1 -f
587 }
588 run_test 151 "secure mgs connection: server flavor control"
589
590 stop_gss_daemons
591
592 complete $SECONDS
593 check_and_cleanup_lustre
594 exit_status