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