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