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