Whamcloud - gitweb
LU-4149 tests: disable sanity_scrub(7, 15) for dne test.
[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         # skip test_7 for LU-4149
559         [ $MDSCOUNT -ge 2 ] && skip "skip now for >= 2 MDTs" && return
560
561         scrub_prep 500
562         scrub_backup_restore 1
563
564         echo "starting MDTs with OI scrub disabled"
565         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
566         scrub_check_status 3 init
567         scrub_check_flags 4 inconsistent
568
569         mount_client $MOUNT || error "(5) Fail to start client!"
570
571         scrub_enable_auto
572         local n
573         for n in $(seq $MDSCOUNT); do
574                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
575                 do_facet mds$n $LCTL set_param fail_val=3
576                 do_facet mds$n $LCTL set_param fail_loc=0x190
577         done
578         scrub_check_data 6
579
580         for n in $(seq $MDSCOUNT); do
581                 stat $DIR/$tdir/mds$n/${tfile}300 ||
582                         error "(7) Failed to stat mds$n/${tfile}300!"
583         done
584
585         scrub_check_status 8 scanning
586
587         scrub_check_flags 9 inconsistent,auto
588
589         for n in $(seq $MDSCOUNT); do
590                 do_facet mds$n $LCTL set_param fail_loc=0
591                 do_facet mds$n $LCTL set_param fail_val=0
592         done
593         sleep 5
594         scrub_check_status 10 completed
595
596         scrub_check_flags ""
597 }
598 run_test 7 "System is available during OI scrub scanning"
599
600 test_8() {
601         scrub_prep 128
602         scrub_backup_restore 1
603
604         echo "starting MDTs with OI scrub disabled"
605         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
606
607         scrub_check_status 3 init
608
609         scrub_check_flags 4 inconsistent
610
611         local n
612         for n in $(seq $MDSCOUNT); do
613                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
614                 do_facet mds$n $LCTL set_param fail_val=1
615                 do_facet mds$n $LCTL set_param fail_loc=0x190
616         done
617         scrub_start 5
618
619         scrub_check_status 6 scanning
620
621         scrub_stop 7
622
623         scrub_check_status 8 stopped
624
625         scrub_start 9
626
627         scrub_check_status 10 scanning
628
629         for n in $(seq $MDSCOUNT); do
630                 do_facet mds$n $LCTL set_param fail_loc=0
631                 do_facet mds$n $LCTL set_param fail_val=0
632         done
633         sleep 5
634         scrub_check_status 11 completed
635
636         scrub_check_flags 12 ""
637 }
638 run_test 8 "Control OI scrub manually"
639
640 test_9() {
641         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
642                 skip "Testing on UP system, the speed may be inaccurate."
643                 return 0
644         fi
645
646         scrub_prep 8000
647         scrub_backup_restore 1
648
649         echo "starting MDTs with OI scrub disabled"
650         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
651
652         scrub_check_status 3 init
653
654         scrub_check_flags 4 inconsistent
655
656         local BASE_SPEED1=100
657         local RUN_TIME1=10
658         # OI scrub should run with full speed under inconsistent case
659         scrub_start 5 -s $BASE_SPEED1
660
661         sleep $RUN_TIME1
662         scrub_check_status 6 completed
663
664         scrub_check_flags 7 ""
665
666         # OI scrub should run with limited speed under non-inconsistent case
667         scrub_start 8 -s $BASE_SPEED1 -r
668
669         sleep $RUN_TIME1
670         scrub_check_status 9 scanning
671
672         # Do NOT ignore that there are 1024 pre-fetched items. And there
673         # may be time error, normally it should be less than 2 seconds.
674         # We allow another 20% schedule error.
675         local PRE_FETCHED=1024
676         local TIME_DIFF=2
677         # MAX_MARGIN = 1.2 = 12 / 10
678         local MAX_SPEED=$(((PRE_FETCHED + BASE_SPEED1 * \
679                 (RUN_TIME1 + TIME_DIFF)) / RUN_TIME1 * 12 / 10))
680         local n
681         for n in $(seq $MDSCOUNT); do
682                 local SPEED=$(scrub_status $n | \
683                         awk '/^average_speed/ { print $2 }')
684                 [ $SPEED -lt $MAX_SPEED ] ||
685                         error "(10) Got speed $SPEED, expected less than" \
686                                 "$MAX_SPEED"
687         done
688
689         # adjust speed limit
690         local BASE_SPEED2=300
691         local RUN_TIME2=10
692         for n in $(seq $MDSCOUNT); do
693                 do_facet mds$n $LCTL set_param -n \
694                         mdd.$(facet_svc mds$n).lfsck_speed_limit $BASE_SPEED2
695         done
696         sleep $RUN_TIME2
697
698         # MIN_MARGIN = 0.8 = 8 / 10
699         local MIN_SPEED=$(((PRE_FETCHED + \
700                             BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
701                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
702                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
703         # MAX_MARGIN = 1.2 = 12 / 10
704         MAX_SPEED=$(((PRE_FETCHED + \
705                       BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
706                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
707                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
708         for n in $(seq $MDSCOUNT); do
709                 SPEED=$(scrub_status $n | awk '/^average_speed/ { print $2 }')
710                 [ $SPEED -gt $MIN_SPEED ] ||
711                         error "(11) Got speed $SPEED, expected more than" \
712                                 "$MIN_SPEED"
713                 [ $SPEED -lt $MAX_SPEED ] ||
714                         error "(12) Got speed $SPEED, expected less than" \
715                                 "$MAX_SPEED"
716
717                 do_facet mds$n $LCTL set_param -n \
718                                 mdd.$(facet_svc mds$n).lfsck_speed_limit 0
719         done
720         sleep 6
721         scrub_check_status 13 completed
722 }
723 run_test 9 "OI scrub speed control"
724
725 test_10a() {
726         scrub_prep 0
727         scrub_backup_restore 1
728
729         echo "starting mds$n with OI scrub disabled"
730         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
731
732         scrub_check_status 3 init
733
734         scrub_check_flags 4 inconsistent
735
736         mount_client $MOUNT || error "(5) Fail to start client!"
737
738         scrub_enable_auto
739         local n
740         for n in $(seq $MDSCOUNT); do
741                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
742                 do_facet mds$n $LCTL set_param fail_val=1
743                 do_facet mds$n $LCTL set_param fail_loc=0x190
744         done
745         scrub_check_data 6
746
747         scrub_check_status 7 scanning
748
749         umount_client $MOUNT || error "(8) Fail to stop client!"
750
751         scrub_stop_mds 9
752
753         echo "starting MDTs with OI scrub disabled"
754         scrub_start_mds 10 "$MOUNT_OPTS_NOSCRUB"
755
756         scrub_check_status 11 paused
757
758         scrub_stop_mds 12
759
760         echo "starting MDTs without disabling OI scrub"
761         scrub_start_mds 13 "$MOUNT_OPTS_SCRUB"
762
763         scrub_check_status 14 scanning
764
765         for n in $(seq $MDSCOUNT); do
766                 do_facet mds$n $LCTL set_param fail_loc=0
767                 do_facet mds$n $LCTL set_param fail_val=0
768         done
769         sleep 5
770         scrub_check_status 15 completed
771
772         scrub_check_flags 16 ""
773 }
774 run_test 10a "non-stopped OI scrub should auto restarts after MDS remount (1)"
775
776 # test_10b is obsolete, it will be coverded by related sanity-lfsck tests.
777 test_10b() {
778         scrub_prep 0
779         scrub_backup_restore 1
780
781         echo "starting MDTs with OI scrub disabled"
782         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
783
784         scrub_check_status 3 init
785
786         scrub_check_flags 4 inconsistent
787
788         local n
789         for n in $(seq $MDSCOUNT); do
790                 #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
791                 do_facet mds$n $LCTL set_param fail_val=3
792                 do_facet mds$n $LCTL set_param fail_loc=0x190
793         done
794
795         scrub_start 5
796
797         scrub_check_status 6 scanning
798
799         scrub_stop_mds 7
800
801         echo "starting MDTs with OI scrub disabled"
802         scrub_start_mds 8 "$MOUNT_OPTS_NOSCRUB"
803
804         scrub_check_status 9 paused
805
806         scrub_stop_mds 10
807
808         echo "starting MDTs without disabling OI scrub"
809         scrub_start_mds 11 "$MOUNT_OPTS_SCRUB"
810
811         scrub_check_status 12 scanning
812
813         for n in $(seq $MDSCOUNT); do
814                 do_facet mds$n $LCTL set_param fail_loc=0
815                 do_facet mds$n $LCTL set_param fail_val=0
816         done
817         sleep 5
818         scrub_check_status 13 completed
819
820         scrub_check_flags 14 ""
821 }
822 #run_test 10b "non-stopped OI scrub should auto restarts after MDS remount (2)"
823
824 test_11() {
825         echo "stopall"
826         stopall > /dev/null
827         echo "formatall"
828         formatall > /dev/null
829         echo "setupall"
830         setupall > /dev/null
831
832         local CREATED=100
833         local tname=`date +%s`
834         rm -rf $MOUNT/$tname > /dev/null
835         mkdir -p $MOUNT/$tname || error "(0) Failed to create $MOUNT/$tname"
836         local n
837         for n in $(seq $MDSCOUNT); do
838                 $LFS mkdir -i $((n - 1)) $MOUNT/$tname/mds$n ||
839                         error "(1) Fail to mkdir $MOUNT/$tname/mds$n"
840
841                 createmany -o $MOUNT/$tname/mds$n/f $CREATED ||
842                         error "(2) Fail to create in $tname/mds$n"
843         done
844
845         cleanup_mount $MOUNT
846         do_facet $SINGLEMDS $LCTL clear
847         start_full_debug_logging
848         # reset OI scrub start point by force
849         scrub_start 3 -r
850         sleep 3
851         scrub_check_status 4 completed
852
853         # OI scrub should skip the new created objects for the first accessing
854         # notice we're creating a new llog for every OST on every startup
855         # new features can make this even less stable, so we only check
856         # that the number of skipped files is less than 2x the number of files
857         local MAXIMUM=$((CREATED * 2))
858         local MINIMUM=$((CREATED + 1)) # files + directory
859         for n in $(seq $MDSCOUNT); do
860                 local SKIPPED=$(scrub_status $n | awk '/^noscrub/ { print $2 }')
861                 [ $SKIPPED -ge $MAXIMUM -o $SKIPPED -lt $MINIMUM ] &&
862                         error "(5) Expect [ $MINIMUM , $MAXIMUM ) objects" \
863                                 "skipped on mds$n, but got $SKIPPED"
864         done
865
866         # reset OI scrub start point by force
867         scrub_start -r
868         sleep 3
869         scrub_check_status 7 completed
870
871         # OI scrub should skip the new created object only once
872         for n in $(seq $MDSCOUNT); do
873                 SKIPPED=$(scrub_status $n | awk '/^noscrub/ { print $2 }')
874                 [ $SKIPPED -eq 0 ] ||
875                         error "(8) Expect 0 objects skipped on mds$n, but" \
876                                 "got $SKIPPED"
877         done
878
879         stop_full_debug_logging
880         restore_mount $MOUNT || error "(9) Fail to start client!"
881         rm -rf $MOUNT/$tname > /dev/null
882 }
883 run_test 11 "OI scrub skips the new created objects only once"
884
885 test_12() {
886         echo "stopall"
887         stopall > /dev/null
888         echo "formatall"
889         formatall > /dev/null
890         echo "setupall"
891         setupall > /dev/null
892
893         mkdir -p $DIR/$tdir
894         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
895
896         #define OBD_FAIL_OSD_COMPAT_INVALID_ENTRY               0x195
897         do_facet ost1 $LCTL set_param fail_loc=0x195
898         createmany -o $DIR/$tdir/f 1000
899
900         echo "stopall"
901         stopall > /dev/null
902         echo "setupall"
903         setupall > /dev/null
904
905         do_facet ost1 $LCTL set_param fail_loc=0
906         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
907         [ "$STATUS" == "init" ] ||
908                 error "(1) Expect 'init', but got '$STATUS'"
909
910         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
911
912         sleep 3
913         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
914         [ "$STATUS" == "completed" ] ||
915                 error "(3) Expect 'completed', but got '$STATUS'"
916
917         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(4) ls should succeed"
918 }
919 run_test 12 "OI scrub can rebuild invalid /O entries"
920
921 test_13() {
922         echo "stopall"
923         stopall > /dev/null
924         echo "formatall"
925         formatall > /dev/null
926         echo "setupall"
927         setupall > /dev/null
928
929         mkdir -p $DIR/$tdir
930         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
931
932         #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
933         do_facet ost1 $LCTL set_param fail_loc=0x196
934         createmany -o $DIR/$tdir/f 1000
935         do_facet ost1 $LCTL set_param fail_loc=0
936
937         echo "stopall"
938         stopall > /dev/null
939         echo "setupall"
940         setupall > /dev/null
941
942         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
943         [ "$STATUS" == "init" ] ||
944                 error "(1) Expect 'init', but got '$STATUS'"
945
946         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
947
948         $START_SCRUB_ON_OST || error "(3) Fail to start OI scrub on OST!"
949         sleep 3
950         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
951         [ "$STATUS" == "completed" ] ||
952                 error "(4) Expect 'completed', but got '$STATUS'"
953
954         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(5) ls should succeed"
955 }
956 run_test 13 "OI scrub can rebuild missed /O entries"
957
958 test_14() {
959         echo "stopall"
960         stopall > /dev/null
961         echo "formatall"
962         formatall > /dev/null
963         echo "setupall"
964         setupall > /dev/null
965
966         mkdir -p $DIR/$tdir
967         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
968
969         #define OBD_FAIL_OSD_COMPAT_NO_ENTRY            0x196
970         do_facet ost1 $LCTL set_param fail_loc=0x196
971         createmany -o $DIR/$tdir/f 64
972         do_facet ost1 $LCTL set_param fail_loc=0
973
974         echo "stopall"
975         stopall > /dev/null
976         echo "setupall"
977         setupall > /dev/null
978
979         local STATUS=$($SHOW_SCRUB_ON_OST | awk '/^status/ { print $2 }')
980         [ "$STATUS" == "init" ] ||
981                 error "(1) Expect 'init', but got '$STATUS'"
982
983         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(2) ls should fail"
984
985         echo "stopall"
986         stopall > /dev/null
987
988         echo "run e2fsck"
989         run_e2fsck $(facet_host ost1) $(ostdevname 1) "-y" ||
990                 error "(3) Fail to run e2fsck error"
991
992         echo "setupall"
993         setupall > /dev/null
994
995         local LF_REPAIRED=$($SHOW_SCRUB_ON_OST |
996                             awk '/^lf_reparied/ { print $2 }')
997         [ $LF_REPAIRED -gt 0 ] ||
998                 error "(4) Some entry under /lost+found should be repaired"
999
1000         ls -ail $DIR/$tdir > /dev/null 2>&1 || error "(5) ls should succeed"
1001 }
1002 run_test 14 "OI scrub can repair objects under lost+found"
1003
1004 test_15() {
1005         # skip test_15 for LU-4182
1006         [ $MDSCOUNT -ge 2 ] && skip "skip now for >= 2 MDTs" && return
1007         scrub_prep 20
1008         scrub_backup_restore 1
1009         echo "starting MDTs with OI scrub disabled"
1010         scrub_start_mds 2 "$MOUNT_OPTS_NOSCRUB"
1011         scrub_check_status 3 init
1012         scrub_check_flags 4 inconsistent
1013
1014         # run under dryrun mode
1015         scrub_start 5 -n on
1016         sleep 3
1017         scrub_check_status 6 completed
1018         scrub_check_flags 7 inconsistent
1019         scrub_check_params 8 dryrun
1020         scrub_check_repaired 9 20
1021
1022         # run under dryrun mode again
1023         scrub_start 10 -n on
1024         sleep 3
1025         scrub_check_status 11 completed
1026         scrub_check_flags 12 inconsistent
1027         scrub_check_params 13 dryrun
1028         scrub_check_repaired 14 20
1029
1030         # run under normal mode
1031         scrub_start 15 -n off
1032         sleep 3
1033         scrub_check_status 16 completed
1034         scrub_check_flags 17 ""
1035         scrub_check_params 18 ""
1036         scrub_check_repaired 19 20
1037
1038         # run under normal mode again
1039         scrub_start 20 -n off
1040         sleep 3
1041         scrub_check_status 21 completed
1042         scrub_check_flags 22 ""
1043         scrub_check_params 23 ""
1044         scrub_check_repaired 24 0
1045 }
1046 run_test 15 "Dryrun mode OI scrub"
1047
1048 # restore MDS/OST size
1049 MDSSIZE=${SAVED_MDSSIZE}
1050 OSTSIZE=${SAVED_OSTSIZE}
1051
1052 # cleanup the system at last
1053 formatall
1054
1055 complete $SECONDS
1056 exit_status