Whamcloud - gitweb
LU-20 kernel: remove obsolete kernel patches
[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_params() {
182         local error_id=$1
183         local expected=$2
184         local actual
185         local n
186
187         for n in $(seq $MDSCOUNT); do
188                 actual=$(do_facet mds$n $LCTL get_param -n \
189                         osd-ldiskfs.$(facet_svc mds$n).oi_scrub |
190                         awk '/^param/ { print $2 }')
191                 if [ "$actual" != "$expected" ]; then
192                         error "($error_id) Expected '$expected' on mds$n, but" \
193                                "got '$actual'"
194                 fi
195         done
196 }
197
198 scrub_check_repaired() {
199         local error_id=$1
200         local expected=$2
201         local actual
202         local n
203
204         for n in $(seq $MDSCOUNT); do
205                 actual=$(do_facet mds$n $LCTL get_param -n \
206                         osd-ldiskfs.$(facet_svc mds$n).oi_scrub |
207                         awk '/^updated/ { print $2 }')
208
209                 if [ $expected -eq 0 -a $actual -ne 0 ]; then
210                         error "($error_id) Expected no repaired on mds$n, but" \
211                                "got '$actual'"
212                 fi
213
214                 if [ $expected -ne 0 -a $actual -lt $expected ]; then
215                         error "($error_id) Expected '$expected' on mds$n, but" \
216                                "got '$actual'"
217                 fi
218         done
219 }
220
221 scrub_check_data() {
222         local error_id=$1
223         local n
224
225         for n in $(seq $MDSCOUNT); do
226                 diff -q $LUSTRE/tests/test-framework.sh \
227                         $DIR/$tdir/mds$n/test-framework.sh ||
228                         error "($error_id) File data check failed"
229         done
230 }
231
232 scrub_remove_ois() {
233         local error_id=$1
234         local index=$2
235         local n
236
237         for n in $(seq $MDSCOUNT); do
238                 mds_remove_ois mds$n $index ||
239                         error "($error_id) Failed to remove OI .$index on mds$n"
240         done
241 }
242
243 scrub_backup_restore() {
244         local error_id=$1
245         local igif=$2
246         local n
247
248         for n in $(seq $MDSCOUNT); do
249                 mds_backup_restore mds$n $igif ||
250                         error "(error_id) Backup/restore on mds$n failed"
251         done
252 }
253
254 scrub_enable_auto() {
255         local n
256
257         for n in $(seq $MDSCOUNT); do
258                 do_facet mds$n $LCTL set_param -n \
259                         osd-ldiskfs.$(facet_svc mds$n).auto_scrub 1
260         done
261 }
262
263 test_0() {
264         scrub_prep 0
265         echo "starting MDTs without disabling OI scrub"
266         scrub_start_mds 1 "$MOUNT_OPTS_SCRUB"
267         scrub_check_status 2 init
268         scrub_check_flags 3 ""
269         mount_client $MOUNT || error "(4) Fail to start client!"
270         scrub_check_data 5
271 }
272 run_test 0 "Do not auto trigger OI scrub for non-backup/restore case"
273
274 test_1a() {
275         scrub_prep 0
276         echo "start $SINGLEMDS without disabling OI scrub"
277         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
278                 error "(1) Fail to start MDS!"
279
280         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
281         [ "$STATUS" == "init" ] ||
282                 error "(2) Expect 'init', but got '$STATUS'"
283
284         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
285         [ -z "$FLAGS" ] || error "(3) Expect empty flags, but got '$FLAGS'"
286
287         mount_client $MOUNT || error "(4) Fail to start client!"
288
289         #define OBD_FAIL_OSD_FID_MAPPING                        0x193
290         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x193
291         # update .lustre OI mapping
292         touch $MOUNT/.lustre
293         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
294
295         umount_client $MOUNT || error "(5) Fail to stop client!"
296
297         echo "stop $SINGLEMDS"
298         stop $SINGLEMDS > /dev/null || error "(6) Fail to stop MDS!"
299
300         echo "start $SINGLEMDS with disabling OI scrub"
301         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
302                 error "(7) Fail to start MDS!"
303
304         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
305         [ "$STATUS" == "init" ] ||
306                 error "(8) Expect 'init', but got '$STATUS'"
307
308         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
309         [ "$FLAGS" == "inconsistent" ] ||
310                 error "(9) Expect 'inconsistent', but got '$FLAGS'"
311 }
312 run_test 1a "Auto trigger initial OI scrub when server mounts"
313
314 test_1b() {
315         scrub_prep 0
316         scrub_remove_ois 1
317         echo "start MDTs without disabling OI scrub"
318         scrub_start_mds 2 "$MOUNT_OPTS_SCRUB"
319         sleep 3
320         scrub_check_status 3 completed
321         mount_client $MOUNT || error "(4) Fail to start client!"
322         scrub_check_data 5
323 }
324 run_test 1b "Trigger OI scrub when MDT mounts for OI files remove/recreate case"
325
326 test_1c() {
327         local index
328
329         # OI files to be removed:
330         # idx 0: oi.16.0
331         # idx 1: oi.16.1
332         # idx 2: oi.16.{2,4,8,16,32}
333         # idx 3: oi.16.{3,9,27}
334         # idx 5: oi.16.{5,25}
335         # idx 7: oi.16.{7,49}
336         for index in 0 1 2 3 5 7; do
337                 scrub_prep 0
338                 scrub_remove_ois 1 $index
339
340                 echo "start MDTs with OI scrub disabled"
341                 scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
342                 scrub_check_flags 3 recreated
343                 scrub_start 4
344                 sleep 3
345                 scrub_check_status 5 completed
346                 scrub_check_flags 6 ""
347         done
348 }
349 run_test 1c "Auto detect kinds of OI file(s) removed/recreated cases"
350
351 test_2() {
352         scrub_prep 0
353         scrub_backup_restore 1
354         echo "starting MDTs without disabling OI scrub"
355         scrub_start_mds 2 "$MOUNT_OPTS_SCRUB"
356         sleep 3
357         scrub_check_status 3 completed
358         mount_client $MOUNT || error "(4) Fail to start client!"
359         scrub_check_data 5
360 }
361 run_test 2 "Trigger OI scrub when MDT mounts for backup/restore case"
362
363 test_3() {
364         scrub_prep 0
365         scrub_backup_restore 1
366         echo "starting MDTs with OI scrub disabled"
367         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
368         sleep 3
369         scrub_check_status 3 init
370         scrub_check_flags 4 inconsistent
371         echo "stopall"
372         stopall > /dev/null
373 }
374 run_test 3 "Do not trigger OI scrub when MDT mounts if 'noscrub' specified"
375
376 test_4() {
377         scrub_prep 0
378         scrub_backup_restore 1
379         echo "starting MDTs with OI scrub disabled"
380         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
381         scrub_check_status 3 init
382         scrub_check_flags 4 inconsistent
383         mount_client $MOUNT || error "(5) Fail to start client!"
384         scrub_enable_auto
385         scrub_check_data 6
386         sleep 3
387         scrub_check_status 7 completed
388 }
389 run_test 4 "Trigger OI scrub automatically if inconsistent OI mapping was found"
390
391 test_5() {
392         scrub_prep 1500
393         scrub_backup_restore 1
394         echo "starting MDTs with OI scrub disabled"
395         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
396         scrub_check_status 3 init
397         scrub_check_flags 4 inconsistent
398         mount_client $MOUNT || error "(5) Fail to start client!"
399         scrub_enable_auto
400
401         local n
402         for n in $(seq $MDSCOUNT); do
403                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
404                 do_facet mds$n $LCTL set_param fail_val=3
405                 do_facet mds$n $LCTL set_param fail_loc=0x190
406         done
407         scrub_check_data 6
408
409         umount_client $MOUNT || error "(7) Fail to stop client!"
410
411         scrub_check_status 8 scanning
412
413         for n in $(seq $MDSCOUNT); do
414                 #define OBD_FAIL_OSD_SCRUB_CRASH         0x191
415                 do_facet mds$n $LCTL set_param fail_loc=0x191
416         done
417         sleep 4
418         scrub_stop_mds 9
419
420         for n in $(seq $MDSCOUNT); do
421                 do_facet mds$n $LCTL set_param fail_loc=0
422                 do_facet mds$n $LCTL set_param fail_val=0
423         done
424
425         echo "starting MDTs with OI scrub disabled"
426         scrub_start_mds 10 "$MOUNT_OPTS_NOSCRUB"
427
428         scrub_check_status 11 crashed
429
430         scrub_stop_mds 12
431
432         for n in $(seq $MDSCOUNT); do
433                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
434                 do_facet mds$n $LCTL set_param fail_val=3
435                 do_facet mds$n $LCTL set_param fail_loc=0x190
436         done
437         echo "starting MDTs without disabling OI scrub"
438         scrub_start_mds 13 "$MOUNT_OPTS_SCRUB"
439
440         scrub_check_status 14 scanning
441
442         for n in $(seq $MDSCOUNT); do
443                 #define OBD_FAIL_OSD_SCRUB_FATAL         0x192
444                 do_facet mds$n $LCTL set_param fail_loc=0x192
445         done
446         sleep 4
447         scrub_check_status 15 failed
448
449         mount_client $MOUNT || error "(16) Fail to start client!"
450
451         for n in $(seq $MDSCOUNT); do
452                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
453                 do_facet mds$n $LCTL set_param fail_val=3
454                 do_facet mds$n $LCTL set_param fail_loc=0x190
455                 stat $DIR/$tdir/mds$n/${tfile}1000 ||
456                         error "(17) Failed to stat mds$n/${tfile}1000"
457         done
458
459         scrub_check_status 18 scanning
460
461         for n in $(seq $MDSCOUNT); do
462                 do_facet mds$n $LCTL set_param fail_loc=0
463                 do_facet mds$n $LCTL set_param fail_val=0
464         done
465         sleep 5
466         scrub_check_status 19 completed
467
468         scrub_check_flags 20 ""
469 }
470 run_test 5 "OI scrub state machine"
471
472 test_6() {
473         scrub_prep 1000
474         scrub_backup_restore 1
475         echo "starting MDTs with OI scrub disabled"
476         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
477         scrub_check_status 3 init
478         scrub_check_flags 4 inconsistent
479         mount_client $MOUNT || error "(5) Fail to start client!"
480         scrub_enable_auto
481         local n
482         for n in $(seq $MDSCOUNT); do
483                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
484                 do_facet mds$n $LCTL set_param fail_val=3
485                 do_facet mds$n $LCTL set_param fail_loc=0x190
486         done
487         scrub_check_data 6
488
489         # Sleep 5 sec to guarantee at least one object processed by OI scrub
490         sleep 5
491         # Fail the OI scrub to guarantee there is at least one checkpoint
492         for n in $(seq $MDSCOUNT); do
493                 #define OBD_FAIL_OSD_SCRUB_FATAL         0x192
494                 do_facet mds$n $LCTL set_param fail_loc=0x192
495         done
496         sleep 4
497         scrub_check_status 7 failed
498
499         for n in $(seq $MDSCOUNT); do
500                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
501                 do_facet mds$n $LCTL set_param fail_val=3
502                 do_facet mds$n $LCTL set_param fail_loc=0x190
503                 # stat will re-trigger OI scrub
504                 stat $DIR/$tdir/mds$n/${tfile}800 ||
505                         error "(8) Failed to stat mds$n/${tfile}800"
506         done
507
508         umount_client $MOUNT || error "(9) Fail to stop client!"
509
510         scrub_check_status 10 scanning
511
512         for n in $(seq $MDSCOUNT); do
513                 #define OBD_FAIL_OSD_SCRUB_CRASH         0x191
514                 do_facet mds$n $LCTL set_param fail_loc=0x191
515         done
516         sleep 4
517         local -a position0
518         for n in $(seq $MDSCOUNT); do
519                 position0[$n]=$(scrub_status $n |
520                         awk '/^last_checkpoint_position/ {print $2}')
521                 position0[$n]=$((${position0[$n]} + 1))
522         done
523
524         scrub_stop_mds 11
525
526         for n in $(seq $MDSCOUNT); do
527                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
528                 do_facet mds$n $LCTL set_param fail_val=3
529                 do_facet mds$n $LCTL set_param fail_loc=0x190
530         done
531         echo "starting MDTs without disabling OI scrub"
532         scrub_start_mds 12 "$MOUNT_OPTS_SCRUB"
533
534         scrub_check_status 13 scanning
535
536         local -a position1
537         for n in $(seq $MDSCOUNT); do
538                 positions1[$n]=$(scrub_status $n |
539                         awk '/^latest_start_position/ {print $2}')
540                 if [ ${position0[$n]} -ne ${position1[$n]} ]; then
541                         error "(14) Expected position ${position0[$n]}, but" \
542                                 "got ${position1[$n]}"
543                 fi
544         done
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 15 completed
552
553         scrub_check_flags 16 ""
554 }
555 run_test 6 "OI scrub resumes from last checkpoint"
556
557 test_7() {
558         scrub_prep 500
559         scrub_backup_restore 1
560
561         echo "starting MDTs with OI scrub disabled"
562         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
563         scrub_check_status 3 init
564         scrub_check_flags 4 inconsistent
565
566         mount_client $MOUNT || error "(5) Fail to start client!"
567
568         scrub_enable_auto
569         local n
570         for n in $(seq $MDSCOUNT); do
571                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
572                 do_facet mds$n $LCTL set_param fail_val=3
573                 do_facet mds$n $LCTL set_param fail_loc=0x190
574         done
575         scrub_check_data 6
576
577         for n in $(seq $MDSCOUNT); do
578                 stat $DIR/$tdir/mds$n/${tfile}300 ||
579                         error "(7) Failed to stat mds$n/${tfile}300!"
580         done
581
582         scrub_check_status 8 scanning
583
584         scrub_check_flags 9 inconsistent,auto
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 10 completed
592
593         scrub_check_flags ""
594 }
595 run_test 7 "System is available during OI scrub scanning"
596
597 test_8() {
598         scrub_prep 128
599         scrub_backup_restore 1
600
601         echo "starting MDTs with OI scrub disabled"
602         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
603
604         scrub_check_status 3 init
605
606         scrub_check_flags 4 inconsistent
607
608         local n
609         for n in $(seq $MDSCOUNT); do
610                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
611                 do_facet mds$n $LCTL set_param fail_val=1
612                 do_facet mds$n $LCTL set_param fail_loc=0x190
613         done
614         scrub_start 5
615
616         scrub_check_status 6 scanning
617
618         scrub_stop 7
619
620         scrub_check_status 8 stopped
621
622         scrub_start 9
623
624         scrub_check_status 10 scanning
625
626         for n in $(seq $MDSCOUNT); do
627                 do_facet mds$n $LCTL set_param fail_loc=0
628                 do_facet mds$n $LCTL set_param fail_val=0
629         done
630         sleep 5
631         scrub_check_status 11 completed
632
633         scrub_check_flags 12 ""
634 }
635 run_test 8 "Control OI scrub manually"
636
637 test_9() {
638         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
639                 skip "Testing on UP system, the speed may be inaccurate."
640                 return 0
641         fi
642
643         scrub_prep 8000
644         scrub_backup_restore 1
645
646         echo "starting MDTs with OI scrub disabled"
647         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
648
649         scrub_check_status 3 init
650
651         scrub_check_flags 4 inconsistent
652
653         local BASE_SPEED1=100
654         local RUN_TIME1=10
655         # OI scrub should run with full speed under inconsistent case
656         scrub_start 5 -s $BASE_SPEED1
657
658         sleep $RUN_TIME1
659         scrub_check_status 6 completed
660
661         scrub_check_flags 7 ""
662
663         # OI scrub should run with limited speed under non-inconsistent case
664         scrub_start 8 -s $BASE_SPEED1 -r
665
666         sleep $RUN_TIME1
667         scrub_check_status 9 scanning
668
669         # Do NOT ignore that there are 1024 pre-fetched items. And there
670         # may be time error, normally it should be less than 2 seconds.
671         # We allow another 20% schedule error.
672         local PRE_FETCHED=1024
673         local TIME_DIFF=2
674         # MAX_MARGIN = 1.2 = 12 / 10
675         local MAX_SPEED=$(((PRE_FETCHED + BASE_SPEED1 * \
676                 (RUN_TIME1 + TIME_DIFF)) / RUN_TIME1 * 12 / 10))
677         local n
678         for n in $(seq $MDSCOUNT); do
679                 local SPEED=$(scrub_status $n | \
680                         awk '/^average_speed/ { print $2 }')
681                 [ $SPEED -lt $MAX_SPEED ] ||
682                         error "(10) Got speed $SPEED, expected less than" \
683                                 "$MAX_SPEED"
684         done
685
686         # adjust speed limit
687         local BASE_SPEED2=300
688         local RUN_TIME2=10
689         for n in $(seq $MDSCOUNT); do
690                 do_facet mds$n $LCTL set_param -n \
691                         mdd.$(facet_svc mds$n).lfsck_speed_limit $BASE_SPEED2
692         done
693         sleep $RUN_TIME2
694
695         # MIN_MARGIN = 0.8 = 8 / 10
696         local MIN_SPEED=$(((PRE_FETCHED + \
697                             BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
698                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
699                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
700         # MAX_MARGIN = 1.2 = 12 / 10
701         MAX_SPEED=$(((PRE_FETCHED + \
702                       BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
703                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
704                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
705         for n in $(seq $MDSCOUNT); do
706                 SPEED=$(scrub_status $n | awk '/^average_speed/ { print $2 }')
707                 [ $SPEED -gt $MIN_SPEED ] ||
708                         error "(11) Got speed $SPEED, expected more than" \
709                                 "$MIN_SPEED"
710                 [ $SPEED -lt $MAX_SPEED ] ||
711                         error "(12) Got speed $SPEED, expected less than" \
712                                 "$MAX_SPEED"
713
714                 do_facet mds$n $LCTL set_param -n \
715                                 mdd.$(facet_svc mds$n).lfsck_speed_limit 0
716         done
717         sleep 6
718         scrub_check_status 13 completed
719 }
720 run_test 9 "OI scrub speed control"
721
722 test_10a() {
723         scrub_prep 0
724         scrub_backup_restore 1
725
726         echo "starting mds$n with OI scrub disabled"
727         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
728
729         scrub_check_status 3 init
730
731         scrub_check_flags 4 inconsistent
732
733         mount_client $MOUNT || error "(5) Fail to start client!"
734
735         scrub_enable_auto
736         local n
737         for n in $(seq $MDSCOUNT); do
738                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
739                 do_facet mds$n $LCTL set_param fail_val=1
740                 do_facet mds$n $LCTL set_param fail_loc=0x190
741         done
742         scrub_check_data 6
743
744         scrub_check_status 7 scanning
745
746         umount_client $MOUNT || error "(8) Fail to stop client!"
747
748         scrub_stop_mds 9
749
750         echo "starting MDTs with OI scrub disabled"
751         scrub_start_mds 10 "$MOUNT_OPTS_NOSCRUB"
752
753         scrub_check_status 11 paused
754
755         scrub_stop_mds 12
756
757         echo "starting MDTs without disabling OI scrub"
758         scrub_start_mds 13 "$MOUNT_OPTS_SCRUB"
759
760         scrub_check_status 14 scanning
761
762         for n in $(seq $MDSCOUNT); do
763                 do_facet mds$n $LCTL set_param fail_loc=0
764                 do_facet mds$n $LCTL set_param fail_val=0
765         done
766         sleep 5
767         scrub_check_status 15 completed
768
769         scrub_check_flags 16 ""
770 }
771 run_test 10a "non-stopped OI scrub should auto restarts after MDS remount (1)"
772
773 # test_10b is obsolete, it will be coverded by related sanity-lfsck tests.
774 test_10b() {
775         scrub_prep 0
776         scrub_backup_restore 1
777
778         echo "starting MDTs with OI scrub disabled"
779         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
780
781         scrub_check_status 3 init
782
783         scrub_check_flags 4 inconsistent
784
785         local n
786         for n in $(seq $MDSCOUNT); do
787                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
788                 do_facet mds$n $LCTL set_param fail_val=3
789                 do_facet mds$n $LCTL set_param fail_loc=0x190
790         done
791
792         scrub_start 5
793
794         scrub_check_status 6 scanning
795
796         scrub_stop_mds 7
797
798         echo "starting MDTs with OI scrub disabled"
799         scrub_start_mds 8 "$MOUNT_OPTS_NOSCRUB"
800
801         scrub_check_status 9 paused
802
803         scrub_stop_mds 10
804
805         echo "starting MDTs without disabling OI scrub"
806         scrub_start_mds 11 "$MOUNT_OPTS_SCRUB"
807
808         scrub_check_status 12 scanning
809
810         for n in $(seq $MDSCOUNT); do
811                 do_facet mds$n $LCTL set_param fail_loc=0
812                 do_facet mds$n $LCTL set_param fail_val=0
813         done
814         sleep 5
815         scrub_check_status 13 completed
816
817         scrub_check_flags 14 ""
818 }
819 #run_test 10b "non-stopped OI scrub should auto restarts after MDS remount (2)"
820
821 test_11() {
822         echo "stopall"
823         stopall > /dev/null
824         echo "formatall"
825         formatall > /dev/null
826         echo "setupall"
827         setupall > /dev/null
828
829         local CREATED=100
830         local tname=`date +%s`
831         rm -rf $MOUNT/$tname > /dev/null
832         mkdir -p $MOUNT/$tname || error "(0) Failed to create $MOUNT/$tname"
833         local n
834         for n in $(seq $MDSCOUNT); do
835                 $LFS mkdir -i $((n - 1)) $MOUNT/$tname/mds$n ||
836                         error "(1) Fail to mkdir $MOUNT/$tname/mds$n"
837
838                 createmany -o $MOUNT/$tname/mds$n/f $CREATED ||
839                         error "(2) Fail to create in $tname/mds$n"
840         done
841
842         cleanup_mount $MOUNT
843         do_facet $SINGLEMDS $LCTL clear
844         start_full_debug_logging
845         # reset OI scrub start point by force
846         scrub_start 3 -r
847         sleep 3
848         scrub_check_status 4 completed
849
850         # OI scrub should skip the new created objects for the first accessing
851         # notice we're creating a new llog for every OST on every startup
852         # new features can make this even less stable, so we only check
853         # that the number of skipped files is less than 2x the number of files
854         local MAXIMUM=$((CREATED * 2))
855         local MINIMUM=$((CREATED + 1)) # files + directory
856         for n in $(seq $MDSCOUNT); do
857                 local SKIPPED=$(scrub_status $n | awk '/^noscrub/ { print $2 }')
858                 [ $SKIPPED -ge $MAXIMUM -o $SKIPPED -lt $MINIMUM ] &&
859                         error "(5) Expect [ $MINIMUM , $MAXIMUM ) objects" \
860                                 "skipped on mds$n, but got $SKIPPED"
861         done
862
863         # reset OI scrub start point by force
864         scrub_start -r
865         sleep 3
866         scrub_check_status 7 completed
867
868         # OI scrub should skip the new created object only once
869         for n in $(seq $MDSCOUNT); do
870                 SKIPPED=$(scrub_status $n | awk '/^noscrub/ { print $2 }')
871                 [ $SKIPPED -eq 0 ] ||
872                         error "(8) Expect 0 objects skipped on mds$n, but" \
873                                 "got $SKIPPED"
874         done
875
876         stop_full_debug_logging
877         restore_mount $MOUNT || error "(9) Fail to start client!"
878         rm -rf $MOUNT/$tname > /dev/null
879 }
880 run_test 11 "OI scrub skips the new created objects only once"
881
882 test_12() {
883         echo "stopall"
884         stopall > /dev/null
885         echo "formatall"
886         formatall > /dev/null
887         echo "setupall"
888         setupall > /dev/null
889
890         mkdir -p $DIR/$tdir
891         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
892
893         #define OBD_FAIL_OSD_COMPAT_INVALID_ENTRY               0x195
894         do_facet ost1 $LCTL set_param fail_loc=0x195
895         createmany -o $DIR/$tdir/f 1000
896
897         echo "stopall"
898         stopall > /dev/null
899         echo "setupall"
900         setupall > /dev/null
901
902         do_facet ost1 $LCTL set_param fail_loc=0
903         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
904         [ "$STATUS" == "init" ] ||
905                 error "(1) Expect 'init', but got '$STATUS'"
906
907         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
908
909         sleep 3
910         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
911         [ "$STATUS" == "completed" ] ||
912                 error "(3) Expect 'completed', but got '$STATUS'"
913
914         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(4) ls should succeed"
915 }
916 run_test 12 "OI scrub can rebuild invalid /O entries"
917
918 test_13() {
919         echo "stopall"
920         stopall > /dev/null
921         echo "formatall"
922         formatall > /dev/null
923         echo "setupall"
924         setupall > /dev/null
925
926         mkdir -p $DIR/$tdir
927         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
928
929         #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
930         do_facet ost1 $LCTL set_param fail_loc=0x196
931         createmany -o $DIR/$tdir/f 1000
932         do_facet ost1 $LCTL set_param fail_loc=0
933
934         echo "stopall"
935         stopall > /dev/null
936         echo "setupall"
937         setupall > /dev/null
938
939         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
940         [ "$STATUS" == "init" ] ||
941                 error "(1) Expect 'init', but got '$STATUS'"
942
943         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
944
945         $START_SCRUB_ON_OST || error "(3) Fail to start OI scrub on OST!"
946         sleep 3
947         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
948         [ "$STATUS" == "completed" ] ||
949                 error "(4) Expect 'completed', but got '$STATUS'"
950
951         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(5) ls should succeed"
952 }
953 run_test 13 "OI scrub can rebuild missed /O entries"
954
955 test_14() {
956         echo "stopall"
957         stopall > /dev/null
958         echo "formatall"
959         formatall > /dev/null
960         echo "setupall"
961         setupall > /dev/null
962
963         mkdir -p $DIR/$tdir
964         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
965
966         #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
967         do_facet ost1 $LCTL set_param fail_loc=0x196
968         createmany -o $DIR/$tdir/f 64
969         do_facet ost1 $LCTL set_param fail_loc=0
970
971         echo "stopall"
972         stopall > /dev/null
973         echo "setupall"
974         setupall > /dev/null
975
976         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
977         [ "$STATUS" == "init" ] ||
978                 error "(1) Expect 'init', but got '$STATUS'"
979
980         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
981
982         echo "stopall"
983         stopall > /dev/null
984
985         echo "run e2fsck"
986         run_e2fsck $(facet_host ost1) $(ostdevname 1) "-y" ||
987                 error "(3) Fail to run e2fsck error"
988
989         echo "setupall"
990         setupall > /dev/null
991
992         local LF_REPAIRED=$($SHOW_SCRUB_ON_OST |
993                             awk '/^lf_reparied/ { print $2 }')
994         [ $LF_REPAIRED -gt 0 ] ||
995                 error "(4) Some entry under /lost+found should be repaired"
996
997         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(5) ls should succeed"
998 }
999 run_test 14 "OI scrub can repair objects under lost+found"
1000
1001 test_15() {
1002         scrub_prep 20
1003         scrub_backup_restore 1
1004         echo "starting MDTs with OI scrub disabled"
1005         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
1006         scrub_check_status 3 init
1007         scrub_check_flags 4 inconsistent
1008
1009         # run under dryrun mode
1010         scrub_start 5 -n on
1011         sleep 3
1012         scrub_check_status 6 completed
1013         scrub_check_flags 7 inconsistent
1014         scrub_check_params 8 dryrun
1015         scrub_check_repaired 9 20
1016
1017         # run under dryrun mode again
1018         scrub_start 10 -n on
1019         sleep 3
1020         scrub_check_status 11 completed
1021         scrub_check_flags 12 inconsistent
1022         scrub_check_params 13 dryrun
1023         scrub_check_repaired 14 20
1024
1025         # run under normal mode
1026         scrub_start 15 -n off
1027         sleep 3
1028         scrub_check_status 16 completed
1029         scrub_check_flags 17 ""
1030         scrub_check_params 18 ""
1031         scrub_check_repaired 19 20
1032
1033         # run under normal mode again
1034         scrub_start 20 -n off
1035         sleep 3
1036         scrub_check_status 21 completed
1037         scrub_check_flags 22 ""
1038         scrub_check_params 23 ""
1039         scrub_check_repaired 24 0
1040 }
1041 run_test 15 "Dryrun mode OI scrub"
1042
1043 # restore MDS/OST size
1044 MDSSIZE=${SAVED_MDSSIZE}
1045 OSTSIZE=${SAVED_OSTSIZE}
1046
1047 # cleanup the system at last
1048 formatall
1049
1050 complete $SECONDS
1051 exit_status