Whamcloud - gitweb
e8e13fa297c2464c6351acd1720c1dffaf81d27a
[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 check_and_setup_lustre
30
31 [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
32         skip "test OI scrub only for ldiskfs" && check_and_cleanup_lustre &&
33         exit 0
34 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.2.90) ]] &&
35         skip "Need MDS version at least 2.2.90" && check_and_cleanup_lustre &&
36         exit 0
37
38 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.90) ]] &&
39         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 1a"
40
41 build_test_filter
42
43 MDT_DEV="${FSNAME}-MDT0000"
44 MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
45 START_SCRUB="do_facet $SINGLEMDS $LCTL lfsck_start -M ${MDT_DEV}"
46 STOP_SCRUB="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
47 SHOW_SCRUB="do_facet $SINGLEMDS \
48                 $LCTL get_param -n osd-ldiskfs.${MDT_DEV}.oi_scrub"
49 MOUNT_OPTS_SCRUB="-o user_xattr"
50 MOUNT_OPTS_NOSCRUB="-o user_xattr,noscrub"
51
52 scrub_prep() {
53         local nfiles=$1
54
55         echo "formatall"
56         formatall > /dev/null
57         echo "setupall"
58         setupall > /dev/null
59
60         echo "preparing... ${nfiles} files will be created."
61         mkdir -p $DIR/$tdir
62         cp $LUSTRE/tests/*.sh $DIR/$tdir/
63         [[ $nfiles -gt 0 ]] && { createmany -o $DIR/$tdir/$tfile $nfiles ||
64                                 error "createmany failed"; }
65
66         echo "prepared."
67         cleanup_mount $MOUNT > /dev/null || error "Fail to stop client!"
68         echo "stop $SINGLEMDS"
69         stop $SINGLEMDS > /dev/null || error "Fail to stop MDS!"
70 }
71
72 test_0() {
73         scrub_prep 0
74         echo "start $SINGLEMDS without disabling OI scrub"
75         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
76                 error "(1) Fail to start MDS!"
77
78         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
79         [ "$STATUS" == "init" ] ||
80                 error "(2) Expect 'init', but got '$STATUS'"
81
82         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
83         [ -z "$FLAGS" ] || error "(3) Expect empty flags, but got '$FLAGS'"
84
85         mount_client $MOUNT || error "(4) Fail to start client!"
86
87         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
88                 error "(5) File diff failed unexpected!"
89 }
90 run_test 0 "Do not auto trigger OI scrub for non-backup/restore case"
91
92 test_1a() {
93         scrub_prep 0
94         echo "start $SINGLEMDS without disabling OI scrub"
95         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
96                 error "(1) Fail to start MDS!"
97
98         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
99         [ "$STATUS" == "init" ] ||
100                 error "(2) Expect 'init', but got '$STATUS'"
101
102         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
103         [ -z "$FLAGS" ] || error "(3) Expect empty flags, but got '$FLAGS'"
104
105         mount_client $MOUNT || error "(4) Fail to start client!"
106
107         #define OBD_FAIL_OSD_FID_MAPPING                        0x193
108         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x193
109         # update .lustre OI mapping
110         touch $MOUNT/.lustre
111         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
112
113         umount_client $MOUNT || error "(5) Fail to stop client!"
114
115         echo "stop $SINGLEMDS"
116         stop $SINGLEMDS > /dev/null || error "(6) Fail to stop MDS!"
117
118         echo "start $SINGLEMDS with disabling OI scrub"
119         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
120                 error "(7) Fail to start MDS!"
121
122         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
123         [ "$STATUS" == "init" ] ||
124                 error "(8) Expect 'init', but got '$STATUS'"
125
126         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
127         [ "$FLAGS" == "inconsistent" ] ||
128                 error "(9) Expect 'inconsistent', but got '$FLAGS'"
129 }
130 run_test 1a "Auto trigger initial OI scrub when server mounts"
131
132 test_1b() {
133         scrub_prep 0
134         mds_remove_ois || error "(1) Fail to remove/recreate!"
135
136         echo "start $SINGLEMDS without disabling OI scrub"
137         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
138                 error "(2) Fail to start MDS!"
139
140         sleep 3
141         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
142         [ "$STATUS" == "completed" ] ||
143                 error "(3) Expect 'completed', but got '$STATUS'"
144
145         mount_client $MOUNT || error "(4) Fail to start client!"
146
147         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
148                 error "(5) File diff failed unexpected!"
149 }
150 run_test 1b "Trigger OI scrub when MDT mounts for OI files remove/recreate case"
151
152 test_1c() {
153         local index
154
155         # OI files to be removed:
156         # idx 0: oi.16.0
157         # idx 1: oi.16.1
158         # idx 2: oi.16.{2,4,8,16,32}
159         # idx 3: oi.16.{3,9,27}
160         # idx 5: oi.16.{5,25}
161         # idx 7: oi.16.{7,49}
162         for index in 0 1 2 3 5 7; do
163                 scrub_prep 0
164                 mds_remove_ois ${index} || error "(1) Fail to remove/recreate!"
165
166                 echo "start $SINGLEMDS with disabling OI scrub"
167                 start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > \
168                         /dev/null || error "(2) Fail to start MDS!"
169
170                 local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
171                 [ "$FLAGS" == "recreated" ] ||
172                         error "(3) Expect 'recreated', but got '$FLAGS'"
173
174                 $START_SCRUB || error "(4) Fail to start OI scrub!"
175                 sleep 3
176                 local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
177                 [ "$STATUS" == "completed" ] ||
178                         error "(5) Expect 'completed', but got '$STATUS'"
179
180                 FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
181                 [ -z "$FLAGS" ] ||
182                         error "(6) Expect empty flags, but got '$FLAGS'"
183         done
184 }
185 run_test 1c "Auto detect kinds of OI file(s) removed/recreated cases"
186
187 test_2() {
188         scrub_prep 0
189         mds_backup_restore || error "(1) Fail to backup/restore!"
190
191         echo "start $SINGLEMDS without disabling OI scrub"
192         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
193                 error "(2) Fail to start MDS!"
194
195         sleep 3
196         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
197         [ "$STATUS" == "completed" ] ||
198                 error "(3) Expect 'completed', but got '$STATUS'"
199
200         mount_client $MOUNT || error "(4) Fail to start client!"
201
202         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
203                 error "(5) File diff failed unexpected!"
204 }
205 run_test 2 "Trigger OI scrub when MDT mounts for backup/restore case"
206
207 test_3() {
208         scrub_prep 0
209         mds_backup_restore || error "(1) Fail to backup/restore!"
210
211         echo "start $SINGLEMDS with disabling OI scrub"
212         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
213                 error "(2) Fail to start MDS!"
214
215         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
216         [ "$STATUS" == "init" ] ||
217                 error "(3) Expect 'init', but got '$STATUS'"
218
219         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
220         [ "$FLAGS" == "inconsistent" ] ||
221                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
222         echo "stopall"
223         stopall > /dev/null
224 }
225 run_test 3 "Do not trigger OI scrub when MDT mounts if 'noscrub' specified"
226
227 test_4() {
228         scrub_prep 0
229         mds_backup_restore || error "(1) Fail to backup/restore!"
230
231         echo "start $SINGLEMDS with disabling OI scrub"
232         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
233                 error "(2) Fail to start MDS!"
234
235         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
236         [ "$STATUS" == "init" ] ||
237                 error "(3) Expect 'init', but got '$STATUS'"
238
239         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
240         [ "$FLAGS" == "inconsistent" ] ||
241                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
242
243         mount_client $MOUNT || error "(5) Fail to start client!"
244
245         do_facet $SINGLEMDS \
246                 $LCTL set_param -n osd-ldiskfs.${MDT_DEV}.auto_scrub 1
247         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
248                 error "(6) File diff failed unexpected!"
249
250         sleep 3
251         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
252         [ "$STATUS" == "completed" ] ||
253                 error "(7) Expect 'completed', but got '$STATUS'"
254 }
255 run_test 4 "Trigger OI scrub automatically if inconsistent OI mapping was found"
256
257 test_5() {
258         scrub_prep 1500
259         mds_backup_restore || error "(1) Fail to backup/restore!"
260
261         echo "start $SINGLEMDS with disabling OI scrub"
262         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
263                 error "(2) Fail to start MDS!"
264
265         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
266         [ "$STATUS" == "init" ] ||
267                 error "(3) Expect 'init', but got '$STATUS'"
268
269         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
270         [ "$FLAGS" == "inconsistent" ] ||
271                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
272
273         mount_client $MOUNT || error "(5) Fail to start client!"
274
275         do_facet $SINGLEMDS \
276                 $LCTL set_param -n osd-ldiskfs.${MDT_DEV}.auto_scrub 1
277         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
278         do_facet $SINGLEMDS $LCTL set_param fail_val=3
279         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
280         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
281                 error "(6) File diff failed unexpected!"
282
283         umount_client $MOUNT || error "(7) Fail to stop client!"
284
285         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
286         [ "$STATUS" == "scanning" ] ||
287                 error "(8) Expect 'scanning', but got '$STATUS'"
288
289         #define OBD_FAIL_OSD_SCRUB_CRASH         0x191
290         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80000191
291         sleep 4
292         echo "stop $SINGLEMDS"
293         stop $SINGLEMDS > /dev/null || error "(9) Fail to stop MDS!"
294
295         echo "start $SINGLEMDS with disabling OI scrub"
296         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
297                 error "(10) Fail to start MDS!"
298
299         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
300         [ "$STATUS" == "crashed" ] ||
301                 error "(11) Expect 'crashed', but got '$STATUS'"
302
303         echo "stop $SINGLEMDS"
304         stop $SINGLEMDS > /dev/null || error "(12) Fail to stop MDS!"
305
306         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
307         do_facet $SINGLEMDS $LCTL set_param fail_val=3
308         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
309         echo "start $SINGLEMDS without disabling OI scrub"
310         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
311                 error "(13) Fail to start MDS!"
312
313         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
314         [ "$STATUS" == "scanning" ] ||
315                 error "(14) Expect 'scanning', but got '$STATUS'"
316
317         #define OBD_FAIL_OSD_SCRUB_FATAL         0x192
318         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80000192
319         sleep 4
320         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
321         [ "$STATUS" == "failed" ] ||
322                 error "(15) Expect 'failed', but got '$STATUS'"
323
324         mount_client $MOUNT || error "(16) Fail to start client!"
325
326         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
327         do_facet $SINGLEMDS $LCTL set_param fail_val=3
328         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
329         stat $DIR/$tdir/${tfile}1000 ||
330                 error "(17) Fail to stat $DIR/$tdir/${tfile}1000!"
331
332         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
333         [ "$STATUS" == "scanning" ] ||
334                 error "(18) Expect 'scanning', but got '$STATUS'"
335
336         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
337         do_facet $SINGLEMDS $LCTL set_param fail_val=0
338         sleep 5
339         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
340         [ "$STATUS" == "completed" ] ||
341                 error "(19) Expect 'completed', but got '$STATUS'"
342
343         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
344         [ -z "$FLAGS" ] || error "(20) Expect empty flags, but got '$FLAGS'"
345 }
346 run_test 5 "OI scrub state machine"
347
348 test_6() {
349         scrub_prep 1000
350         mds_backup_restore || error "(1) Fail to backup/restore!"
351
352         echo "start $SINGLEMDS with disabling OI scrub"
353         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
354                 error "(2) Fail to start MDS!"
355
356         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
357         [ "$STATUS" == "init" ] ||
358                 error "(3) Expect 'init', but got '$STATUS'"
359
360         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
361         [ "$FLAGS" == "inconsistent" ] ||
362                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
363
364         mount_client $MOUNT || error "(5) Fail to start client!"
365
366         do_facet $SINGLEMDS \
367                 $LCTL set_param -n osd-ldiskfs.${MDT_DEV}.auto_scrub 1
368         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
369         do_facet $SINGLEMDS $LCTL set_param fail_val=3
370         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
371         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
372                 error "(6) File diff failed unexpected!"
373
374         # Sleep 5 sec to guarantee at least one object processed by OI scrub
375         sleep 5
376         # Fail the OI scrub to guarantee there is at least one checkpoint
377         #define OBD_FAIL_OSD_SCRUB_FATAL         0x192
378         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80000192
379         sleep 4
380         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
381         [ "$STATUS" == "failed" ] ||
382                 error "(7) Expect 'failed', but got '$STATUS'"
383
384         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
385         do_facet $SINGLEMDS $LCTL set_param fail_val=3
386         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
387         # stat will re-trigger OI scrub
388         stat $DIR/$tdir/${tfile}800 ||
389                 error "(8) Fail to stat $DIR/$tdir/${tfile}800!"
390
391         umount_client $MOUNT || error "(9) Fail to stop client!"
392
393         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
394         [ "$STATUS" == "scanning" ] ||
395                 error "(10) Expect 'scanning', but got '$STATUS'"
396
397         #define OBD_FAIL_OSD_SCRUB_CRASH         0x191
398         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80000191
399         sleep 4
400         local POSITION0=$($SHOW_SCRUB |
401                         awk '/^last_checkpoint_position/ {print $2}')
402         POSITION0=$((POSITION0 + 1))
403
404         echo "stop $SINGLEMDS"
405         stop $SINGLEMDS > /dev/null || error "(11) Fail to stop MDS!"
406
407         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
408         do_facet $SINGLEMDS $LCTL set_param fail_val=3
409         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
410         echo "start $SINGLEMDS without disabling OI scrub"
411         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
412                 error "(12) Fail to start MDS!"
413
414         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
415         [ "$STATUS" == "scanning" ] ||
416                 error "(13) Expect 'scanning', but got '$STATUS'"
417
418         local POSITION1=$($SHOW_SCRUB |
419                         awk '/^latest_start_position/ {print $2}')
420         [ $POSITION0 -eq $POSITION1 ] ||
421                 error "(14) Expect position: $POSITION0, but got $POSITION1"
422
423         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
424         do_facet $SINGLEMDS $LCTL set_param fail_val=0
425         sleep 5
426         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
427         [ "$STATUS" == "completed" ] ||
428                 error "(15) Expect 'completed', but got '$STATUS'"
429
430         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
431         [ -z "$FLAGS" ] || error "(16) Expect empty flags, but got '$FLAGS'"
432 }
433 run_test 6 "OI scrub resumes from last checkpoint"
434
435 test_7() {
436         scrub_prep 500
437         mds_backup_restore || error "(1) Fail to backup/restore!"
438
439         echo "start $SINGLEMDS with disabling OI scrub"
440         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
441                 error "(2) Fail to start MDS!"
442
443         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
444         [ "$STATUS" == "init" ] ||
445                 error "(3) Expect 'init', but got '$STATUS'"
446
447         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
448         [ "$FLAGS" == "inconsistent" ] ||
449                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
450
451         mount_client $MOUNT || error "(5) Fail to start client!"
452
453         do_facet $SINGLEMDS \
454                 $LCTL set_param -n osd-ldiskfs.${MDT_DEV}.auto_scrub 1
455         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
456         do_facet $SINGLEMDS $LCTL set_param fail_val=3
457         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
458         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
459                 error "(6) File diff failed unexpected!"
460
461         stat $DIR/$tdir/${tfile}300 ||
462                 error "(7) Fail to stat $DIR/$tdir/${tfile}300!"
463
464         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
465         [ "$STATUS" == "scanning" ] ||
466                 error "(8) Expect 'scanning', but got '$STATUS'"
467
468         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
469         [ "$FLAGS" == "inconsistent,auto" ] ||
470                 error "(9) Expect 'inconsistent,auto', but got '$FLAGS'"
471
472         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
473         do_facet $SINGLEMDS $LCTL set_param fail_val=0
474         sleep 5
475         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
476         [ "$STATUS" == "completed" ] ||
477                 error "(10) Expect 'completed', but got '$STATUS'"
478
479         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
480         [ -z "$FLAGS" ] || error "(11) Expect empty flags, but got '$FLAGS'"
481 }
482 run_test 7 "System is available during OI scrub scanning"
483
484 test_8() {
485         scrub_prep 0
486         mds_backup_restore || error "(1) Fail to backup/restore!"
487
488         echo "start $SINGLEMDS with disabling OI scrub"
489         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
490                 error "(2) Fail to start MDS!"
491
492         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
493         [ "$STATUS" == "init" ] ||
494                 error "(3) Expect 'init', but got '$STATUS'"
495
496         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
497         [ "$FLAGS" == "inconsistent" ] ||
498                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
499
500         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
501         do_facet $SINGLEMDS $LCTL set_param fail_val=1
502         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
503         $START_SCRUB || error "(5) Fail to start OI scrub!"
504
505         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
506         [ "$STATUS" == "scanning" ] ||
507                 error "(6) Expect 'scanning', but got '$STATUS'"
508
509         $STOP_SCRUB || error "(7) Fail to stop OI scrub!"
510
511         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
512         [ "$STATUS" == "stopped" ] ||
513                 error "(8) Expect 'stopped', but got '$STATUS'"
514
515         $START_SCRUB || error "(9) Fail to start OI scrub!"
516
517         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
518         [ "$STATUS" == "scanning" ] ||
519                 error "(10) Expect 'scanning', but got '$STATUS'"
520
521         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
522         do_facet $SINGLEMDS $LCTL set_param fail_val=0
523         sleep 5
524         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
525         [ "$STATUS" == "completed" ] ||
526                 error "(11) Expect 'completed', but got '$STATUS'"
527
528         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
529         [ -z "$FLAGS" ] || error "(12) Expect empty flags, but got '$FLAGS'"
530 }
531 run_test 8 "Control OI scrub manually"
532
533 test_9() {
534         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
535                 skip "Testing on UP system, the speed may be inaccurate."
536                 return 0
537         fi
538
539         scrub_prep 8000
540         mds_backup_restore || error "(1) Fail to backup/restore!"
541
542         echo "start $SINGLEMDS with disabling OI scrub"
543         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
544                 error "(2) Fail to start MDS!"
545
546         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
547         [ "$STATUS" == "init" ] ||
548                 error "(3) Expect 'init', but got '$STATUS'"
549
550         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
551         [ "$FLAGS" == "inconsistent" ] ||
552                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
553
554         local BASE_SPEED1=100
555         local RUN_TIME1=10
556         # OI scrub should run with full speed under inconsistent case
557         $START_SCRUB -s $BASE_SPEED1 || error "(5) Fail to start OI scrub!"
558
559         sleep $RUN_TIME1
560         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
561         [ "$STATUS" == "completed" ] ||
562                 error "(6) Expect 'completed', but got '$STATUS'"
563
564         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
565         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
566
567         # OI scrub should run with limited speed under non-inconsistent case
568         $START_SCRUB -s $BASE_SPEED1 -r || error "(8) Fail to start OI scrub!"
569
570         sleep $RUN_TIME1
571         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
572         [ "$STATUS" == "scanning" ] ||
573                 error "(9) Expect 'scanning', but got '$STATUS'"
574
575         local SPEED=$($SHOW_SCRUB | awk '/^average_speed/ { print $2 }')
576
577         # Do NOT ignore that there are 1024 pre-fetched items. And there
578         # may be time error, normally it should be less than 2 seconds.
579         # We allow another 20% schedule error.
580         local PRE_FETCHED=1024
581         local TIME_DIFF=2
582         # MAX_MARGIN = 1.2 = 12 / 10
583         local MAX_SPEED=$(((PRE_FETCHED + BASE_SPEED1 * \
584                             (RUN_TIME1 + TIME_DIFF)) / RUN_TIME1 * 12 / 10))
585         [ $SPEED -lt $MAX_SPEED ] ||
586                 error "(10) Got speed $SPEED, expected less than $MAX_SPEED"
587
588         # adjust speed limit
589         local BASE_SPEED2=300
590         local RUN_TIME2=10
591         do_facet $SINGLEMDS \
592                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
593         sleep $RUN_TIME2
594
595         SPEED=$($SHOW_SCRUB | awk '/^average_speed/ { print $2 }')
596         # MIN_MARGIN = 0.8 = 8 / 10
597         local MIN_SPEED=$(((PRE_FETCHED + \
598                             BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
599                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
600                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
601         [ $SPEED -gt $MIN_SPEED ] ||
602                 error "(11) Got speed $SPEED, expected more than $MIN_SPEED"
603
604         # MAX_MARGIN = 1.2 = 12 / 10
605         MAX_SPEED=$(((PRE_FETCHED + \
606                       BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
607                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
608                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
609         [ $SPEED -lt $MAX_SPEED ] ||
610                 error "(12) Got speed $SPEED, expected less than $MAX_SPEED"
611
612         do_facet $SINGLEMDS \
613                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
614         sleep 6
615         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
616         [ "$STATUS" == "completed" ] ||
617                 error "(13) Expect 'completed', but got '$STATUS'"
618 }
619 run_test 9 "OI scrub speed control"
620
621 test_10a() {
622         scrub_prep 0
623         mds_backup_restore || error "(1) Fail to backup/restore!"
624
625         echo "start $SINGLEMDS with disabling OI scrub"
626         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
627                 error "(2) Fail to start MDS!"
628
629         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
630         [ "$STATUS" == "init" ] ||
631                 error "(3) Expect 'init', but got '$STATUS'"
632
633         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
634         [ "$FLAGS" == "inconsistent" ] ||
635                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
636
637         mount_client $MOUNT || error "(5) Fail to start client!"
638
639         do_facet $SINGLEMDS \
640                 $LCTL set_param -n osd-ldiskfs.${MDT_DEV}.auto_scrub 1
641         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
642         do_facet $SINGLEMDS $LCTL set_param fail_val=1
643         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
644         diff -q $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
645                 error "(6) File diff failed unexpected!"
646
647         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
648         [ "$STATUS" == "scanning" ] ||
649                 error "(7) Expect 'scanning', but got '$STATUS'"
650
651         umount_client $MOUNT || error "(8) Fail to stop client!"
652
653         echo "stop $SINGLEMDS"
654         stop $SINGLEMDS > /dev/null || error "(9) Fail to stop MDS!"
655
656         echo "start $SINGLEMDS with disabling OI scrub"
657         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
658                 error "(10) Fail to start MDS!"
659
660         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
661         [ "$STATUS" == "paused" ] ||
662                 error "(11) Expect 'paused', but got '$STATUS'"
663
664         echo "stop $SINGLEMDS"
665         stop $SINGLEMDS > /dev/null || error "(12) Fail to stop MDS!"
666
667         echo "start $SINGLEMDS without disabling OI scrub"
668         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
669                 error "(13) Fail to start MDS!"
670
671         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
672         [ "$STATUS" == "scanning" ] ||
673                 error "(14) Expect 'scanning', but got '$STATUS'"
674
675         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
676         do_facet $SINGLEMDS $LCTL set_param fail_val=0
677         sleep 5
678         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
679         [ "$STATUS" == "completed" ] ||
680                 error "(15) Expect 'completed', but got '$STATUS'"
681
682         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
683         [ -z "$FLAGS" ] || error "(16) Expect empty flags, but got '$FLAGS'"
684 }
685 run_test 10a "non-stopped OI scrub should auto restarts after MDS remount (1)"
686
687 # test_10b is obsolete, it will be coverded by related sanity-lfsck tests.
688 test_10b() {
689         scrub_prep 0
690         mds_backup_restore || error "(1) Fail to backup/restore!"
691
692         echo "start $SINGLEMDS with disabling OI scrub"
693         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
694                 error "(2) Fail to start MDS!"
695
696         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
697         [ "$STATUS" == "init" ] ||
698                 error "(3) Expect 'init', but got '$STATUS'"
699
700         local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
701         [ "$FLAGS" == "inconsistent" ] ||
702                 error "(4) Expect 'inconsistent', but got '$FLAGS'"
703
704         #define OBD_FAIL_OSD_SCRUB_DELAY         0x190
705         do_facet $SINGLEMDS $LCTL set_param fail_val=3
706         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x190
707
708         $START_SCRUB || error "(5) Fail to start OI scrub!"
709
710         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
711         [ "$STATUS" == "scanning" ] ||
712                 error "(6) Expect 'scanning', but got '$STATUS'"
713
714         echo "stop $SINGLEMDS"
715         stop $SINGLEMDS > /dev/null || error "(7) Fail to stop MDS!"
716
717         echo "start $SINGLEMDS with disabling OI scrub"
718         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
719                 error "(8) Fail to start MDS!"
720
721         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
722         [ "$STATUS" == "paused" ] ||
723                 error "(9) Expect 'paused', but got '$STATUS'"
724
725         echo "stop $SINGLEMDS"
726         stop $SINGLEMDS > /dev/null || error "(10) Fail to stop MDS!"
727
728         echo "start $SINGLEMDS without disabling OI scrub"
729         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
730                 error "(11) Fail to start MDS!"
731
732         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
733         [ "$STATUS" == "scanning" ] ||
734                 error "(12) Expect 'scanning', but got '$STATUS'"
735
736         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
737         do_facet $SINGLEMDS $LCTL set_param fail_val=0
738         sleep 5
739         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
740         [ "$STATUS" == "completed" ] ||
741                 error "(13) Expect 'completed', but got '$STATUS'"
742
743         FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
744         [ -z "$FLAGS" ] || error "(14) Expect empty flags, but got '$FLAGS'"
745 }
746 #run_test 10b "non-stopped OI scrub should auto restarts after MDS remount (2)"
747
748 test_11() {
749         echo "stopall"
750         stopall > /dev/null
751         echo "formatall"
752         formatall > /dev/null
753         echo "setupall"
754         setupall > /dev/null
755
756         local CREATED=100
757         local tname=`date +%s`
758         rm -rf $MOUNT/$tname > /dev/null
759         mkdir $MOUNT/$tname || error "(1) Fail to mkdir $MOUNT/$tname"
760
761         createmany -o $MOUNT/$tname/f $CREATED || error "(2) Fail to create!"
762
763         # reset OI scrub start point by force
764         $START_SCRUB -r || error "(3) Fail to start OI scrub!"
765         sleep 3
766         local STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
767         [ "$STATUS" == "completed" ] ||
768                 error "(4) Expect 'completed', but got '$STATUS'"
769
770         # OI scrub should skip the new created objects for the first accessing
771         local SKIPPED=$($SHOW_SCRUB | awk '/^noscrub/ { print $2 }')
772         # notice we're creating a new llog for every OST on every startup
773         # new features can make this even less stable, so we only check
774         # that the number of skipped files is less than 2x the number of files
775         local MAXIMUM=$((CREATED * 2))
776         local MINIMUM=$((CREATED + 1)) # files + directory
777         [ $SKIPPED -ge $MAXIMUM -o $SKIPPED -lt $MINIMUM ] &&
778         error "(5) Expect [ $MINIMUM , $MAXIMUM ) objects skipped, got $SKIPPED"
779
780         # reset OI scrub start point by force
781         $START_SCRUB -r || error "(6) Fail to start OI scrub!"
782         sleep 3
783         STATUS=$($SHOW_SCRUB | awk '/^status/ { print $2 }')
784         [ "$STATUS" == "completed" ] ||
785                 error "(7) Expect 'completed', but got '$STATUS'"
786
787         # OI scrub should skip the new created object only once
788         SKIPPED=$($SHOW_SCRUB | awk '/^noscrub/ { print $2 }')
789         [ $SKIPPED -eq 0 ] ||
790                 error "(8) Expect 0 objects skipped, but got $SKIPPED"
791
792         rm -rf $MOUNT/$tname > /dev/null
793 }
794 run_test 11 "OI scrub skips the new created objects only once"
795
796 # restore MDS/OST size
797 MDSSIZE=${SAVED_MDSSIZE}
798 OSTSIZE=${SAVED_OSTSIZE}
799
800 # cleanup the system at last
801 formatall
802
803 complete $SECONDS
804 exit_status