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