Whamcloud - gitweb
4db0e258b7736478a392aa1b94554d672eedb940
[fs/lustre-release.git] / lustre / tests / sanity-scrub.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
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10 ALWAYS_EXCEPT="$SANITY_SCRUB_EXCEPT"
11 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
12 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
13
14 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
15 . $LUSTRE/tests/test-framework.sh
16 init_test_env $@
17 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
18 init_logging
19
20 require_dsh_mds || exit 0
21
22 SAVED_MDSSIZE=${MDSSIZE}
23 SAVED_OSTSIZE=${OSTSIZE}
24 # use small MDS + OST size to speed formatting time
25 # do not use too small MDSSIZE/OSTSIZE, which affect the default journal size
26 MDSSIZE=100000
27 OSTSIZE=100000
28
29 MOUNT_2=""
30 check_and_setup_lustre
31
32 [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
33         skip "test OI scrub only for ldiskfs" && check_and_cleanup_lustre &&
34         exit 0
35 [ $(facet_fstype ost1) != "ldiskfs" ] &&
36         skip "test OI scrub only for ldiskfs" && check_and_cleanup_lustre &&
37         exit 0
38 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.2.90) ]] &&
39         skip "Need MDS version at least 2.2.90" && check_and_cleanup_lustre &&
40         exit 0
41
42 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.90) ]] &&
43         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 1a"
44
45 [[ $(lustre_version_code ost1) -lt $(version_code 2.4.50) ]] &&
46         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 11 12 13 14"
47
48 build_test_filter
49
50 MDT_DEV="${FSNAME}-MDT0000"
51 OST_DEV="${FSNAME}-OST0000"
52 MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
53
54 scrub_start() {
55         local error_id=$1
56         local n
57
58         for n in $(seq $MDSCOUNT); do
59                 do_facet mds$n $LCTL lfsck_start -M $(facet_svc mds$n) "$@" ||
60                         error "($error_id) Failed to start OI scrub on mds$n"
61         done
62 }
63
64 scrub_stop() {
65         local error_id=$1
66         local n
67
68         for n in $(seq $MDSCOUNT); do
69                 do_facet mds$n $LCTL lfsck_stop -M $(facet_svc mds$n) ||
70                         error "($error_id) Failed to stop OI scrub on mds$n"
71         done
72 }
73
74 scrub_status() {
75         local n=$1
76
77         do_facet mds$n $LCTL get_param -n \
78                 osd-ldiskfs.$(facet_svc mds$n).oi_scrub
79 }
80
81 START_SCRUB="do_facet $SINGLEMDS $LCTL lfsck_start -M ${MDT_DEV}"
82 START_SCRUB_ON_OST="do_facet ost1 $LCTL lfsck_start -M ${OST_DEV}"
83 STOP_SCRUB="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
84 SHOW_SCRUB="do_facet $SINGLEMDS \
85                 $LCTL get_param -n osd-ldiskfs.${MDT_DEV}.oi_scrub"
86 SHOW_SCRUB_ON_OST="do_facet ost1 \
87                 $LCTL get_param -n osd-ldiskfs.${OST_DEV}.oi_scrub"
88 MOUNT_OPTS_SCRUB="-o user_xattr"
89 MOUNT_OPTS_NOSCRUB="-o user_xattr,noscrub"
90
91 scrub_prep() {
92         local nfiles=$1
93         local n
94
95         echo "formatall"
96         formatall > /dev/null
97         echo "setupall"
98         setupall > /dev/null
99
100         echo "preparing..."
101         for n in $(seq $MDSCOUNT); do
102                 echo "creating $nfiles files on mds$n"
103                 if [ $n -eq 1 ]; then
104                         mkdir -p $DIR/$tdir/mds$n ||
105                                 error "Failed to create directory mds$n"
106                 else
107                         $LFS mkdir -i $((n - 1)) $DIR/$tdir/mds$n ||
108                                 error "Failed to create remote directory mds$n"
109                 fi
110                 cp $LUSTRE/tests/*.sh $DIR/$tdir/mds$n ||
111                         error "Failed to copy files to mds$n"
112                 if [[ $nfiles -gt 0 ]]; then
113                         createmany -o $DIR/$tdir/mds$n/$tfile $nfiles ||
114                                 error "createmany failed on mds$n"
115                 fi
116         done
117         echo "prepared."
118         cleanup_mount $MOUNT > /dev/null || error "Fail to stop client!"
119         for n in $(seq $MDSCOUNT); do
120                 echo "stop mds$n"
121                 stop mds$n > /dev/null || error "Fail to stop MDS$n!"
122         done
123 }
124
125 scrub_start_mds() {
126         local error_id=$1
127         local opts=$2
128         local n
129
130         for n in $(seq $MDSCOUNT); do
131                 start mds$n $(mdsdevname $n) $opts >/dev/null ||
132                         error "($error_id) Failed to start mds$n"
133         done
134 }
135
136 scrub_stop_mds() {
137         local error_id=$1
138         local n
139
140         for n in $(seq $MDSCOUNT); do
141                 echo "stopping mds$n"
142                 stop mds$n >/dev/null ||
143                         error "($error_id) Failed to stop mds$n"
144         done
145 }
146
147 scrub_check_status() {
148         local error_id=$1
149         local expected=$2
150         local actual
151         local n
152
153         for n in $(seq $MDSCOUNT); do
154                 actual=$(do_facet mds$n $LCTL get_param -n \
155                         osd-ldiskfs.$(facet_svc mds$n).oi_scrub |
156                         awk '/^status/ { print $2 }')
157                 if [ "$actual" != "$expected" ]; then
158                         error "($error_id) Expected '$expected' on mds$n, but" \
159                                "got '$actual'"
160                 fi
161         done
162 }
163
164 scrub_check_flags() {
165         local error_id=$1
166         local expected=$2
167         local actual
168         local n
169
170         for n in $(seq $MDSCOUNT); do
171                 actual=$(do_facet mds$n $LCTL get_param -n \
172                         osd-ldiskfs.$(facet_svc mds$n).oi_scrub |
173                         awk '/^flags/ { print $2 }')
174                 if [ "$actual" != "$expected" ]; then
175                         error "($error_id) Expected '$expected' on mds$n, but" \
176                                "got '$actual'"
177                 fi
178         done
179 }
180
181 scrub_check_data() {
182         local error_id=$1
183         local n
184
185         for n in $(seq $MDSCOUNT); do
186                 diff -q $LUSTRE/tests/test-framework.sh \
187                         $DIR/$tdir/mds$n/test-framework.sh ||
188                         error "($error_id) File data check failed"
189         done
190 }
191
192 scrub_remove_ois() {
193         local error_id=$1
194         local index=$2
195         local n
196
197         for n in $(seq $MDSCOUNT); do
198                 mds_remove_ois mds$n $index ||
199                         error "($error_id) Failed to remove OI .$index on mds$n"
200         done
201 }
202
203 scrub_backup_restore() {
204         local error_id=$1
205         local igif=$2
206         local n
207
208         for n in $(seq $MDSCOUNT); do
209                 mds_backup_restore mds$n $igif ||
210                         error "(error_id) Backup/restore on mds$n failed"
211         done
212 }
213
214 scrub_enable_auto() {
215         local n
216
217         for n in $(seq $MDSCOUNT); do
218                 do_facet mds$n $LCTL set_param -n \
219                         osd-ldiskfs.$(facet_svc mds$n).auto_scrub 1
220         done
221 }
222
223 test_0() {
224         scrub_prep 0
225         echo "starting MDTs without disabling OI scrub"
226         scrub_start_mds 1 "$MOUNT_OPTS_SCRUB"
227         scrub_check_status 2 init
228         scrub_check_flags 3 ""
229         mount_client $MOUNT || error "(4) Fail to start client!"
230         scrub_check_data 5
231 }
232 run_test 0 "Do not auto trigger OI scrub for non-backup/restore case"
233
234 test_1a() {
235         scrub_prep 0
236         echo "start $SINGLEMDS without disabling OI scrub"
237         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
238                 error "(1) Fail to start MDS!"
239
240         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
241         [ "$STATUS" == "init" ] ||
242                 error "(2) Expect 'init', but got '$STATUS'"
243
244         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
245         [ -z "$FLAGS" ] || error "(3) Expect empty flags, but got '$FLAGS'"
246
247         mount_client $MOUNT || error "(4) Fail to start client!"
248
249         #define OBD_FAIL_OSD_FID_MAPPING                        0x193
250         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x193
251         # update .lustre OI mapping
252         touch $MOUNT/.lustre
253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
254
255         umount_client $MOUNT || error "(5) Fail to stop client!"
256
257         echo "stop $SINGLEMDS"
258         stop $SINGLEMDS > /dev/null || error "(6) Fail to stop MDS!"
259
260         echo "start $SINGLEMDS with disabling OI scrub"
261         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
262                 error "(7) Fail to start MDS!"
263
264         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
265         [ "$STATUS" == "init" ] ||
266                 error "(8) Expect 'init', but got '$STATUS'"
267
268         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
269         [ "$FLAGS" == "inconsistent" ] ||
270                 error "(9) Expect 'inconsistent', but got '$FLAGS'"
271 }
272 run_test 1a "Auto trigger initial OI scrub when server mounts"
273
274 test_1b() {
275         scrub_prep 0
276         scrub_remove_ois 1
277         echo "start MDTs without disabling OI scrub"
278         scrub_start_mds 2 "$MOUNT_OPTS_SCRUB"
279         sleep 3
280         scrub_check_status 3 completed
281         mount_client $MOUNT || error "(4) Fail to start client!"
282         scrub_check_data 5
283 }
284 run_test 1b "Trigger OI scrub when MDT mounts for OI files remove/recreate case"
285
286 test_1c() {
287         local index
288
289         # OI files to be removed:
290         # idx 0: oi.16.0
291         # idx 1: oi.16.1
292         # idx 2: oi.16.{2,4,8,16,32}
293         # idx 3: oi.16.{3,9,27}
294         # idx 5: oi.16.{5,25}
295         # idx 7: oi.16.{7,49}
296         for index in 0 1 2 3 5 7; do
297                 scrub_prep 0
298                 scrub_remove_ois 1 $index
299
300                 echo "start MDTs with OI scrub disabled"
301                 scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
302                 scrub_check_flags 3 recreated
303                 scrub_start 4
304                 sleep 3
305                 scrub_check_status 5 completed
306                 scrub_check_flags 6 ""
307         done
308 }
309 run_test 1c "Auto detect kinds of OI file(s) removed/recreated cases"
310
311 test_2() {
312         scrub_prep 0
313         scrub_backup_restore 1
314         echo "starting MDTs without disabling OI scrub"
315         scrub_start_mds 2 "$MOUNT_OPTS_SCRUB"
316         sleep 3
317         scrub_check_status 3 completed
318         mount_client $MOUNT || error "(4) Fail to start client!"
319         scrub_check_data 5
320 }
321 run_test 2 "Trigger OI scrub when MDT mounts for backup/restore case"
322
323 test_3() {
324         scrub_prep 0
325         scrub_backup_restore 1
326         echo "starting MDTs with OI scrub disabled"
327         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
328         sleep 3
329         scrub_check_status 3 init
330         scrub_check_flags 4 inconsistent
331         echo "stopall"
332         stopall > /dev/null
333 }
334 run_test 3 "Do not trigger OI scrub when MDT mounts if 'noscrub' specified"
335
336 test_4() {
337         scrub_prep 0
338         scrub_backup_restore 1
339         echo "starting MDTs with OI scrub disabled"
340         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
341         scrub_check_status 3 init
342         scrub_check_flags 4 inconsistent
343         mount_client $MOUNT || error "(5) Fail to start client!"
344         scrub_enable_auto
345         scrub_check_data 6
346         sleep 3
347         scrub_check_status 7 completed
348 }
349 run_test 4 "Trigger OI scrub automatically if inconsistent OI mapping was found"
350
351 test_5() {
352         scrub_prep 1500
353         scrub_backup_restore 1
354         echo "starting MDTs with OI scrub disabled"
355         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
356         scrub_check_status 3 init
357         scrub_check_flags 4 inconsistent
358         mount_client $MOUNT || error "(5) Fail to start client!"
359         scrub_enable_auto
360
361         local n
362         for n in $(seq $MDSCOUNT); do
363                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
364                 do_facet mds$n $LCTL set_param fail_val=3
365                 do_facet mds$n $LCTL set_param fail_loc=0x190
366         done
367         scrub_check_data 6
368
369         umount_client $MOUNT || error "(7) Fail to stop client!"
370
371         scrub_check_status 8 scanning
372
373         for n in $(seq $MDSCOUNT); do
374                 #define OBD_FAIL_OSD_SCRUB_CRASH         0x191
375                 do_facet mds$n $LCTL set_param fail_loc=0x191
376         done
377         sleep 4
378         scrub_stop_mds 9
379
380         for n in $(seq $MDSCOUNT); do
381                 do_facet mds$n $LCTL set_param fail_loc=0
382                 do_facet mds$n $LCTL set_param fail_val=0
383         done
384
385         echo "starting MDTs with OI scrub disabled"
386         scrub_start_mds 10 "$MOUNT_OPTS_NOSCRUB"
387
388         scrub_check_status 11 crashed
389
390         scrub_stop_mds 12
391
392         for n in $(seq $MDSCOUNT); do
393                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
394                 do_facet mds$n $LCTL set_param fail_val=3
395                 do_facet mds$n $LCTL set_param fail_loc=0x190
396         done
397         echo "starting MDTs without disabling OI scrub"
398         scrub_start_mds 13 "$MOUNT_OPTS_SCRUB"
399
400         scrub_check_status 14 scanning
401
402         for n in $(seq $MDSCOUNT); do
403                 #define OBD_FAIL_OSD_SCRUB_FATAL         0x192
404                 do_facet mds$n $LCTL set_param fail_loc=0x192
405         done
406         sleep 4
407         scrub_check_status 15 failed
408
409         mount_client $MOUNT || error "(16) Fail to start client!"
410
411         for n in $(seq $MDSCOUNT); do
412                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
413                 do_facet mds$n $LCTL set_param fail_val=3
414                 do_facet mds$n $LCTL set_param fail_loc=0x190
415                 stat $DIR/$tdir/mds$n/${tfile}1000 ||
416                         error "(17) Failed to stat mds$n/${tfile}1000"
417         done
418
419         scrub_check_status 18 scanning
420
421         for n in $(seq $MDSCOUNT); do
422                 do_facet mds$n $LCTL set_param fail_loc=0
423                 do_facet mds$n $LCTL set_param fail_val=0
424         done
425         sleep 5
426         scrub_check_status 19 completed
427
428         scrub_check_flags 20 ""
429 }
430 run_test 5 "OI scrub state machine"
431
432 test_6() {
433         scrub_prep 1000
434         scrub_backup_restore 1
435         echo "starting MDTs with OI scrub disabled"
436         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
437         scrub_check_status 3 init
438         scrub_check_flags 4 inconsistent
439         mount_client $MOUNT || error "(5) Fail to start client!"
440         scrub_enable_auto
441         local n
442         for n in $(seq $MDSCOUNT); do
443                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
444                 do_facet mds$n $LCTL set_param fail_val=3
445                 do_facet mds$n $LCTL set_param fail_loc=0x190
446         done
447         scrub_check_data 6
448
449         # Sleep 5 sec to guarantee at least one object processed by OI scrub
450         sleep 5
451         # Fail the OI scrub to guarantee there is at least one checkpoint
452         for n in $(seq $MDSCOUNT); do
453                 #define OBD_FAIL_OSD_SCRUB_FATAL         0x192
454                 do_facet mds$n $LCTL set_param fail_loc=0x192
455         done
456         sleep 4
457         scrub_check_status 7 failed
458
459         for n in $(seq $MDSCOUNT); do
460                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
461                 do_facet mds$n $LCTL set_param fail_val=3
462                 do_facet mds$n $LCTL set_param fail_loc=0x190
463                 # stat will re-trigger OI scrub
464                 stat $DIR/$tdir/mds$n/${tfile}800 ||
465                         error "(8) Failed to stat mds$n/${tfile}800"
466         done
467
468         umount_client $MOUNT || error "(9) Fail to stop client!"
469
470         scrub_check_status 10 scanning
471
472         for n in $(seq $MDSCOUNT); do
473                 #define OBD_FAIL_OSD_SCRUB_CRASH         0x191
474                 do_facet mds$n $LCTL set_param fail_loc=0x191
475         done
476         sleep 4
477         local -a position0
478         for n in $(seq $MDSCOUNT); do
479                 position0[$n]=$(scrub_status $n |
480                         awk '/^last_checkpoint_position/ {print $2}')
481                 position0[$n]=$((${position0[$n]} + 1))
482         done
483
484         scrub_stop_mds 11
485
486         for n in $(seq $MDSCOUNT); do
487                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
488                 do_facet mds$n $LCTL set_param fail_val=3
489                 do_facet mds$n $LCTL set_param fail_loc=0x190
490         done
491         echo "starting MDTs without disabling OI scrub"
492         scrub_start_mds 12 "$MOUNT_OPTS_SCRUB"
493
494         scrub_check_status 13 scanning
495
496         local -a position1
497         for n in $(seq $MDSCOUNT); do
498                 positions1[$n]=$(scrub_status $n |
499                         awk '/^latest_start_position/ {print $2}')
500                 if [ ${position0[$n]} -ne ${position1[$n]} ]; then
501                         error "(14) Expected position ${position0[$n]}, but" \
502                                 "got ${position1[$n]}"
503                 fi
504         done
505
506         for n in $(seq $MDSCOUNT); do
507                 do_facet mds$n $LCTL set_param fail_loc=0
508                 do_facet mds$n $LCTL set_param fail_val=0
509         done
510         sleep 5
511         scrub_check_status 15 completed
512
513         scrub_check_flags 16 ""
514 }
515 run_test 6 "OI scrub resumes from last checkpoint"
516
517 test_7() {
518         scrub_prep 500
519         scrub_backup_restore 1
520
521         echo "starting MDTs with OI scrub disabled"
522         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
523         scrub_check_status 3 init
524         scrub_check_flags 4 inconsistent
525
526         mount_client $MOUNT || error "(5) Fail to start client!"
527
528         scrub_enable_auto
529         local n
530         for n in $(seq $MDSCOUNT); do
531                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
532                 do_facet mds$n $LCTL set_param fail_val=3
533                 do_facet mds$n $LCTL set_param fail_loc=0x190
534         done
535         scrub_check_data 6
536
537         for n in $(seq $MDSCOUNT); do
538                 stat $DIR/$tdir/mds$n/${tfile}300 ||
539                         error "(7) Failed to stat mds$n/${tfile}300!"
540         done
541
542         scrub_check_status 8 scanning
543
544         scrub_check_flags 9 inconsistent,auto
545
546         for n in $(seq $MDSCOUNT); do
547                 do_facet mds$n $LCTL set_param fail_loc=0
548                 do_facet mds$n $LCTL set_param fail_val=0
549         done
550         sleep 5
551         scrub_check_status 10 completed
552
553         scrub_check_flags ""
554 }
555 run_test 7 "System is available during OI scrub scanning"
556
557 test_8() {
558         scrub_prep 128
559         scrub_backup_restore 1
560
561         echo "starting MDTs with OI scrub disabled"
562         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
563
564         scrub_check_status 3 init
565
566         scrub_check_flags 4 inconsistent
567
568         local n
569         for n in $(seq $MDSCOUNT); do
570                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
571                 do_facet mds$n $LCTL set_param fail_val=1
572                 do_facet mds$n $LCTL set_param fail_loc=0x190
573         done
574         scrub_start 5
575
576         scrub_check_status 6 scanning
577
578         scrub_stop 7
579
580         scrub_check_status 8 stopped
581
582         scrub_start 9
583
584         scrub_check_status 10 scanning
585
586         for n in $(seq $MDSCOUNT); do
587                 do_facet mds$n $LCTL set_param fail_loc=0
588                 do_facet mds$n $LCTL set_param fail_val=0
589         done
590         sleep 5
591         scrub_check_status 11 completed
592
593         scrub_check_flags 12 ""
594 }
595 run_test 8 "Control OI scrub manually"
596
597 test_9() {
598         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
599                 skip "Testing on UP system, the speed may be inaccurate."
600                 return 0
601         fi
602
603         scrub_prep 8000
604         scrub_backup_restore 1
605
606         echo "starting MDTs with OI scrub disabled"
607         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
608
609         scrub_check_status 3 init
610
611         scrub_check_flags 4 inconsistent
612
613         local BASE_SPEED1=100
614         local RUN_TIME1=10
615         # OI scrub should run with full speed under inconsistent case
616         scrub_start 5 -s $BASE_SPEED1
617
618         sleep $RUN_TIME1
619         scrub_check_status 6 completed
620
621         scrub_check_flags 7 ""
622
623         # OI scrub should run with limited speed under non-inconsistent case
624         scrub_start 8 -s $BASE_SPEED1 -r
625
626         sleep $RUN_TIME1
627         scrub_check_status 9 scanning
628
629         # Do NOT ignore that there are 1024 pre-fetched items. And there
630         # may be time error, normally it should be less than 2 seconds.
631         # We allow another 20% schedule error.
632         local PRE_FETCHED=1024
633         local TIME_DIFF=2
634         # MAX_MARGIN = 1.2 = 12 / 10
635         local MAX_SPEED=$(((PRE_FETCHED + BASE_SPEED1 * \
636                 (RUN_TIME1 + TIME_DIFF)) / RUN_TIME1 * 12 / 10))
637         local n
638         for n in $(seq $MDSCOUNT); do
639                 local SPEED=$(scrub_status $n | \
640                         awk '/^average_speed/ { print $2 }')
641                 [ $SPEED -lt $MAX_SPEED ] ||
642                         error "(10) Got speed $SPEED, expected less than" \
643                                 "$MAX_SPEED"
644         done
645
646         # adjust speed limit
647         local BASE_SPEED2=300
648         local RUN_TIME2=10
649         for n in $(seq $MDSCOUNT); do
650                 do_facet mds$n $LCTL set_param -n \
651                         mdd.$(facet_svc mds$n).lfsck_speed_limit $BASE_SPEED2
652         done
653         sleep $RUN_TIME2
654
655         # MIN_MARGIN = 0.8 = 8 / 10
656         local MIN_SPEED=$(((PRE_FETCHED + \
657                             BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
658                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
659                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
660         # MAX_MARGIN = 1.2 = 12 / 10
661         MAX_SPEED=$(((PRE_FETCHED + \
662                       BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
663                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
664                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
665         for n in $(seq $MDSCOUNT); do
666                 SPEED=$(scrub_status $n | awk '/^average_speed/ { print $2 }')
667                 [ $SPEED -gt $MIN_SPEED ] ||
668                         error "(11) Got speed $SPEED, expected more than" \
669                                 "$MIN_SPEED"
670                 [ $SPEED -lt $MAX_SPEED ] ||
671                         error "(12) Got speed $SPEED, expected less than" \
672                                 "$MAX_SPEED"
673
674                 do_facet mds$n $LCTL set_param -n \
675                                 mdd.$(facet_svc mds$n).lfsck_speed_limit 0
676         done
677         sleep 6
678         scrub_check_status 13 completed
679 }
680 run_test 9 "OI scrub speed control"
681
682 test_10a() {
683         scrub_prep 0
684         scrub_backup_restore 1
685
686         echo "starting mds$n with OI scrub disabled"
687         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
688
689         scrub_check_status 3 init
690
691         scrub_check_flags 4 inconsistent
692
693         mount_client $MOUNT || error "(5) Fail to start client!"
694
695         scrub_enable_auto
696         local n
697         for n in $(seq $MDSCOUNT); do
698                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
699                 do_facet mds$n $LCTL set_param fail_val=1
700                 do_facet mds$n $LCTL set_param fail_loc=0x190
701         done
702         scrub_check_data 6
703
704         scrub_check_status 7 scanning
705
706         umount_client $MOUNT || error "(8) Fail to stop client!"
707
708         scrub_stop_mds 9
709
710         echo "starting MDTs with OI scrub disabled"
711         scrub_start_mds 10 "$MOUNT_OPTS_NOSCRUB"
712
713         scrub_check_status 11 paused
714
715         scrub_stop_mds 12
716
717         echo "starting MDTs without disabling OI scrub"
718         scrub_start_mds 13 "$MOUNT_OPTS_SCRUB"
719
720         scrub_check_status 14 scanning
721
722         for n in $(seq $MDSCOUNT); do
723                 do_facet mds$n $LCTL set_param fail_loc=0
724                 do_facet mds$n $LCTL set_param fail_val=0
725         done
726         sleep 5
727         scrub_check_status 15 completed
728
729         scrub_check_flags 16 ""
730 }
731 run_test 10a "non-stopped OI scrub should auto restarts after MDS remount (1)"
732
733 # test_10b is obsolete, it will be coverded by related sanity-lfsck tests.
734 test_10b() {
735         scrub_prep 0
736         scrub_backup_restore 1
737
738         echo "starting MDTs with OI scrub disabled"
739         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
740
741         scrub_check_status 3 init
742
743         scrub_check_flags 4 inconsistent
744
745         local n
746         for n in $(seq $MDSCOUNT); do
747                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
748                 do_facet mds$n $LCTL set_param fail_val=3
749                 do_facet mds$n $LCTL set_param fail_loc=0x190
750         done
751
752         scrub_start 5
753
754         scrub_check_status 6 scanning
755
756         scrub_stop_mds 7
757
758         echo "starting MDTs with OI scrub disabled"
759         scrub_start_mds 8 "$MOUNT_OPTS_NOSCRUB"
760
761         scrub_check_status 9 paused
762
763         scrub_stop_mds 10
764
765         echo "starting MDTs without disabling OI scrub"
766         scrub_start_mds 11 "$MOUNT_OPTS_SCRUB"
767
768         scrub_check_status 12 scanning
769
770         for n in $(seq $MDSCOUNT); do
771                 do_facet mds$n $LCTL set_param fail_loc=0
772                 do_facet mds$n $LCTL set_param fail_val=0
773         done
774         sleep 5
775         scrub_check_status 13 completed
776
777         scrub_check_flags 14 ""
778 }
779 #run_test 10b "non-stopped OI scrub should auto restarts after MDS remount (2)"
780
781 test_11() {
782         echo "stopall"
783         stopall > /dev/null
784         echo "formatall"
785         formatall > /dev/null
786         echo "setupall"
787         setupall > /dev/null
788
789         local CREATED=100
790         local tname=`date +%s`
791         rm -rf $MOUNT/$tname > /dev/null
792         mkdir -p $MOUNT/$tname || error "(0) Failed to create $MOUNT/$tname"
793         local n
794         for n in $(seq $MDSCOUNT); do
795                 $LFS mkdir -i $((n - 1)) $MOUNT/$tname/mds$n ||
796                         error "(1) Fail to mkdir $MOUNT/$tname/mds$n"
797
798                 createmany -o $MOUNT/$tname/mds$n/f $CREATED ||
799                         error "(2) Fail to create in $tname/mds$n"
800         done
801
802         cleanup_mount $MOUNT
803         do_facet $SINGLEMDS $LCTL clear
804         start_full_debug_logging
805         # reset OI scrub start point by force
806         scrub_start 3 -r
807         sleep 3
808         scrub_check_status 4 completed
809
810         # OI scrub should skip the new created objects for the first accessing
811         # notice we're creating a new llog for every OST on every startup
812         # new features can make this even less stable, so we only check
813         # that the number of skipped files is less than 2x the number of files
814         local MAXIMUM=$((CREATED * 2))
815         local MINIMUM=$((CREATED + 1)) # files + directory
816         for n in $(seq $MDSCOUNT); do
817                 local SKIPPED=$(scrub_status $n | awk '/^noscrub/ { print $2 }')
818                 [ $SKIPPED -ge $MAXIMUM -o $SKIPPED -lt $MINIMUM ] &&
819                         error "(5) Expect [ $MINIMUM , $MAXIMUM ) objects" \
820                                 "skipped on mds$n, but got $SKIPPED"
821         done
822
823         # reset OI scrub start point by force
824         scrub_start -r
825         sleep 3
826         scrub_check_status 7 completed
827
828         # OI scrub should skip the new created object only once
829         for n in $(seq $MDSCOUNT); do
830                 SKIPPED=$(scrub_status $n | awk '/^noscrub/ { print $2 }')
831                 [ $SKIPPED -eq 0 ] ||
832                         error "(8) Expect 0 objects skipped on mds$n, but" \
833                                 "got $SKIPPED"
834         done
835
836         stop_full_debug_logging
837         restore_mount $MOUNT || error "(9) Fail to start client!"
838         rm -rf $MOUNT/$tname > /dev/null
839 }
840 run_test 11 "OI scrub skips the new created objects only once"
841
842 test_12() {
843         echo "stopall"
844         stopall > /dev/null
845         echo "formatall"
846         formatall > /dev/null
847         echo "setupall"
848         setupall > /dev/null
849
850         mkdir -p $DIR/$tdir
851         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
852
853         #define OBD_FAIL_OSD_COMPAT_INVALID_ENTRY               0x195
854         do_facet ost1 $LCTL set_param fail_loc=0x195
855         createmany -o $DIR/$tdir/f 1000
856
857         echo "stopall"
858         stopall > /dev/null
859         echo "setupall"
860         setupall > /dev/null
861
862         do_facet ost1 $LCTL set_param fail_loc=0
863         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
864         [ "$STATUS" == "init" ] ||
865                 error "(1) Expect 'init', but got '$STATUS'"
866
867         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
868
869         sleep 3
870         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
871         [ "$STATUS" == "completed" ] ||
872                 error "(3) Expect 'completed', but got '$STATUS'"
873
874         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(4) ls should succeed"
875 }
876 run_test 12 "OI scrub can rebuild invalid /O entries"
877
878 test_13() {
879         echo "stopall"
880         stopall > /dev/null
881         echo "formatall"
882         formatall > /dev/null
883         echo "setupall"
884         setupall > /dev/null
885
886         mkdir -p $DIR/$tdir
887         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
888
889         #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
890         do_facet ost1 $LCTL set_param fail_loc=0x196
891         createmany -o $DIR/$tdir/f 1000
892         do_facet ost1 $LCTL set_param fail_loc=0
893
894         echo "stopall"
895         stopall > /dev/null
896         echo "setupall"
897         setupall > /dev/null
898
899         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
900         [ "$STATUS" == "init" ] ||
901                 error "(1) Expect 'init', but got '$STATUS'"
902
903         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
904
905         $START_SCRUB_ON_OST || error "(3) Fail to start OI scrub on OST!"
906         sleep 3
907         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
908         [ "$STATUS" == "completed" ] ||
909                 error "(4) Expect 'completed', but got '$STATUS'"
910
911         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(5) ls should succeed"
912 }
913 run_test 13 "OI scrub can rebuild missed /O entries"
914
915 test_14() {
916         echo "stopall"
917         stopall > /dev/null
918         echo "formatall"
919         formatall > /dev/null
920         echo "setupall"
921         setupall > /dev/null
922
923         mkdir -p $DIR/$tdir
924         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
925
926         #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
927         do_facet ost1 $LCTL set_param fail_loc=0x196
928         createmany -o $DIR/$tdir/f 64
929         do_facet ost1 $LCTL set_param fail_loc=0
930
931         echo "stopall"
932         stopall > /dev/null
933         echo "setupall"
934         setupall > /dev/null
935
936         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
937         [ "$STATUS" == "init" ] ||
938                 error "(1) Expect 'init', but got '$STATUS'"
939
940         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
941
942         echo "stopall"
943         stopall > /dev/null
944
945         echo "run e2fsck"
946         run_e2fsck $(facet_host ost1) $(ostdevname 1) "-y" ||
947                 error "(3) Fail to run e2fsck error"
948
949         echo "setupall"
950         setupall > /dev/null
951
952         local LF_REPAIRED=$($SHOW_SCRUB_ON_OST |
953                             awk '/^lf_reparied/ { print $2 }')
954         [ $LF_REPAIRED -gt 0 ] ||
955                 error "(4) Some entry under /lost+found should be repaired"
956
957         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(5) ls should succeed"
958 }
959 run_test 14 "OI scrub can repair objects under lost+found"
960
961 # restore MDS/OST size
962 MDSSIZE=${SAVED_MDSSIZE}
963 OSTSIZE=${SAVED_OSTSIZE}
964
965 # cleanup the system at last
966 formatall
967
968 complete $SECONDS
969 exit_status