Whamcloud - gitweb
ee03c9accb5294a838a597c5e79f095ffbbfd765
[fs/lustre-release.git] / lustre / tests / recovery-small.sh
1 #!/bin/bash
2
3 set -e
4
5 #         bug  5494 5493
6 ALWAYS_EXCEPT="24   52 $RECOVERY_SMALL_EXCEPT"
7
8 export MULTIOP=${MULTIOP:-multiop}
9 PTLDEBUG=${PTLDEBUG:--1}
10 LUSTRE=${LUSTRE:-`dirname $0`/..}
11 . $LUSTRE/tests/test-framework.sh
12 init_test_env $@
13 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
14 init_logging
15
16 require_dsh_mds || exit 0
17
18 # also long tests: 19, 21a, 21e, 21f, 23, 27
19 #                                   1  2.5  2.5    4    4          (min)"
20 [ "$SLOW" = "no" ] && EXCEPT_SLOW="17  26a  26b    50   51     57"
21
22 build_test_filter
23
24 # Allow us to override the setup if we already have a mounted system by
25 # setting SETUP=" " and CLEANUP=" "
26 SETUP=${SETUP:-""}
27 CLEANUP=${CLEANUP:-""}
28
29 check_and_setup_lustre
30
31 assert_DIR
32 rm -rf $DIR/[df][0-9]*
33
34 test_1() {
35     drop_request "mcreate $DIR/f1"  || return 1
36     drop_reint_reply "mcreate $DIR/f2"    || return 2
37 }
38 run_test 1 "mcreate: drop req, drop rep"
39
40 test_2() {
41     drop_request "tchmod 111 $DIR/f2"  || return 1
42     drop_reint_reply "tchmod 666 $DIR/f2"    || return 2
43 }
44 run_test 2 "chmod: drop req, drop rep"
45
46 test_3() {
47     drop_request "statone $DIR/f2" || return 1
48     drop_reply "statone $DIR/f2"   || return 2
49 }
50 run_test 3 "stat: drop req, drop rep"
51
52 SAMPLE_NAME=f0.recovery-small.junk
53 SAMPLE_FILE=$TMP/$SAMPLE_NAME
54 # make this big, else test 9 doesn't wait for bulk -- bz 5595
55 dd if=/dev/urandom of=$SAMPLE_FILE bs=1M count=4
56
57 test_4() {
58     do_facet client "cp $SAMPLE_FILE $DIR/$SAMPLE_NAME" || return 1
59     drop_request "cat $DIR/$SAMPLE_NAME > /dev/null"   || return 2
60     drop_reply "cat $DIR/$SAMPLE_NAME > /dev/null"     || return 3
61 }
62 run_test 4 "open: drop req, drop rep"
63
64 RENAMED_AGAIN=$DIR/f0.renamed-again
65
66 test_5() {
67     drop_request "mv $DIR/$SAMPLE_NAME $DIR/$tfile-renamed" || return 1
68     drop_reint_reply "mv $DIR/$tfile-renamed $RENAMED_AGAIN" || return 2
69     do_facet client "checkstat -v $RENAMED_AGAIN"  || return 3
70 }
71 run_test 5 "rename: drop req, drop rep"
72
73 [ ! -e $RENAMED_AGAIN ] && cp $SAMPLE_FILE $RENAMED_AGAIN
74 LINK1=$DIR/f0.link1
75 LINK2=$DIR/f0.link2
76
77 test_6() {
78     drop_request "mlink $RENAMED_AGAIN $LINK1" || return 1
79     drop_reint_reply "mlink $RENAMED_AGAIN $LINK2"   || return 2
80 }
81 run_test 6 "link: drop req, drop rep"
82
83 [ ! -e $LINK1 ] && mlink $RENAMED_AGAIN $LINK1
84 [ ! -e $LINK2 ] && mlink $RENAMED_AGAIN $LINK2
85 test_7() {
86     drop_request "munlink $LINK1"   || return 1
87     drop_reint_reply "munlink $LINK2"     || return 2
88 }
89 run_test 7 "unlink: drop req, drop rep"
90
91 #bug 1423
92 test_8() {
93     drop_reint_reply "touch $DIR/$tfile"    || return 1
94 }
95 run_test 8 "touch: drop rep (bug 1423)"
96
97 #bug 1420
98 test_9() {
99     remote_ost_nodsh && skip "remote OST with nodsh" && return 0
100
101     pause_bulk "cp /etc/profile $DIR/$tfile"       || return 1
102     do_facet client "cp $SAMPLE_FILE $DIR/${tfile}.2"  || return 2
103     do_facet client "sync"
104     do_facet client "rm $DIR/$tfile $DIR/${tfile}.2" || return 3
105 }
106 run_test 9 "pause bulk on OST (bug 1420)"
107
108 #bug 1521
109 test_10() {
110     do_facet client mcreate $DIR/$tfile        || return 1
111     drop_bl_callback "chmod 0777 $DIR/$tfile"  || echo "evicted as expected"
112     # wait for the mds to evict the client
113     #echo "sleep $(($TIMEOUT*2))"
114     #sleep $(($TIMEOUT*2))
115     do_facet client touch $DIR/$tfile || echo "touch failed, evicted"
116     do_facet client checkstat -v -p 0777 $DIR/$tfile  || return 3
117     do_facet client "munlink $DIR/$tfile"
118 }
119 run_test 10 "finish request on server after client eviction (bug 1521)"
120
121 #bug 2460
122 # wake up a thread waiting for completion after eviction
123 test_11(){
124     do_facet client $MULTIOP $DIR/$tfile Ow  || return 1
125     do_facet client $MULTIOP $DIR/$tfile or  || return 2
126
127     cancel_lru_locks osc
128
129     do_facet client $MULTIOP $DIR/$tfile or  || return 3
130     drop_bl_callback $MULTIOP $DIR/$tfile Ow || echo "evicted as expected"
131
132     do_facet client munlink $DIR/$tfile  || return 4
133 }
134 run_test 11 "wake up a thread waiting for completion after eviction (b=2460)"
135
136 #b=2494
137 test_12(){
138     $LCTL mark $MULTIOP $DIR/$tfile OS_c
139     do_facet $SINGLEMDS "lctl set_param fail_loc=0x115"
140     clear_failloc $SINGLEMDS $((TIMEOUT * 2)) &
141     multiop_bg_pause $DIR/$tfile OS_c || return 1
142     PID=$!
143 #define OBD_FAIL_MDS_CLOSE_NET           0x115
144     kill -USR1 $PID
145     echo "waiting for multiop $PID"
146     wait $PID || return 2
147     do_facet client munlink $DIR/$tfile  || return 3
148 }
149 run_test 12 "recover from timed out resend in ptlrpcd (b=2494)"
150
151 # Bug 113, check that readdir lost recv timeout works.
152 test_13() {
153     mkdir -p $DIR/$tdir || return 1
154     touch $DIR/$tdir/newentry || return
155 # OBD_FAIL_MDS_READPAGE_NET|OBD_FAIL_ONCE
156     do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000104"
157     ls $DIR/$tdir || return 3
158     do_facet $SINGLEMDS "lctl set_param fail_loc=0"
159     rm -rf $DIR/$tdir || return 4
160 }
161 run_test 13 "mdc_readpage restart test (bug 1138)"
162
163 # Bug 113, check that readdir lost send timeout works.
164 test_14() {
165     mkdir -p $DIR/$tdir
166     touch $DIR/$tdir/newentry
167 # OBD_FAIL_MDS_SENDPAGE|OBD_FAIL_ONCE
168     do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000106"
169     ls $DIR/$tdir || return 1
170     do_facet $SINGLEMDS "lctl set_param fail_loc=0"
171 }
172 run_test 14 "mdc_readpage resend test (bug 1138)"
173
174 test_15() {
175     do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000128"
176     touch $DIR/$tfile && return 1
177     return 0
178 }
179 run_test 15 "failed open (-ENOMEM)"
180
181 READ_AHEAD=`lctl get_param -n llite.*.max_read_ahead_mb | head -n 1`
182 stop_read_ahead() {
183    lctl set_param -n llite.*.max_read_ahead_mb 0
184 }
185
186 start_read_ahead() {
187    lctl set_param -n llite.*.max_read_ahead_mb $READ_AHEAD
188 }
189
190 test_16() {
191     remote_ost_nodsh && skip "remote OST with nodsh" && return 0
192
193     do_facet client cp $SAMPLE_FILE $DIR
194     sync
195     stop_read_ahead
196
197 #define OBD_FAIL_PTLRPC_BULK_PUT_NET 0x504 | OBD_FAIL_ONCE
198     do_facet ost1 "lctl set_param fail_loc=0x80000504"
199     cancel_lru_locks osc
200     # OST bulk will time out here, client resends
201     do_facet client "cmp $SAMPLE_FILE $DIR/${SAMPLE_FILE##*/}" || return 1
202     do_facet ost1 lctl set_param fail_loc=0
203     # give recovery a chance to finish (shouldn't take long)
204     sleep $TIMEOUT
205     do_facet client "cmp $SAMPLE_FILE $DIR/${SAMPLE_FILE##*/}" || return 2
206     start_read_ahead
207 }
208 run_test 16 "timeout bulk put, don't evict client (2732)"
209
210 test_17() {
211     local at_max_saved=0
212
213     remote_ost_nodsh && skip "remote OST with nodsh" && return 0
214
215     # With adaptive timeouts, bulk_get won't expire until adaptive_timeout_max
216     if at_is_enabled; then
217         at_max_saved=$(at_max_get ost1)
218         at_max_set $TIMEOUT ost1
219     fi
220
221     # OBD_FAIL_PTLRPC_BULK_GET_NET 0x0503 | OBD_FAIL_ONCE
222     # OST bulk will time out here, client retries
223     do_facet ost1 lctl set_param fail_loc=0x80000503
224     # need to ensure we send an RPC
225     do_facet client cp $SAMPLE_FILE $DIR/$tfile
226     sync
227
228     # with AT, client will wait adaptive_max*factor+net_latency before
229     # expiring the req, hopefully timeout*2 is enough
230     sleep $(($TIMEOUT*2))
231
232     do_facet ost1 lctl set_param fail_loc=0
233     do_facet client "df $DIR"
234     # expect cmp to succeed, client resent bulk
235     do_facet client "cmp $SAMPLE_FILE $DIR/$tfile" || return 3
236     do_facet client "rm $DIR/$tfile" || return 4
237     [ $at_max_saved -ne 0 ] && at_max_set $at_max_saved ost1
238     return 0
239 }
240 run_test 17 "timeout bulk get, don't evict client (2732)"
241
242 test_18a() {
243     [ -z ${ost2_svc} ] && skip_env "needs 2 osts" && return 0
244
245     do_facet client mkdir -p $DIR/$tdir
246     f=$DIR/$tdir/$tfile
247
248     cancel_lru_locks osc
249     pgcache_empty || return 1
250
251     # 1 stripe on ost2
252     $LFS setstripe -i 1 -c 1 $f
253     stripe_index=$($LFS getstripe -i $f)
254     if [ $stripe_index -ne 1 ]; then
255         $LFS getstripe $f
256         error "$f: stripe_index $stripe_index != 1" && return
257     fi
258
259     do_facet client cp $SAMPLE_FILE $f
260     sync
261     local osc2dev=`lctl get_param -n devices | grep ${ost2_svc}-osc- | egrep -v 'MDT' | awk '{print $1}'`
262     $LCTL --device $osc2dev deactivate || return 3
263     # my understanding is that there should be nothing in the page
264     # cache after the client reconnects?     
265     rc=0
266     pgcache_empty || rc=2
267     $LCTL --device $osc2dev activate
268     rm -f $f
269     return $rc
270 }
271 run_test 18a "manual ost invalidate clears page cache immediately"
272
273 test_18b() {
274     remote_ost_nodsh && skip "remote OST with nodsh" && return 0
275
276     do_facet client mkdir -p $DIR/$tdir
277     f=$DIR/$tdir/$tfile
278
279     cancel_lru_locks osc
280     pgcache_empty || return 1
281
282     $LFS setstripe -i 0 -c 1 $f
283     stripe_index=$($LFS getstripe -i $f)
284     if [ $stripe_index -ne 0 ]; then
285         $LFS getstripe $f
286         error "$f: stripe_index $stripe_index != 0" && return
287     fi
288
289     do_facet client cp $SAMPLE_FILE $f
290     sync
291     ost_evict_client
292     # allow recovery to complete
293     sleep $((TIMEOUT + 2))
294     # my understanding is that there should be nothing in the page
295     # cache after the client reconnects?     
296     rc=0
297     pgcache_empty || rc=2
298     rm -f $f
299     return $rc
300 }
301 run_test 18b "eviction and reconnect clears page cache (2766)"
302
303 test_18c() {
304     remote_ost_nodsh && skip "remote OST with nodsh" && return 0
305
306     do_facet client mkdir -p $DIR/$tdir
307     f=$DIR/$tdir/$tfile
308
309     cancel_lru_locks osc
310     pgcache_empty || return 1
311
312     $LFS setstripe -i 0 -c 1 $f
313     stripe_index=$($LFS getstripe -i $f)
314     if [ $stripe_index -ne 0 ]; then
315         $LFS getstripe $f
316         error "$f: stripe_index $stripe_index != 0" && return
317     fi
318
319     do_facet client cp $SAMPLE_FILE $f
320     sync
321     ost_evict_client
322
323     # OBD_FAIL_OST_CONNECT_NET2
324     # lost reply to connect request
325     do_facet ost1 lctl set_param fail_loc=0x80000225
326     # force reconnect
327     sleep 1
328     df $MOUNT > /dev/null 2>&1
329     sleep 2
330     # my understanding is that there should be nothing in the page
331     # cache after the client reconnects?     
332     rc=0
333     pgcache_empty || rc=2
334     rm -f $f
335     return $rc
336 }
337 run_test 18c "Dropped connect reply after eviction handing (14755)"
338
339 test_19a() {
340         local BEFORE=`date +%s`
341         local EVICT
342
343         mount_client $DIR2
344
345         do_facet client mcreate $DIR/$tfile        || return 1
346         drop_ldlm_cancel "chmod 0777 $DIR2"
347
348         umount_client $DIR2
349         do_facet client "munlink $DIR/$tfile"
350
351         # let the client reconnect
352         sleep 5
353         EVICT=$(do_facet client $LCTL get_param mdc.$FSNAME-MDT*.state | \
354             awk -F"[ [,]" '/EVICTED]$/ { if (mx<$4) {mx=$4;} } END { print mx }')
355
356         [ ! -z "$EVICT" ] && [[ $EVICT -gt $BEFORE ]] || error "no eviction"
357 }
358 run_test 19a "test expired_lock_main on mds (2867)"
359
360 test_19b() {
361         local BEFORE=`date +%s`
362         local EVICT
363
364         mount_client $DIR2
365
366         do_facet client $MULTIOP $DIR/$tfile Ow  || return 1
367         drop_ldlm_cancel $MULTIOP $DIR2/$tfile Ow
368         umount_client $DIR2
369         do_facet client munlink $DIR/$tfile
370
371         # let the client reconnect
372         sleep 5
373         EVICT=$(do_facet client $LCTL get_param osc.$FSNAME-OST*.state | \
374             awk -F"[ [,]" '/EVICTED]$/ { if (mx<$4) {mx=$4;} } END { print mx }')
375
376         [ ! -z "$EVICT" ] && [[ $EVICT -gt $BEFORE ]] || error "no eviction"
377 }
378 run_test 19b "test expired_lock_main on ost (2867)"
379
380 test_20a() {    # bug 2983 - ldlm_handle_enqueue cleanup
381         remote_ost_nodsh && skip "remote OST with nodsh" && return 0
382
383         mkdir -p $DIR/$tdir
384         $LFS setstripe -i 0 -c 1 $DIR/$tdir/${tfile}
385         multiop_bg_pause $DIR/$tdir/${tfile} O_wc || return 1
386         MULTI_PID=$!
387         cancel_lru_locks osc
388 #define OBD_FAIL_LDLM_ENQUEUE_EXTENT_ERR 0x308
389         do_facet ost1 lctl set_param fail_loc=0x80000308
390         kill -USR1 $MULTI_PID
391         wait $MULTI_PID
392         rc=$?
393         [ $rc -eq 0 ] && error "multiop didn't fail enqueue: rc $rc" || true
394 }
395 run_test 20a "ldlm_handle_enqueue error (should return error)" 
396
397 test_20b() {    # bug 2986 - ldlm_handle_enqueue error during open
398         remote_ost_nodsh && skip "remote OST with nodsh" && return 0
399
400         mkdir -p $DIR/$tdir
401         $LFS setstripe -i 0 -c 1 $DIR/$tdir/${tfile}
402         cancel_lru_locks osc
403 #define OBD_FAIL_LDLM_ENQUEUE_EXTENT_ERR 0x308
404         do_facet ost1 lctl set_param fail_loc=0x80000308
405         dd if=/etc/hosts of=$DIR/$tdir/$tfile && \
406                 error "didn't fail open enqueue" || true
407 }
408 run_test 20b "ldlm_handle_enqueue error (should return error)"
409
410 test_21a() {
411        mkdir -p $DIR/$tdir-1
412        mkdir -p $DIR/$tdir-2
413        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
414        close_pid=$!
415
416        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000129"
417        $MULTIOP $DIR/$tdir-2/f Oc &
418        open_pid=$!
419        sleep 1
420        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
421
422        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000115"
423        kill -USR1 $close_pid
424        cancel_lru_locks mdc
425        wait $close_pid || return 1
426        wait $open_pid || return 2
427        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
428
429        $CHECKSTAT -t file $DIR/$tdir-1/f || return 3
430        $CHECKSTAT -t file $DIR/$tdir-2/f || return 4
431
432        rm -rf $DIR/$tdir-*
433 }
434 run_test 21a "drop close request while close and open are both in flight"
435
436 test_21b() {
437        mkdir -p $DIR/$tdir-1
438        mkdir -p $DIR/$tdir-2
439        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
440        close_pid=$!
441
442        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000107"
443        mcreate $DIR/$tdir-2/f &
444        open_pid=$!
445        sleep 1
446        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
447
448        kill -USR1 $close_pid
449        cancel_lru_locks mdc
450        wait $close_pid || return 1
451        wait $open_pid || return 3
452
453        $CHECKSTAT -t file $DIR/$tdir-1/f || return 4
454        $CHECKSTAT -t file $DIR/$tdir-2/f || return 5
455        rm -rf $DIR/$tdir-*
456 }
457 run_test 21b "drop open request while close and open are both in flight"
458
459 test_21c() {
460        mkdir -p $DIR/$tdir-1
461        mkdir -p $DIR/$tdir-2
462        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
463        close_pid=$!
464
465        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000107"
466        mcreate $DIR/$tdir-2/f &
467        open_pid=$!
468        sleep 3
469        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
470
471        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000115"
472        kill -USR1 $close_pid
473        cancel_lru_locks mdc
474        wait $close_pid || return 1
475        wait $open_pid || return 2
476
477        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
478
479        $CHECKSTAT -t file $DIR/$tdir-1/f || return 2
480        $CHECKSTAT -t file $DIR/$tdir-2/f || return 3
481        rm -rf $DIR/$tdir-*
482 }
483 run_test 21c "drop both request while close and open are both in flight"
484
485 test_21d() {
486        mkdir -p $DIR/$tdir-1
487        mkdir -p $DIR/$tdir-2
488        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
489        pid=$!
490
491        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000129"
492        $MULTIOP $DIR/$tdir-2/f Oc &
493        sleep 1
494        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
495
496        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000122"
497        kill -USR1 $pid
498        cancel_lru_locks mdc
499        wait $pid || return 1
500        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
501
502        $CHECKSTAT -t file $DIR/$tdir-1/f || return 2
503        $CHECKSTAT -t file $DIR/$tdir-2/f || return 3
504
505        rm -rf $DIR/$tdir-*
506 }
507 run_test 21d "drop close reply while close and open are both in flight"
508
509 test_21e() {
510        mkdir -p $DIR/$tdir-1
511        mkdir -p $DIR/$tdir-2
512        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
513        pid=$!
514
515        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000119"
516        touch $DIR/$tdir-2/f &
517        sleep 1
518        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
519
520        kill -USR1 $pid
521        cancel_lru_locks mdc
522        wait $pid || return 1
523
524        sleep $TIMEOUT
525        $CHECKSTAT -t file $DIR/$tdir-1/f || return 2
526        $CHECKSTAT -t file $DIR/$tdir-2/f || return 3
527        rm -rf $DIR/$tdir-*
528 }
529 run_test 21e "drop open reply while close and open are both in flight"
530
531 test_21f() {
532        mkdir -p $DIR/$tdir-1
533        mkdir -p $DIR/$tdir-2
534        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
535        pid=$!
536
537        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000119"
538        touch $DIR/$tdir-2/f &
539        sleep 1
540        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
541
542        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000122"
543        kill -USR1 $pid
544        cancel_lru_locks mdc
545        wait $pid || return 1
546        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
547
548        $CHECKSTAT -t file $DIR/$tdir-1/f || return 2
549        $CHECKSTAT -t file $DIR/$tdir-2/f || return 3
550        rm -rf $DIR/$tdir-*
551 }
552 run_test 21f "drop both reply while close and open are both in flight"
553
554 test_21g() {
555        mkdir -p $DIR/$tdir-1
556        mkdir -p $DIR/$tdir-2
557        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
558        pid=$!
559
560        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000119"
561        touch $DIR/$tdir-2/f &
562        sleep 1
563        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
564
565        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000115"
566        kill -USR1 $pid
567        cancel_lru_locks mdc
568        wait $pid || return 1
569        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
570
571        $CHECKSTAT -t file $DIR/$tdir-1/f || return 2
572        $CHECKSTAT -t file $DIR/$tdir-2/f || return 3
573        rm -rf $DIR/$tdir-*
574 }
575 run_test 21g "drop open reply and close request while close and open are both in flight"
576
577 test_21h() {
578        mkdir -p $DIR/$tdir-1
579        mkdir -p $DIR/$tdir-2
580        multiop_bg_pause $DIR/$tdir-1/f O_c || return 1
581        pid=$!
582
583        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000107"
584        touch $DIR/$tdir-2/f &
585        touch_pid=$!
586        sleep 1
587        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
588
589        do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000122"
590        cancel_lru_locks mdc
591        kill -USR1 $pid
592        wait $pid || return 1
593        do_facet $SINGLEMDS "lctl set_param fail_loc=0"
594
595        wait $touch_pid || return 2
596
597        $CHECKSTAT -t file $DIR/$tdir-1/f || return 3
598        $CHECKSTAT -t file $DIR/$tdir-2/f || return 4
599        rm -rf $DIR/$tdir-*
600 }
601 run_test 21h "drop open request and close reply while close and open are both in flight"
602
603 # bug 3462 - multiple MDC requests
604 test_22() {
605     f1=$DIR/${tfile}-1
606     f2=$DIR/${tfile}-2
607     
608     do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000115"
609     $MULTIOP $f2 Oc &
610     close_pid=$!
611
612     sleep 1
613     $MULTIOP $f1 msu || return 1
614
615     cancel_lru_locks mdc
616     do_facet $SINGLEMDS "lctl set_param fail_loc=0"
617
618     wait $close_pid || return 2
619     rm -rf $f2 || return 4
620 }
621 run_test 22 "drop close request and do mknod"
622
623 test_23() { #b=4561
624     multiop_bg_pause $DIR/$tfile O_c || return 1
625     pid=$!
626     # give a chance for open
627     sleep 5
628
629     # try the close
630     drop_request "kill -USR1 $pid"
631
632     fail $SINGLEMDS
633     wait $pid || return 1
634     return 0
635 }
636 run_test 23 "client hang when close a file after mds crash"
637
638 test_24() { # bug 11710 details correct fsync() behavior
639         remote_ost_nodsh && skip "remote OST with nodsh" && return 0
640
641         mkdir -p $DIR/$tdir
642         $LFS setstripe -i 0 -c 1 $DIR/$tdir
643         cancel_lru_locks osc
644         multiop_bg_pause $DIR/$tdir/$tfile Owy_wyc || return 1
645         MULTI_PID=$!
646         ost_evict_client
647         kill -USR1 $MULTI_PID
648         wait $MULTI_PID
649         rc=$?
650         lctl set_param fail_loc=0x0
651         client_reconnect
652         [ $rc -eq 0 ] && error_ignore 5494 "multiop didn't fail fsync: rc $rc" || true
653 }
654 run_test 24 "fsync error (should return error)"
655
656 wait_client_evicted () {
657         local facet=$1
658         local exports=$2
659         local varsvc=${facet}_svc
660
661         wait_update $(facet_active_host $facet) \
662                 "lctl get_param -n *.${!varsvc}.num_exports | cut -d' ' -f2" \
663                 $((exports - 1)) $3
664 }
665
666 test_26a() {      # was test_26 bug 5921 - evict dead exports by pinger
667 # this test can only run from a client on a separate node.
668         remote_ost || { skip "local OST" && return 0; }
669         remote_ost_nodsh && skip "remote OST with nodsh" && return 0
670         remote_mds || { skip "local MDS" && return 0; }
671
672         if [ $(facet_host mgs) = $(facet_host ost1) ]; then
673                 skip "msg and ost1 are at the same node"
674                 return 0
675         fi
676
677         check_timeout || return 1
678
679         local OST_NEXP=$(do_facet ost1 lctl get_param -n obdfilter.${ost1_svc}.num_exports | cut -d' ' -f2)
680
681         echo starting with $OST_NEXP OST exports
682 # OBD_FAIL_PTLRPC_DROP_RPC 0x505
683         do_facet client lctl set_param fail_loc=0x505
684         # evictor takes PING_EVICT_TIMEOUT + 3 * PING_INTERVAL to evict.
685         # But if there's a race to start the evictor from various obds,
686         # the loser might have to wait for the next ping.
687
688         local rc=0
689         wait_client_evicted ost1 $OST_NEXP $((TIMEOUT * 2 + TIMEOUT * 3 / 4))
690         rc=$?
691         do_facet client lctl set_param fail_loc=0x0
692         [ $rc -eq 0 ] || error "client not evicted from OST"
693 }
694 run_test 26a "evict dead exports"
695
696 test_26b() {      # bug 10140 - evict dead exports by pinger
697         remote_ost_nodsh && skip "remote OST with nodsh" && return 0
698
699         if [ $(facet_host mgs) = $(facet_host ost1) ]; then
700                 skip "msg and ost1 are at the same node"
701                 return 0
702         fi
703
704         check_timeout || return 1
705         clients_up
706         zconf_mount `hostname` $MOUNT2 ||
707                 { error "Failed to mount $MOUNT2"; return 2; }
708         sleep 1 # wait connections being established
709
710         local MDS_NEXP=$(do_facet $SINGLEMDS lctl get_param -n mdt.${mds1_svc}.num_exports | cut -d' ' -f2)
711         local OST_NEXP=$(do_facet ost1 lctl get_param -n obdfilter.${ost1_svc}.num_exports | cut -d' ' -f2)
712
713         echo starting with $OST_NEXP OST and $MDS_NEXP MDS exports
714
715         zconf_umount `hostname` $MOUNT2 -f
716
717         # PING_INTERVAL max(obd_timeout / 4, 1U)
718         # PING_EVICT_TIMEOUT (PING_INTERVAL * 6)
719
720         # evictor takes PING_EVICT_TIMEOUT + 3 * PING_INTERVAL to evict.  
721         # But if there's a race to start the evictor from various obds, 
722         # the loser might have to wait for the next ping.
723         # = 9 * PING_INTERVAL + PING_INTERVAL
724         # = 10 PING_INTERVAL = 10 obd_timeout / 4 = 2.5 obd_timeout
725         # let's wait $((TIMEOUT * 3)) # bug 19887
726         local rc=0
727         wait_client_evicted ost1 $OST_NEXP $((TIMEOUT * 3)) || \
728                 error "Client was not evicted by ost" rc=1
729         wait_client_evicted $SINGLEMDS $MDS_NEXP $((TIMEOUT * 3)) || \
730                 error "Client was not evicted by mds"
731 }
732 run_test 26b "evict dead exports"
733
734 test_27() {
735         mkdir -p $DIR/$tdir
736         writemany -q -a $DIR/$tdir/$tfile 0 5 &
737         CLIENT_PID=$!
738         sleep 1
739         local save_FAILURE_MODE=$FAILURE_MODE
740         FAILURE_MODE="SOFT"
741         facet_failover $SINGLEMDS
742 #define OBD_FAIL_OSC_SHUTDOWN            0x407
743         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000407
744         # need to wait for reconnect
745         echo waiting for fail_loc
746         wait_update_facet $SINGLEMDS "lctl get_param -n fail_loc" "-2147482617"
747         facet_failover $SINGLEMDS
748         #no crashes allowed!
749         kill -USR1 $CLIENT_PID
750         wait $CLIENT_PID 
751         true
752         FAILURE_MODE=$save_FAILURE_MODE
753 }
754 run_test 27 "fail LOV while using OSC's"
755
756 test_28() {      # bug 6086 - error adding new clients
757         do_facet client mcreate $DIR/$tfile       || return 1
758         drop_bl_callback "chmod 0777 $DIR/$tfile" ||echo "evicted as expected"
759         #define OBD_FAIL_MDS_CLIENT_ADD 0x12f
760         do_facet $SINGLEMDS "lctl set_param fail_loc=0x8000012f"
761         # fail once (evicted), reconnect fail (fail_loc), ok
762         client_up || (sleep 10; client_up) || (sleep 10; client_up) || error "reconnect failed"
763         rm -f $DIR/$tfile
764         fail $SINGLEMDS         # verify MDS last_rcvd can be loaded
765 }
766 run_test 28 "handle error adding new clients (bug 6086)"
767
768 test_29a() { # bug 22273 - error adding new clients
769         #define OBD_FAIL_TGT_CLIENT_ADD 0x711
770         do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000711"
771         # fail abort so client will be new again
772         fail_abort $SINGLEMDS
773         client_up || error "reconnect failed"
774         return 0
775 }
776 run_test 29a "error adding new clients doesn't cause LBUG (bug 22273)"
777
778 test_29b() { # bug 22273 - error adding new clients
779         #define OBD_FAIL_TGT_CLIENT_ADD 0x711
780         do_facet ost1 "lctl set_param fail_loc=0x80000711"
781         # fail abort so client will be new again
782         fail_abort ost1
783         client_up || error "reconnect failed"
784         return 0
785 }
786 run_test 29b "error adding new clients doesn't cause LBUG (bug 22273)"
787
788 test_50() {
789         mkdir -p $DIR/$tdir
790         # put a load of file creates/writes/deletes
791         writemany -q $DIR/$tdir/$tfile 0 5 &
792         CLIENT_PID=$!
793         echo writemany pid $CLIENT_PID
794         sleep 10
795         FAILURE_MODE="SOFT"
796         fail $SINGLEMDS
797         # wait for client to reconnect to MDS
798         sleep 60
799         fail $SINGLEMDS
800         sleep 60
801         fail $SINGLEMDS
802         # client process should see no problems even though MDS went down
803         sleep $TIMEOUT
804         kill -USR1 $CLIENT_PID
805         wait $CLIENT_PID 
806         rc=$?
807         echo writemany returned $rc
808         #these may fail because of eviction due to slow AST response.
809         [ $rc -eq 0 ] || error_ignore 13652 "writemany returned rc $rc" || true
810 }
811 run_test 50 "failover MDS under load"
812
813 test_51() {
814         #define OBD_FAIL_MDS_SYNC_CAPA_SL                    0x1310
815         do_facet ost1 lctl set_param fail_loc=0x00001310
816
817         mkdir -p $DIR/$tdir
818         # put a load of file creates/writes/deletes
819         writemany -q $DIR/$tdir/$tfile 0 5 &
820         CLIENT_PID=$!
821         sleep 1
822         FAILURE_MODE="SOFT"
823         facet_failover $SINGLEMDS
824         # failover at various points during recovery
825         SEQ="1 5 10 $(seq $TIMEOUT 5 $(($TIMEOUT+10)))"
826         echo will failover at $SEQ
827         for i in $SEQ
828           do
829           echo failover in $i sec
830           sleep $i
831           facet_failover $SINGLEMDS
832         done
833         # client process should see no problems even though MDS went down
834         # and recovery was interrupted
835         sleep $TIMEOUT
836         kill -USR1 $CLIENT_PID
837         wait $CLIENT_PID 
838         rc=$?
839         echo writemany returned $rc
840         [ $rc -eq 0 ] || error_ignore 13652 "writemany returned rc $rc" || true
841 }
842 run_test 51 "failover MDS during recovery"
843
844 test_52_guts() {
845         do_facet client "mkdir -p $DIR/$tdir"
846         do_facet client "writemany -q -a $DIR/$tdir/$tfile 300 5" &
847         CLIENT_PID=$!
848         echo writemany pid $CLIENT_PID
849         sleep 10
850         FAILURE_MODE="SOFT"
851         fail ost1
852         rc=0
853         wait $CLIENT_PID || rc=$?
854         # active client process should see an EIO for down OST
855         [ $rc -eq 5 ] && { echo "writemany correctly failed $rc" && return 0; }
856         # but timing or failover setup may allow success
857         [ $rc -eq 0 ] && { echo "writemany succeeded" && return 0; }
858         echo "writemany returned $rc"
859         return $rc
860 }
861
862 test_52() {
863         remote_ost_nodsh && skip "remote OST with nodsh" && return 0
864
865         mkdir -p $DIR/$tdir
866         test_52_guts
867         rc=$?
868         [ $rc -ne 0 ] && { return $rc; }
869         # wait for client to reconnect to OST
870         sleep 30
871         test_52_guts
872         rc=$?
873         [ $rc -ne 0 ] && { return $rc; }
874         sleep 30
875         test_52_guts
876         rc=$?
877         client_reconnect
878         #return $rc
879 }
880 run_test 52 "failover OST under load"
881
882 # test of open reconstruct
883 test_53() {
884         touch $DIR/$tfile
885         drop_ldlm_reply "openfile -f O_RDWR:O_CREAT -m 0755 $DIR/$tfile" ||\
886                 return 2
887 }
888 run_test 53 "touch: drop rep"
889
890 test_54() {
891         zconf_mount `hostname` $MOUNT2
892         touch $DIR/$tfile
893         touch $DIR2/$tfile.1
894         sleep 10
895         cat $DIR2/$tfile.missing # save transno = 0, rc != 0 into last_rcvd
896         fail $SINGLEMDS
897         umount $MOUNT2
898         ERROR=`dmesg | egrep "(test 54|went back in time)" | tail -n1 | grep "went back in time"`
899         [ x"$ERROR" == x ] || error "back in time occured"
900 }
901 run_test 54 "back in time"
902
903 # bug 11330 - liblustre application death during I/O locks up OST
904 test_55() {
905         remote_ost_nodsh && skip "remote OST with nodsh" && return 0
906
907         mkdir -p $DIR/$tdir
908
909         # first dd should be finished quickly
910         $LFS setstripe -c 1 -i 0 $DIR/$tdir/$tfile-1
911         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=32M count=4  &
912         DDPID=$!
913         count=0
914         echo  "step1: testing ......"
915         while [ true ]; do
916             if [ -z `ps x | awk '$1 == '$DDPID' { print $5 }'` ]; then break; fi
917             count=$[count+1]
918             if [ $count -gt 64 ]; then
919                 error "dd should be finished!"
920             fi
921             sleep 1
922         done    
923         echo "(dd_pid=$DDPID, time=$count)successful"
924
925         $LFS setstripe -c 1 -i 0 $DIR/$tdir/$tfile-2
926         #define OBD_FAIL_OST_DROP_REQ            0x21d
927         do_facet ost1 lctl set_param fail_loc=0x0000021d
928         # second dd will be never finished
929         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=32M count=4  &        
930         DDPID=$!
931         count=0
932         echo  "step2: testing ......"
933         while [ $count -le 64 ]; do
934             dd_name="`ps x | awk '$1 == '$DDPID' { print $5 }'`"            
935             if [ -z  $dd_name ]; then 
936                 ls -l $DIR/$tdir
937                 echo  "debug: (dd_name=$dd_name, dd_pid=$DDPID, time=$count)"
938                 error "dd shouldn't be finished!"
939             fi
940             count=$[count+1]
941             sleep 1
942         done    
943         echo "(dd_pid=$DDPID, time=$count)successful"
944
945         #Recover fail_loc and dd will finish soon
946         do_facet ost1 lctl set_param fail_loc=0
947         count=0
948         echo  "step3: testing ......"
949         while [ true ]; do
950             if [ -z `ps x | awk '$1 == '$DDPID' { print $5 }'` ]; then break; fi
951             count=$[count+1]
952             if [ $count -gt 500 ]; then
953                 error "dd should be finished!"
954             fi
955             sleep 1
956         done    
957         echo "(dd_pid=$DDPID, time=$count)successful"
958
959         rm -rf $DIR/$tdir
960 }
961 run_test 55 "ost_brw_read/write drops timed-out read/write request"
962
963 test_56() { # b=11277
964 #define OBD_FAIL_MDS_RESEND      0x136
965         touch $DIR/$tfile
966         do_facet $SINGLEMDS "lctl set_param fail_loc=0x80000136"
967         stat $DIR/$tfile
968         do_facet $SINGLEMDS "lctl set_param fail_loc=0"
969         rm -f $DIR/$tfile
970 }
971 run_test 56 "do not allow reconnect to busy exports"
972
973 test_57_helper() {
974         # no oscs means no client or mdt 
975         while lctl get_param osc.*.* > /dev/null 2>&1; do
976                 : # loop until proc file is removed
977         done
978 }
979
980 test_57() { # bug 10866
981         test_57_helper &
982         pid=$!
983         sleep 1
984 #define OBD_FAIL_LPROC_REMOVE            0xB00
985         lctl set_param fail_loc=0x80000B00
986         zconf_umount `hostname` $DIR
987         lctl set_param fail_loc=0x80000B00
988         fail_abort $SINGLEMDS
989         kill -9 $pid
990         lctl set_param fail_loc=0
991         mount_client $DIR
992         do_facet client "df $DIR"
993 }
994 run_test 57 "read procfs entries causes kernel crash"
995
996 test_58() { # bug 11546
997 #define OBD_FAIL_MDC_ENQUEUE_PAUSE        0x801
998         touch $DIR/$tfile
999         ls -la $DIR/$tfile
1000         lctl set_param fail_loc=0x80000801
1001         cp $DIR/$tfile /dev/null &
1002         pid=$!
1003         sleep 1
1004         lctl set_param fail_loc=0
1005         drop_bl_callback rm -f $DIR/$tfile
1006         wait $pid
1007         do_facet client "df $DIR"
1008 }
1009 run_test 58 "Eviction in the middle of open RPC reply processing"
1010
1011 test_59() { # bug 10589
1012         zconf_mount `hostname` $MOUNT2 || error "Failed to mount $MOUNT2"
1013         echo $DIR2 | grep -q $MOUNT2 || error "DIR2 is not set properly: $DIR2"
1014 #define OBD_FAIL_LDLM_CANCEL_EVICT_RACE  0x311
1015         lctl set_param fail_loc=0x311
1016         writes=$(LANG=C dd if=/dev/zero of=$DIR2/$tfile count=1 2>&1)
1017         [ $? = 0 ] || error "dd write failed"
1018         writes=$(echo $writes | awk  -F '+' '/out/ {print $1}')
1019         lctl set_param fail_loc=0
1020         sync
1021         zconf_umount `hostname` $MOUNT2 -f
1022         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1)
1023         [ $? = 0 ] || error "dd read failed"
1024         reads=$(echo $reads | awk -F '+' '/in/ {print $1}')
1025         [ "$reads" -eq "$writes" ] || error "read" $reads "blocks, must be" $writes
1026 }
1027 run_test 59 "Read cancel race on client eviction"
1028
1029 err17935 () {
1030     # we assume that all md changes are in the MDT0 changelog
1031     if [ $MDSCOUNT -gt 1 ]; then
1032         error_ignore 17935 $*
1033     else
1034         error $*
1035     fi
1036 }
1037
1038 test_60() {
1039         MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid | \
1040             awk '{gsub(/_UUID/,""); print $1}' | head -1)
1041
1042         NUM_FILES=15000
1043         mkdir -p $DIR/$tdir
1044
1045         # Register (and start) changelog
1046         USER=$(do_facet $SINGLEMDS lctl --device $MDT0 changelog_register -n)
1047         echo "Registered as $MDT0 changelog user $USER"
1048
1049         # Generate a large number of changelog entries
1050         createmany -o $DIR/$tdir/$tfile $NUM_FILES
1051         sync
1052         sleep 5
1053
1054         # Unlink files in the background
1055         unlinkmany $DIR/$tdir/$tfile $NUM_FILES &
1056         CLIENT_PID=$!
1057         sleep 1
1058
1059         # Failover the MDS while unlinks are happening
1060         facet_failover $SINGLEMDS
1061
1062         # Wait for unlinkmany to finish
1063         wait $CLIENT_PID
1064
1065         # Check if all the create/unlink events were recorded
1066         # in the changelog
1067         $LFS changelog $MDT0 >> $DIR/$tdir/changelog
1068         local cl_count=$(grep UNLNK $DIR/$tdir/changelog | wc -l)
1069         echo "$cl_count unlinks in $MDT0 changelog"
1070
1071         do_facet $SINGLEMDS lctl --device $MDT0 changelog_deregister $USER
1072         USERS=$(( $(do_facet $SINGLEMDS lctl get_param -n \
1073             mdd.$MDT0.changelog_users | wc -l) - 2 ))
1074         if [ $USERS -eq 0 ]; then
1075             [ $cl_count -eq $NUM_FILES ] || \
1076                 err17935 "Recorded ${cl_count} unlinks out of $NUM_FILES"
1077             # Also make sure we can clear large changelogs
1078             cl_count=$($LFS changelog $FSNAME | wc -l)
1079             [ $cl_count -le 2 ] || \
1080                 error "Changelog not empty: $cl_count entries"
1081         else
1082             # If there are other users, there may be other unlinks in the log
1083             [ $cl_count -ge $NUM_FILES ] || \
1084                 err17935 "Recorded ${cl_count} unlinks out of $NUM_FILES"
1085             echo "$USERS other changelog users; can't verify clear"
1086         fi
1087 }
1088 run_test 60 "Add Changelog entries during MDS failover"
1089
1090 test_61()
1091 {
1092         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1093         mdtosc=${mdtosc/-MDT*/-MDT\*}
1094         local cflags="osc.$mdtosc.connect_flags"
1095         do_facet $SINGLEMDS "lctl get_param -n $cflags" |grep -q skip_orphan
1096         [ $? -ne 0 ] && skip "don't have skip orphan feature" && return
1097
1098         mkdir -p $DIR/$tdir || error "mkdir dir $DIR/$tdir failed"
1099         # Set the default stripe of $DIR/$tdir to put the files to ost1
1100         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1101
1102         replay_barrier $SINGLEMDS
1103         createmany -o $DIR/$tdir/$tfile-%d 10 
1104         local oid=`do_facet ost1 "lctl get_param -n obdfilter.${ost1_svc}.last_id"`
1105
1106         fail_abort $SINGLEMDS
1107         
1108         touch $DIR/$tdir/$tfile
1109         local id=`$LFS getstripe $DIR/$tdir/$tfile | awk '$1 == 0 { print $2 }'`
1110         [ $id -le $oid ] && error "the orphan objid was reused, failed"
1111
1112         # Cleanup
1113         rm -rf $DIR/$tdir
1114 }
1115 run_test 61 "Verify to not reuse orphan objects - bug 17025"
1116
1117 check_cli_ir_state()
1118 {
1119         local NODE=${1:-$HOSTNAME}
1120         local st
1121         st=$(do_node $NODE "lctl get_param mgc.*.ir_state |
1122                             awk '/imperative_recovery:/ { print \\\$2}'")
1123         [ $st != ON -o $st != OFF ] ||
1124                 error "Error state $st, must be ON or OFF"
1125         echo -n $st
1126 }
1127
1128 check_target_ir_state()
1129 {
1130         local target=${1}
1131         local name=${target}_svc
1132         local recovery_proc=obdfilter.${!name}.recovery_status
1133         local st
1134
1135         st=$(do_facet $target "lctl get_param -n $recovery_proc |
1136                                awk '/IR:/{ print \\\$2}'")
1137         [ $st != ON -o $st != OFF ] ||
1138                 error "Error state $st, must be ON or OFF"
1139         echo -n $st
1140 }
1141
1142 set_ir_status()
1143 {
1144         do_facet mgs lctl set_param -n mgs.MGS.live.$FSNAME="state=$1"
1145 }
1146
1147 get_ir_status()
1148 {
1149         local state=$(do_facet mgs "lctl get_param -n mgs.MGS.live.$FSNAME |
1150                                     awk '/state:/{ print \\\$2 }'")
1151         echo -n ${state/,/}
1152 }
1153
1154 nidtbl_version_mgs()
1155 {
1156         local ver=$(do_facet mgs "lctl get_param -n mgs.MGS.live.$FSNAME |
1157                                   awk '/nidtbl_version:/{ print \\\$2 }'")
1158         echo -n $ver
1159 }
1160
1161 # nidtbl_version_client <mds1|client> [node]
1162 nidtbl_version_client()
1163 {
1164         local cli=$1
1165         local node=${2:-$HOSTNAME}
1166
1167         if [ X$cli = Xclient ]; then
1168                 cli=$FSNAME-client
1169         else
1170                 local obdtype=${cli/%[0-9]*/}
1171                 [ $obdtype != mds ] && error "wrong parameters $cli"
1172
1173                 node=$(facet_active_host $cli)
1174                 local t=${cli}_svc
1175                 cli=${!t}
1176         fi
1177
1178         local vers=$(do_node $node "lctl get_param -n mgc.*.ir_state" |
1179                      awk "/$cli/{print \$6}" |sort -u)
1180
1181         # in case there are multiple mounts on the client node
1182         local arr=($vers)
1183         [ ${#arr[@]} -ne 1 ] && error "versions on client node mismatch"
1184         echo -n $vers
1185 }
1186
1187 nidtbl_versions_match()
1188 {
1189         [ $(nidtbl_version_mgs) -eq $(nidtbl_version_client ${1:-client}) ]
1190 }
1191
1192 target_instance_match()
1193 {
1194         local srv=$1
1195         local obdtype
1196         local cliname
1197
1198         obdtype=${srv/%[0-9]*/}
1199         case $obdtype in
1200         mds)
1201                 obdname="mdt"
1202                 cliname="mdc"
1203                 ;;
1204         ost)
1205                 obdname="obdfilter"
1206                 cliname="osc"
1207                 ;;
1208         *)
1209                 error "invalid target type" $srv
1210                 return 1
1211                 ;;
1212         esac
1213
1214         local target=${srv}_svc
1215         local si=$(do_facet $srv lctl get_param -n $obdname.${!target}.instance)
1216         local ci=$(lctl get_param -n $cliname.${!target}-${cliname}-*.import | \
1217                   awk '/instance/{ print $2 }' |head -1)
1218
1219         return $([ $si -eq $ci ])
1220 }
1221
1222 test_100()
1223 {
1224         do_facet mgs $LCTL list_param mgs.*.ir_timeout ||
1225                 { skip "MGS without IR support"; return 0; }
1226
1227         # disable IR
1228         set_ir_status disabled
1229
1230         local saved_FAILURE_MODE=$FAILURE_MODE
1231         [ $(facet_host mgs) = $(facet_host ost1) ] && FAILURE_MODE="SOFT"
1232         fail ost1
1233
1234         # valid check
1235         nidtbl_versions_match &&
1236                 error "version must differ due to IR disabled"
1237         target_instance_match ost1 || error "instance mismatch"
1238
1239         # restore env
1240         set_ir_status full
1241         FAILURE_MODE=$saved_FAILURE_MODE
1242 }
1243 run_test 100 "IR: Make sure normal recovery still works w/o IR"
1244
1245 test_101()
1246 {
1247         do_facet mgs $LCTL list_param mgs.*.ir_timeout ||
1248                 { skip "MGS without IR support"; return 0; }
1249
1250         set_ir_status full
1251
1252         local OST1_IMP=$(get_osc_import_name client ost1)
1253
1254         # disable pinger recovery
1255         lctl set_param -n osc.$OST1_IMP.pinger_recov=0
1256
1257         fail ost1
1258
1259         target_instance_match ost1 || error "instance mismatch"
1260         nidtbl_versions_match || error "version must match"
1261
1262         lctl set_param -n osc.$OST1_IMP.pinger_recov=1
1263 }
1264 run_test 101 "IR: Make sure IR works w/o normal recovery"
1265
1266 test_102()
1267 {
1268         do_facet mgs $LCTL list_param mgs.*.ir_timeout ||
1269                 { skip "MGS without IR support"; return 0; }
1270
1271         local clients=${CLIENTS:-$HOSTNAME}
1272         local old_version
1273         local new_version
1274         local mgsdev=mgs
1275
1276         set_ir_status full
1277
1278         # let's have a new nidtbl version
1279         fail ost1
1280
1281         # sleep for a while so that clients can see the failure of ost
1282         # it must be MGC_TIMEOUT_MIN_SECONDS + MGC_TIMEOUT_RAND_CENTISEC.
1283         # int mgc_request.c:
1284         # define MGC_TIMEOUT_MIN_SECONDS   5
1285         # define MGC_TIMEOUT_RAND_CENTISEC 0x1ff /* ~500 *
1286         local count=30  # 20 seconds at most
1287         while [ $count -gt 0 ]; do
1288                 nidtbl_versions_match && break
1289                 sleep 1
1290                 count=$((count-1))
1291         done
1292
1293         nidtbl_versions_match || error "nidtbl mismatch"
1294
1295         # get the version #
1296         old_version=$(nidtbl_version_client client)
1297
1298         zconf_umount_clients $clients $MOUNT || error "Cannot umount client"
1299
1300         # restart mgs
1301         combined_mgs_mds && mgsdev=mds1
1302         remount_facet $mgsdev
1303         fail ost1
1304
1305         zconf_mount_clients $clients $MOUNT || error "Cannot mount client"
1306
1307         # check new version
1308         new_version=$(nidtbl_version_client client)
1309         [ $new_version -lt $old_version ] &&
1310                 error "nidtbl version wrong after mgs restarts"
1311         return 0
1312 }
1313 run_test 102 "IR: New client gets updated nidtbl after MGS restart"
1314
1315 test_103()
1316 {
1317         do_facet mgs $LCTL list_param mgs.*.ir_timeout ||
1318                 { skip "MGS without IR support"; return 0; }
1319
1320         combined_mgs_mds && skip "mgs and mds on the same target" && return 0
1321
1322         # workaround solution to generate config log on the mds
1323         remount_facet mds1
1324
1325         stop mgs
1326         stop mds1
1327
1328         # We need this test because mds is like a client in IR context.
1329         start mds1 $MDSDEV1 || error "MDS should start w/o mgs"
1330
1331         # start mgs and remount mds w/ ir
1332         start mgs $MGSDEV
1333         clients_up
1334
1335         # remount client so that fsdb will be created on the MGS
1336         umount_client $MOUNT || error "umount failed"
1337         mount_client $MOUNT || error "mount failed"
1338
1339         # sleep 30 seconds so the MDS has a chance to detect MGS restarting
1340         local count=30
1341         while [ $count -gt 0 ]; do
1342                 [ $(nidtbl_version_client mds1) -ne 0 ] && break
1343                 sleep 1
1344                 count=$((count-1))
1345         done
1346
1347         # after a while, mds should be able to reconnect to mgs and fetch
1348         # up-to-date nidtbl version
1349         nidtbl_versions_match mds1 || error "mds nidtbl mismatch"
1350
1351         # reset everything
1352         set_ir_status full
1353 }
1354 run_test 103 "IR: MDS can start w/o MGS and get updated nidtbl later"
1355
1356 test_104()
1357 {
1358         do_facet mgs $LCTL list_param mgs.*.ir_timeout ||
1359                 { skip "MGS without IR support"; return 0; }
1360
1361         set_ir_status full
1362
1363         stop ost1
1364         start ost1 $(ostdevname 1) "$OST_MOUNT_OPTS -onoir" ||
1365                 error "OST1 cannot start"
1366         clients_up
1367
1368         local ir_state=$(check_target_ir_state ost1)
1369         [ $ir_state = "OFF" ] || error "ir status on ost1 should be OFF"
1370 }
1371 run_test 104 "IR: ost can disable IR voluntarily"
1372
1373 test_105()
1374 {
1375         [ -z "$RCLIENTS" ] && skip "Needs multiple clients" && return 0
1376         do_facet mgs $LCTL list_param mgs.*.ir_timeout ||
1377                 { skip "MGS without IR support"; return 0; }
1378
1379         set_ir_status full
1380
1381         # get one of the clients from client list
1382         local rcli=$(echo $RCLIENTS |cut -d' ' -f 1)
1383
1384         local old_MOUNTOPT=$MOUNTOPT
1385         MOUNTOPT=${MOUNTOPT},noir
1386         zconf_umount $rcli $MOUNT || error "umount failed"
1387         zconf_mount $rcli $MOUNT || error "mount failed"
1388
1389         # make sure lustre mount at $rcli disabling IR
1390         local ir_state=$(check_cli_ir_state $rcli)
1391         [ $ir_state = OFF ] || error "IR state must be OFF at $rcli"
1392
1393         # Since the client just mounted, its last_rcvd entry is not on disk.
1394         # Send an RPC so exp_need_sync forces last_rcvd to commit this export
1395         # so the client can reconnect during OST recovery (LU-924, LU-1582)
1396         $SETSTRIPE -i 0 $DIR/$tfile
1397         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=sync
1398
1399         # make sure MGS's state is Partial
1400         [ $(get_ir_status) = "partial" ] || error "MGS IR state must be partial"
1401
1402         fail ost1
1403         # make sure IR on ost1 is OFF
1404         local ir_state=$(check_target_ir_state ost1)
1405         [ $ir_state = "OFF" ] || error "IR status on ost1 should be OFF"
1406
1407         # restore it
1408         MOUNTOPT=$old_MOUNTOPT
1409         zconf_umount $rcli $MOUNT || error "umount failed"
1410         zconf_mount $rcli $MOUNT || error "mount failed"
1411
1412         # make sure MGS's state is full
1413         [ $(get_ir_status) = "full" ] || error "MGS IR status must be full"
1414
1415         fail ost1
1416         # make sure IR on ost1 is ON
1417         local ir_state=$(check_target_ir_state ost1)
1418         [ $ir_state = "ON" ] || error "IR status on ost1 should be OFF"
1419
1420         return 0
1421 }
1422 run_test 105 "IR: NON IR clients support"
1423
1424 complete $(basename $0) $SECONDS
1425 check_and_cleanup_lustre
1426 exit_status