Whamcloud - gitweb
LU-3950 lfsck: control LFSCK on all devices via single command
[fs/lustre-release.git] / lustre / tests / sanity-lfsck.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_LFSCK_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 # remove the check when ZFS backend iteration is ready
21 [ $(facet_fstype $SINGLEMDS) != "ldiskfs" ] &&
22         skip "test LFSCK only for ldiskfs" && exit 0
23 [ $(facet_fstype ost1) != ldiskfs ] &&
24         skip "test LFSCK only for ldiskfs" && exit 0
25
26 require_dsh_mds || exit 0
27
28 MCREATE=${MCREATE:-mcreate}
29 SAVED_MDSSIZE=${MDSSIZE}
30 SAVED_OSTSIZE=${OSTSIZE}
31 # use small MDS + OST size to speed formatting time
32 # do not use too small MDSSIZE/OSTSIZE, which affect the default journal size
33 MDSSIZE=100000
34 OSTSIZE=100000
35
36 check_and_setup_lustre
37
38 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.60) ]] &&
39         skip "Need MDS version at least 2.3.60" && check_and_cleanup_lustre &&
40         exit 0
41
42 [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.4.90) ]] &&
43         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 2c"
44
45 [[ $(lustre_version_code ost1) -lt $(version_code 2.5.50) ]] &&
46         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 11 12"
47
48 build_test_filter
49
50 $LCTL set_param debug=+lfsck > /dev/null || true
51
52 MDT_DEV="${FSNAME}-MDT0000"
53 OST_DEV="${FSNAME}-OST0000"
54 MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
55 START_NAMESPACE="do_facet $SINGLEMDS \
56                 $LCTL lfsck_start -M ${MDT_DEV} -t namespace"
57 START_LAYOUT_ON_OST="do_facet ost1 $LCTL lfsck_start -M ${OST_DEV} -t layout"
58 STOP_LFSCK="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
59 SHOW_NAMESPACE="do_facet $SINGLEMDS \
60                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace"
61 SHOW_LAYOUT_ON_OST="do_facet ost1 \
62                 $LCTL get_param -n obdfilter.${OST_DEV}.lfsck_layout"
63 MOUNT_OPTS_SCRUB="-o user_xattr"
64 MOUNT_OPTS_NOSCRUB="-o user_xattr,noscrub"
65
66 lfsck_prep() {
67         local ndirs=$1
68         local nfiles=$2
69         local igif=$3
70
71         echo "formatall"
72         formatall > /dev/null
73
74         echo "setupall"
75         setupall > /dev/null
76
77         if [ ! -z $igif ]; then
78                 #define OBD_FAIL_FID_IGIF       0x1504
79                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
80         fi
81
82         echo "preparing... ${nfiles} * ${ndirs} files will be created."
83         mkdir -p $DIR/$tdir
84         cp $LUSTRE/tests/*.sh $DIR/
85         for ((i = 0; i < ${ndirs}; i++)); do
86                 mkdir $DIR/$tdir/d${i}
87                 touch $DIR/$tdir/f${i}
88                 for ((j = 0; j < ${nfiles}; j++)); do
89                         touch $DIR/$tdir/d${i}/f${j}
90                 done
91                 mkdir $DIR/$tdir/e${i}
92         done
93
94         if [ ! -z $igif ]; then
95                 touch $DIR/$tdir/dummy
96                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0
97         fi
98
99         echo "prepared."
100         cleanup_mount $MOUNT > /dev/null || error "Fail to stop client!"
101         echo "stop $SINGLEMDS"
102         stop $SINGLEMDS > /dev/null || error "Fail to stop MDS!"
103 }
104
105 test_0() {
106         lfsck_prep 10 10
107         echo "start $SINGLEMDS"
108         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
109                 error "(1) Fail to start MDS!"
110
111         #define OBD_FAIL_LFSCK_DELAY1           0x1600
112         do_facet $SINGLEMDS $LCTL set_param fail_val=3
113         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
114         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
115
116         $SHOW_NAMESPACE || error "Fail to monitor LFSCK (3)"
117
118         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
119         [ "$STATUS" == "scanning-phase1" ] ||
120                 error "(4) Expect 'scanning-phase1', but got '$STATUS'"
121
122         $STOP_LFSCK || error "(5) Fail to stop LFSCK!"
123
124         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
125         [ "$STATUS" == "stopped" ] ||
126                 error "(6) Expect 'stopped', but got '$STATUS'"
127
128         $START_NAMESPACE || error "(7) Fail to start LFSCK for namespace!"
129
130         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
131         [ "$STATUS" == "scanning-phase1" ] ||
132                 error "(8) Expect 'scanning-phase1', but got '$STATUS'"
133
134         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
135         do_facet $SINGLEMDS $LCTL set_param fail_val=0
136         sleep 3
137         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
138         [ "$STATUS" == "completed" ] ||
139                 error "(9) Expect 'completed', but got '$STATUS'"
140
141         local repaired=$($SHOW_NAMESPACE |
142                          awk '/^updated_phase1/ { print $2 }')
143         [ $repaired -eq 0 ] ||
144                 error "(10) Expect nothing to be repaired, but got: $repaired"
145
146         local scanned1=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
147         $START_NAMESPACE -r || error "(11) Fail to reset LFSCK!"
148         sleep 3
149
150         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
151         [ "$STATUS" == "completed" ] ||
152                 error "(12) Expect 'completed', but got '$STATUS'"
153
154         local scanned2=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
155         [ $((scanned1 + 1)) -eq $scanned2 ] ||
156                 error "(13) Expect success $((scanned1 + 1)), but got $scanned2"
157
158         echo "stopall, should NOT crash LU-3649"
159         stopall > /dev/null
160 }
161 run_test 0 "Control LFSCK manually"
162
163 test_1a() {
164         lfsck_prep 1 1
165         echo "start $SINGLEMDS"
166         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
167                 error "(1) Fail to start MDS!"
168
169         mount_client $MOUNT || error "(2) Fail to start client!"
170
171         #define OBD_FAIL_FID_INDIR      0x1501
172         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1501
173         touch $DIR/$tdir/dummy
174
175         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
176         umount_client $MOUNT
177         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
178
179         sleep 3
180         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
181         [ "$STATUS" == "completed" ] ||
182                 error "(4) Expect 'completed', but got '$STATUS'"
183
184         local repaired=$($SHOW_NAMESPACE |
185                          awk '/^updated_phase1/ { print $2 }')
186         [ $repaired -eq 1 ] ||
187                 error "(5) Fail to repair crashed FID-in-dirent: $repaired"
188
189         mount_client $MOUNT || error "(6) Fail to start client!"
190
191         #define OBD_FAIL_FID_LOOKUP     0x1505
192         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
193         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
194
195         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
196 }
197 run_test 1a "LFSCK can find out and repair crashed FID-in-dirent"
198
199 test_1b()
200 {
201         lfsck_prep 1 1
202         echo "start $SINGLEMDS"
203         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
204                 error "(1) Fail to start MDS!"
205
206         mount_client $MOUNT || error "(2) Fail to start client!"
207
208         #define OBD_FAIL_FID_INLMA      0x1502
209         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1502
210         touch $DIR/$tdir/dummy
211
212         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
213         umount_client $MOUNT
214         #define OBD_FAIL_FID_NOLMA      0x1506
215         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1506
216         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
217
218         sleep 3
219         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
220         [ "$STATUS" == "completed" ] ||
221                 error "(4) Expect 'completed', but got '$STATUS'"
222
223         local repaired=$($SHOW_NAMESPACE |
224                          awk '/^updated_phase1/ { print $2 }')
225         [ $repaired -eq 1 ] ||
226                 error "(5) Fail to repair missed FID-in-LMA: $repaired"
227
228         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
229         mount_client $MOUNT || error "(6) Fail to start client!"
230
231         #define OBD_FAIL_FID_LOOKUP     0x1505
232         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
233         stat $DIR/$tdir/dummy > /dev/null || error "(7) no FID-in-LMA."
234
235         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
236 }
237 run_test 1b "LFSCK can find out and repair missed FID-in-LMA"
238
239 test_2a() {
240         lfsck_prep 1 1
241         echo "start $SINGLEMDS"
242         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
243                 error "(1) Fail to start MDS!"
244
245         mount_client $MOUNT || error "(2) Fail to start client!"
246
247         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
248         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
249         touch $DIR/$tdir/dummy
250
251         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
252         umount_client $MOUNT
253         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
254
255         sleep 3
256         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
257         [ "$STATUS" == "completed" ] ||
258                 error "(4) Expect 'completed', but got '$STATUS'"
259
260         local repaired=$($SHOW_NAMESPACE |
261                          awk '/^updated_phase1/ { print $2 }')
262         [ $repaired -eq 1 ] ||
263                 error "(5) Fail to repair crashed linkEA: $repaired"
264
265         mount_client $MOUNT || error "(6) Fail to start client!"
266
267         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
268                 error "(7) Fail to stat $DIR/$tdir/dummy"
269
270         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
271         local dummyname=$($LFS fid2path $DIR $dummyfid)
272         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
273                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
274 }
275 run_test 2a "LFSCK can find out and repair crashed linkEA entry"
276
277 test_2b()
278 {
279         lfsck_prep 1 1
280         echo "start $SINGLEMDS"
281         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
282                 error "(1) Fail to start MDS!"
283
284         mount_client $MOUNT || error "(2) Fail to start client!"
285
286         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
287         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
288         touch $DIR/$tdir/dummy
289
290         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
291         umount_client $MOUNT
292         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
293
294         sleep 3
295         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
296         [ "$STATUS" == "completed" ] ||
297                 error "(4) Expect 'completed', but got '$STATUS'"
298
299         local repaired=$($SHOW_NAMESPACE |
300                          awk '/^updated_phase2/ { print $2 }')
301         [ $repaired -eq 1 ] ||
302                 error "(5) Fail to repair crashed linkEA: $repaired"
303
304         mount_client $MOUNT || error "(6) Fail to start client!"
305
306         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
307                 error "(7) Fail to stat $DIR/$tdir/dummy"
308
309         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
310         local dummyname=$($LFS fid2path $DIR $dummyfid)
311         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
312                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
313 }
314 run_test 2b "LFSCK can find out and remove invalid linkEA entry"
315
316 test_2c()
317 {
318         lfsck_prep 1 1
319         echo "start $SINGLEMDS"
320         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
321                 error "(1) Fail to start MDS!"
322
323         mount_client $MOUNT || error "(2) Fail to start client!"
324
325         #define OBD_FAIL_LFSCK_LINKEA_MORE2     0x1605
326         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1605
327         touch $DIR/$tdir/dummy
328
329         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
330         umount_client $MOUNT
331         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
332
333         sleep 3
334         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
335         [ "$STATUS" == "completed" ] ||
336                 error "(4) Expect 'completed', but got '$STATUS'"
337
338         local repaired=$($SHOW_NAMESPACE |
339                          awk '/^updated_phase2/ { print $2 }')
340         [ $repaired -eq 1 ] ||
341                 error "(5) Fail to repair crashed linkEA: $repaired"
342
343         mount_client $MOUNT || error "(6) Fail to start client!"
344
345         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
346                 error "(7) Fail to stat $DIR/$tdir/dummy"
347
348         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
349         local dummyname=$($LFS fid2path $DIR $dummyfid)
350         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
351                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
352 }
353 run_test 2c "LFSCK can find out and remove repeated linkEA entry"
354
355 test_4()
356 {
357         lfsck_prep 3 3
358         mds_backup_restore $SINGLEMDS || error "(1) Fail to backup/restore!"
359         echo "start $SINGLEMDS with disabling OI scrub"
360         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
361                 error "(2) Fail to start MDS!"
362
363         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
364         [ "$STATUS" == "init" ] ||
365                 error "(3) Expect 'init', but got '$STATUS'"
366
367         #define OBD_FAIL_LFSCK_DELAY2           0x1601
368         do_facet $SINGLEMDS $LCTL set_param fail_val=1
369         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
370         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
371
372         sleep 5
373         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
374         [ "$STATUS" == "scanning-phase1" ] ||
375                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
376
377         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
378         [ "$FLAGS" == "inconsistent" ] ||
379                 error "(6) Expect 'inconsistent', but got '$FLAGS'"
380
381         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
382         do_facet $SINGLEMDS $LCTL set_param fail_val=0
383         sleep 3
384         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
385         [ "$STATUS" == "completed" ] ||
386                 error "(7) Expect 'completed', but got '$STATUS'"
387
388         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
389         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
390
391         local repaired=$($SHOW_NAMESPACE |
392                          awk '/^updated_phase1/ { print $2 }')
393         [ $repaired -ge 9 ] ||
394                 error "(9) Fail to repair crashed linkEA: $repaired"
395
396         mount_client $MOUNT || error "(10) Fail to start client!"
397
398         #define OBD_FAIL_FID_LOOKUP     0x1505
399         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
400         ls $DIR/$tdir/ > /dev/null || error "(11) no FID-in-dirent."
401
402         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
403 }
404 run_test 4 "FID-in-dirent can be rebuilt after MDT file-level backup/restore"
405
406 test_5()
407 {
408         lfsck_prep 1 1 1
409         mds_backup_restore $SINGLEMDS 1 || error "(1) Fail to backup/restore!"
410         echo "start $SINGLEMDS with disabling OI scrub"
411         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
412                 error "(2) Fail to start MDS!"
413
414         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
415         [ "$STATUS" == "init" ] ||
416                 error "(3) Expect 'init', but got '$STATUS'"
417
418         #define OBD_FAIL_LFSCK_DELAY2           0x1601
419         do_facet $SINGLEMDS $LCTL set_param fail_val=1
420         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
421         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
422
423         sleep 5
424         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
425         [ "$STATUS" == "scanning-phase1" ] ||
426                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
427
428         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
429         [ "$FLAGS" == "inconsistent,upgrade" ] ||
430                 error "(6) Expect 'inconsistent,upgrade', but got '$FLAGS'"
431
432         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
433         do_facet $SINGLEMDS $LCTL set_param fail_val=0
434         sleep 3
435         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
436         [ "$STATUS" == "completed" ] ||
437                 error "(7) Expect 'completed', but got '$STATUS'"
438
439         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
440         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
441
442         local repaired=$($SHOW_NAMESPACE |
443                          awk '/^updated_phase1/ { print $2 }')
444         [ $repaired -ge 2 ] ||
445                 error "(9) Fail to repair crashed linkEA: $repaired"
446
447         mount_client $MOUNT || error "(10) Fail to start client!"
448
449         #define OBD_FAIL_FID_LOOKUP     0x1505
450         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
451         stat $DIR/$tdir/dummy > /dev/null || error "(11) no FID-in-LMA."
452
453         ls $DIR/$tdir/ > /dev/null || error "(12) no FID-in-dirent."
454
455         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
456         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
457         local dummyname=$($LFS fid2path $DIR $dummyfid)
458         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
459                 error "(13) Fail to generate linkEA: $dummyfid $dummyname"
460 }
461 run_test 5 "LFSCK can handle IFIG object upgrading"
462
463 test_6a() {
464         lfsck_prep 10 10
465         echo "start $SINGLEMDS"
466         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
467                 error "(1) Fail to start MDS!"
468
469         #define OBD_FAIL_LFSCK_DELAY1           0x1600
470         do_facet $SINGLEMDS $LCTL set_param fail_val=1
471         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
472         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
473
474         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
475         [ "$STATUS" == "scanning-phase1" ] ||
476                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
477
478         # Sleep 3 sec to guarantee at least one object processed by LFSCK
479         sleep 3
480         # Fail the LFSCK to guarantee there is at least one checkpoint
481         #define OBD_FAIL_LFSCK_FATAL1           0x1608
482         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001608
483         sleep 3
484         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
485         [ "$STATUS" == "failed" ] ||
486                 error "(4) Expect 'failed', but got '$STATUS'"
487
488         local POSITION0=$($SHOW_NAMESPACE |
489                           awk '/^last_checkpoint_position/ { print $2 }' |
490                           tr -d ',')
491
492         #define OBD_FAIL_LFSCK_DELAY1           0x1600
493         do_facet $SINGLEMDS $LCTL set_param fail_val=1
494         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
495         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
496
497         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
498         [ "$STATUS" == "scanning-phase1" ] ||
499                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
500
501         local POSITION1=$($SHOW_NAMESPACE |
502                           awk '/^latest_start_position/ { print $2 }' |
503                           tr -d ',')
504         [ $POSITION0 -lt $POSITION1 ] ||
505                 error "(7) Expect larger than: $POSITION0, but got $POSITION1"
506
507         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
508         do_facet $SINGLEMDS $LCTL set_param fail_val=0
509         sleep 3
510         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
511         [ "$STATUS" == "completed" ] ||
512                 error "(8) Expect 'completed', but got '$STATUS'"
513 }
514 run_test 6a "LFSCK resumes from last checkpoint (1)"
515
516 test_6b() {
517         lfsck_prep 10 10
518         echo "start $SINGLEMDS"
519         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
520                 error "(1) Fail to start MDS!"
521
522         #define OBD_FAIL_LFSCK_DELAY2           0x1601
523         do_facet $SINGLEMDS $LCTL set_param fail_val=1
524         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
525         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
526
527         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
528         [ "$STATUS" == "scanning-phase1" ] ||
529                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
530
531         # Sleep 3 sec to guarantee at least one object processed by LFSCK
532         sleep 3
533         # Fail the LFSCK to guarantee there is at least one checkpoint
534         #define OBD_FAIL_LFSCK_FATAL2           0x1609
535         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
536         sleep 3
537         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
538         [ "$STATUS" == "failed" ] ||
539                 error "(4) Expect 'failed', but got '$STATUS'"
540
541         local POSITION0=$($SHOW_NAMESPACE |
542                           awk '/^last_checkpoint_position/ { print $4 }')
543
544         #define OBD_FAIL_LFSCK_DELAY2           0x1601
545         do_facet $SINGLEMDS $LCTL set_param fail_val=1
546         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
547         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
548
549         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
550         [ "$STATUS" == "scanning-phase1" ] ||
551                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
552
553         local POSITION1=$($SHOW_NAMESPACE |
554                           awk '/^latest_start_position/ { print $4 }')
555         if [ $POSITION0 -gt $POSITION1 ]; then
556                 [ $POSITION1 -eq 0 -a $POSITION0 -eq $((POSITION1 + 1)) ] ||
557                 error "(7) Expect larger than: $POSITION0, but got $POSITION1"
558         fi
559
560         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
561         do_facet $SINGLEMDS $LCTL set_param fail_val=0
562         sleep 3
563         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
564         [ "$STATUS" == "completed" ] ||
565                 error "(8) Expect 'completed', but got '$STATUS'"
566 }
567 run_test 6b "LFSCK resumes from last checkpoint (2)"
568
569 test_7a()
570 {
571         lfsck_prep 10 10
572         echo "start $SINGLEMDS"
573         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
574                 error "(1) Fail to start MDS!"
575
576         #define OBD_FAIL_LFSCK_DELAY2           0x1601
577         do_facet $SINGLEMDS $LCTL set_param fail_val=1
578         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
579         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
580
581         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
582         [ "$STATUS" == "scanning-phase1" ] ||
583                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
584
585         # Sleep 3 sec to guarantee at least one object processed by LFSCK
586         sleep 3
587         echo "stop $SINGLEMDS"
588         stop $SINGLEMDS > /dev/null || error "(4) Fail to stop MDS!"
589
590         echo "start $SINGLEMDS"
591         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
592                 error "(5) Fail to start MDS!"
593
594         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
595         [ "$STATUS" == "scanning-phase1" ] ||
596                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
597
598         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
599         do_facet $SINGLEMDS $LCTL set_param fail_val=0
600         sleep 3
601         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
602         [ "$STATUS" == "completed" ] ||
603                 error "(7) Expect 'completed', but got '$STATUS'"
604 }
605 run_test 7a "non-stopped LFSCK should auto restarts after MDS remount (1)"
606
607 test_7b()
608 {
609         lfsck_prep 2 2
610         echo "start $SINGLEMDS"
611         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
612                 error "(1) Fail to start MDS!"
613
614         mount_client $MOUNT || error "(2) Fail to start client!"
615
616         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
617         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
618         for ((i = 0; i < 20; i++)); do
619                 touch $DIR/$tdir/dummy${i}
620         done
621
622         #define OBD_FAIL_LFSCK_DELAY3           0x1602
623         do_facet $SINGLEMDS $LCTL set_param fail_val=1
624         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1602
625         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
626
627         sleep 3
628         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
629         [ "$STATUS" == "scanning-phase2" ] ||
630                 error "(4) Expect 'scanning-phase2', but got '$STATUS'"
631
632         echo "stop $SINGLEMDS"
633         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop MDS!"
634
635         echo "start $SINGLEMDS"
636         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
637                 error "(6) Fail to start MDS!"
638
639         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
640         [ "$STATUS" == "scanning-phase2" ] ||
641                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
642
643         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
644         do_facet $SINGLEMDS $LCTL set_param fail_val=0
645         sleep 3
646         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
647         [ "$STATUS" == "completed" ] ||
648                 error "(8) Expect 'completed', but got '$STATUS'"
649 }
650 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
651
652 test_8()
653 {
654         lfsck_prep 20 20
655         echo "start $SINGLEMDS"
656         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
657                 error "(1) Fail to start MDS!"
658
659         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
660         [ "$STATUS" == "init" ] ||
661                 error "(2) Expect 'init', but got '$STATUS'"
662
663         mount_client $MOUNT || error "(3) Fail to start client!"
664
665         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
666         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
667         mkdir $DIR/$tdir/crashed
668
669         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
670         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
671         for ((i = 0; i < 5; i++)); do
672                 touch $DIR/$tdir/dummy${i}
673         done
674
675         #define OBD_FAIL_LFSCK_DELAY2           0x1601
676         do_facet $SINGLEMDS $LCTL set_param fail_val=2
677         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
678         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
679
680         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
681         [ "$STATUS" == "scanning-phase1" ] ||
682                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
683
684         $STOP_LFSCK || error "(6) Fail to stop LFSCK!"
685
686         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
687         [ "$STATUS" == "stopped" ] ||
688                 error "(7) Expect 'stopped', but got '$STATUS'"
689
690         $START_NAMESPACE || error "(8) Fail to start LFSCK for namespace!"
691
692         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
693         [ "$STATUS" == "scanning-phase1" ] ||
694                 error "(9) Expect 'scanning-phase1', but got '$STATUS'"
695
696         #define OBD_FAIL_LFSCK_FATAL2           0x1609
697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
698         sleep 3
699         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
700         [ "$STATUS" == "failed" ] ||
701                 error "(10) Expect 'failed', but got '$STATUS'"
702
703         #define OBD_FAIL_LFSCK_DELAY1           0x1600
704         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
705         $START_NAMESPACE || error "(11) Fail to start LFSCK for namespace!"
706
707         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
708         [ "$STATUS" == "scanning-phase1" ] ||
709                 error "(12) Expect 'scanning-phase1', but got '$STATUS'"
710
711         #define OBD_FAIL_LFSCK_CRASH            0x160a
712         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
713         sleep 5
714
715         echo "stop $SINGLEMDS"
716         stop $SINGLEMDS > /dev/null || error "(13) Fail to stop MDS!"
717
718         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
719         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
720
721         echo "start $SINGLEMDS"
722         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
723                 error "(14) Fail to start MDS!"
724
725         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
726         [ "$STATUS" == "crashed" ] ||
727                 error "(15) Expect 'crashed', but got '$STATUS'"
728
729         #define OBD_FAIL_LFSCK_DELAY2           0x1601
730         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
731         $START_NAMESPACE || error "(16) Fail to start LFSCK for namespace!"
732
733         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
734         [ "$STATUS" == "scanning-phase1" ] ||
735                 error "(17) Expect 'scanning-phase1', but got '$STATUS'"
736
737         echo "stop $SINGLEMDS"
738         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop MDS!"
739
740         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
741         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
742
743         echo "start $SINGLEMDS"
744         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
745                 error "(19) Fail to start MDS!"
746
747         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
748         [ "$STATUS" == "paused" ] ||
749                 error "(20) Expect 'paused', but got '$STATUS'"
750
751         #define OBD_FAIL_LFSCK_DELAY3           0x1602
752         do_facet $SINGLEMDS $LCTL set_param fail_val=2
753         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1602
754
755         $START_NAMESPACE || error "(21) Fail to start LFSCK for namespace!"
756         sleep 2
757         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
758         [ "$STATUS" == "scanning-phase2" ] ||
759                 error "(22) Expect 'scanning-phase2', but got '$STATUS'"
760
761         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
762         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
763                 error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
764
765         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
766         do_facet $SINGLEMDS $LCTL set_param fail_val=0
767         sleep 2
768         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
769         [ "$STATUS" == "completed" ] ||
770                 error "(24) Expect 'completed', but got '$STATUS'"
771
772         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
773         [ -z "$FLAGS" ] || error "(25) Expect empty flags, but got '$FLAGS'"
774
775 }
776 run_test 8 "LFSCK state machine"
777
778 test_9a() {
779         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
780                 skip "Testing on UP system, the speed may be inaccurate."
781                 return 0
782         fi
783
784         lfsck_prep 70 70
785         echo "start $SINGLEMDS"
786         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
787                 error "(1) Fail to start MDS!"
788
789         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
790         [ "$STATUS" == "init" ] ||
791                 error "(2) Expect 'init', but got '$STATUS'"
792
793         local BASE_SPEED1=100
794         local RUN_TIME1=10
795         $START_NAMESPACE -s $BASE_SPEED1 || error "(3) Fail to start LFSCK!"
796
797         sleep $RUN_TIME1
798         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
799         [ "$STATUS" == "scanning-phase1" ] ||
800                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
801
802         local SPEED=$($SHOW_NAMESPACE |
803                       awk '/^average_speed_phase1/ { print $2 }')
804
805         # There may be time error, normally it should be less than 2 seconds.
806         # We allow another 20% schedule error.
807         local TIME_DIFF=2
808         # MAX_MARGIN = 1.2 = 12 / 10
809         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
810                            RUN_TIME1 * 12 / 10))
811         [ $SPEED -lt $MAX_SPEED ] ||
812                 error "(4) Got speed $SPEED, expected less than $MAX_SPEED"
813
814         # adjust speed limit
815         local BASE_SPEED2=300
816         local RUN_TIME2=10
817         do_facet $SINGLEMDS \
818                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
819         sleep $RUN_TIME2
820
821         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase1/ { print $2 }')
822         # MIN_MARGIN = 0.8 = 8 / 10
823         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
824                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
825                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
826         [ $SPEED -gt $MIN_SPEED ] ||
827                 error "(5) Got speed $SPEED, expected more than $MIN_SPEED"
828
829         # MAX_MARGIN = 1.2 = 12 / 10
830         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
831                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
832                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
833         [ $SPEED -lt $MAX_SPEED ] ||
834                 error "(6) Got speed $SPEED, expected less than $MAX_SPEED"
835
836         do_facet $SINGLEMDS \
837                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
838         sleep 5
839         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
840         [ "$STATUS" == "completed" ] ||
841                 error "(7) Expect 'completed', but got '$STATUS'"
842 }
843 run_test 9a "LFSCK speed control (1)"
844
845 test_9b() {
846         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
847                 skip "Testing on UP system, the speed may be inaccurate."
848                 return 0
849         fi
850
851         lfsck_prep 0 0
852         echo "start $SINGLEMDS"
853         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
854                 error "(1) Fail to start MDS!"
855
856         mount_client $MOUNT || error "(2) Fail to start client!"
857
858         echo "Another preparing... 50 * 50 files (with error) will be created."
859         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
860         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
861         for ((i = 0; i < 50; i++)); do
862                 mkdir -p $DIR/$tdir/d${i}
863                 touch $DIR/$tdir/f${i}
864                 for ((j = 0; j < 50; j++)); do
865                         touch $DIR/$tdir/d${i}/f${j}
866                 done
867         done
868
869         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
870         [ "$STATUS" == "init" ] ||
871                 error "(3) Expect 'init', but got '$STATUS'"
872
873         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
874         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
875         $START_NAMESPACE || error "(4) Fail to start LFSCK!"
876
877         sleep 10
878         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
879         [ "$STATUS" == "stopped" ] ||
880                 error "(5) Expect 'stopped', but got '$STATUS'"
881
882         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
883
884         local BASE_SPEED1=50
885         local RUN_TIME1=10
886         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
887
888         sleep $RUN_TIME1
889         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
890         [ "$STATUS" == "scanning-phase2" ] ||
891                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
892
893         local SPEED=$($SHOW_NAMESPACE |
894                       awk '/^average_speed_phase2/ { print $2 }')
895         # There may be time error, normally it should be less than 2 seconds.
896         # We allow another 20% schedule error.
897         local TIME_DIFF=2
898         # MAX_MARGIN = 1.2 = 12 / 10
899         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
900                           RUN_TIME1 * 12 / 10))
901         [ $SPEED -lt $MAX_SPEED ] ||
902                 error "(8) Got speed $SPEED, expected less than $MAX_SPEED"
903
904         # adjust speed limit
905         local BASE_SPEED2=150
906         local RUN_TIME2=10
907         do_facet $SINGLEMDS \
908                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
909         sleep $RUN_TIME2
910
911         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
912         # MIN_MARGIN = 0.8 = 8 / 10
913         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
914                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
915                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
916         [ $SPEED -gt $MIN_SPEED ] ||
917                 error "(9) Got speed $SPEED, expected more than $MIN_SPEED"
918
919         # MAX_MARGIN = 1.2 = 12 / 10
920         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
921                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
922                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
923         [ $SPEED -lt $MAX_SPEED ] ||
924                 error "(10) Got speed $SPEED, expected less than $MAX_SPEED"
925
926         do_facet $SINGLEMDS \
927                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
928         sleep 5
929         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
930         [ "$STATUS" == "completed" ] ||
931                 error "(11) Expect 'completed', but got '$STATUS'"
932 }
933 run_test 9b "LFSCK speed control (2)"
934
935 test_10()
936 {
937         lfsck_prep 1 1
938         echo "start $SINGLEMDS"
939         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
940                 error "(1) Fail to start MDS!"
941
942         mount_client $MOUNT || error "(2) Fail to start client!"
943
944         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
945         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
946         for ((i = 0; i < 1000; i = $((i+2)))); do
947                 mkdir -p $DIR/$tdir/d${i}
948                 touch $DIR/$tdir/f${i}
949                 for ((j = 0; j < 5; j++)); do
950                         touch $DIR/$tdir/d${i}/f${j}
951                 done
952         done
953
954         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
955         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
956         for ((i = 1; i < 1000; i = $((i+2)))); do
957                 mkdir -p $DIR/$tdir/d${i}
958                 touch $DIR/$tdir/f${i}
959                 for ((j = 0; j < 5; j++)); do
960                         touch $DIR/$tdir/d${i}/f${j}
961                 done
962         done
963
964         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
965         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
966
967         umount_client $MOUNT
968         mount_client $MOUNT || error "(3) Fail to start client!"
969
970         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
971         [ "$STATUS" == "init" ] ||
972                 error "(4) Expect 'init', but got '$STATUS'"
973
974         $START_NAMESPACE -s 100 || error "(5) Fail to start LFSCK!"
975
976         sleep 10
977         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
978         [ "$STATUS" == "scanning-phase1" ] ||
979                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
980
981         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
982
983         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
984
985         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
986
987         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
988
989         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
990
991         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
992
993         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
994
995         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
996                 error "(14) Fail to softlink!"
997
998         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
999         [ "$STATUS" == "scanning-phase1" ] ||
1000                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
1001
1002         do_facet $SINGLEMDS \
1003                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
1004         umount_client $MOUNT
1005         sleep 10
1006         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1007         [ "$STATUS" == "completed" ] ||
1008                 error "(16) Expect 'completed', but got '$STATUS'"
1009 }
1010 run_test 10 "System is available during LFSCK scanning"
1011
1012 # remove LAST_ID
1013 ost_remove_lastid() {
1014         local ost=$1
1015         local idx=$2
1016         local rcmd="do_facet ost${ost}"
1017
1018         echo "remove LAST_ID on ost${ost}: idx=${idx}"
1019
1020         # step 1: local mount
1021         mount_fstype ost${ost} || return 1
1022         # step 2: remove the specified LAST_ID
1023         ${rcmd} rm -fv $(facet_mntpt ost${ost})/O/${idx}/LAST_ID
1024         # step 3: umount
1025         unmount_fstype ost${ost} || return 2
1026 }
1027
1028 test_11a() {
1029         echo "stopall"
1030         stopall > /dev/null
1031         echo "formatall"
1032         formatall > /dev/null
1033         echo "setupall"
1034         setupall > /dev/null
1035
1036         mkdir -p $DIR/$tdir
1037         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1038         createmany -o $DIR/$tdir/f 64
1039
1040         echo "stopall"
1041         stopall > /dev/null
1042
1043         ost_remove_lastid 1 0 || error "(1) Fail to remove LAST_ID"
1044
1045         echo "start ost1"
1046         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
1047                 error "(2) Fail to start ost1"
1048
1049         local STATUS=$($SHOW_LAYOUT_ON_OST | awk '/^status/ { print $2 }')
1050         [ "$STATUS" == "init" ] ||
1051                 error "(3) Expect 'init', but got '$STATUS'"
1052
1053         #define OBD_FAIL_LFSCK_DELAY4           0x160e
1054         do_facet ost1 $LCTL set_param fail_val=3
1055         do_facet ost1 $LCTL set_param fail_loc=0x160e
1056
1057         echo "trigger LFSCK for layout on ost1 to rebuild the LAST_ID(s)"
1058         $START_LAYOUT_ON_OST || error "(4) Fail to start LFSCK on OST!"
1059
1060         wait_update_facet ost1 "$LCTL get_param -n \
1061                 obdfilter.${OST_DEV}.lfsck_layout |
1062                 awk '/^flags/ { print \\\$2 }'" "crashed_lastid" 60 || {
1063                 $SHOW_LAYOUT_ON_OST
1064                 return 5
1065         }
1066
1067         do_facet ost1 $LCTL set_param fail_val=0
1068         do_facet ost1 $LCTL set_param fail_loc=0
1069
1070         wait_update_facet ost1 "$LCTL get_param -n \
1071                 obdfilter.${OST_DEV}.lfsck_layout |
1072                 awk '/^status/ { print \\\$2 }'" "completed" 3 || {
1073                 $SHOW_LAYOUT_ON_OST
1074                 return 6
1075         }
1076
1077         echo "the LAST_ID(s) should have been rebuilt"
1078         FLAGS=$($SHOW_LAYOUT_ON_OST | awk '/^flags/ { print $2 }')
1079         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
1080 }
1081 run_test 11a "LFSCK can rebuild lost last_id"
1082
1083 test_11b() {
1084         echo "stopall"
1085         stopall > /dev/null
1086         echo "formatall"
1087         formatall > /dev/null
1088         echo "setupall"
1089         setupall > /dev/null
1090
1091         mkdir -p $DIR/$tdir
1092         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1093
1094         echo "set fail_loc=0x160d to skip the updating LAST_ID on-disk"
1095         #define OBD_FAIL_LFSCK_SKIP_LASTID      0x160d
1096         do_facet ost1 $LCTL set_param fail_loc=0x160d
1097         createmany -o $DIR/$tdir/f 64
1098         local lastid1=$(do_facet ost1 "lctl get_param -n \
1099                 obdfilter.${ost1_svc}.last_id" | grep 0x100000000 |
1100                 awk -F: '{ print $2 }')
1101
1102         umount_client $MOUNT
1103         echo "stop ost1"
1104         stop ost1 || error "(1) Fail to stop ost1"
1105
1106         #define OBD_FAIL_OST_ENOSPC              0x215
1107         do_facet ost1 $LCTL set_param fail_loc=0x215
1108
1109         echo "start ost1"
1110         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1111                 error "(2) Fail to start ost1"
1112
1113         local STATUS=$($SHOW_LAYOUT_ON_OST | awk '/^status/ { print $2 }')
1114         [ "$STATUS" == "init" ] ||
1115                 error "(3) Expect 'init', but got '$STATUS'"
1116
1117         for ((i = 0; i < 60; i++)); do
1118                 lastid2=$(do_facet ost1 "lctl get_param -n \
1119                         obdfilter.${ost1_svc}.last_id" | grep 0x100000000 |
1120                         awk -F: '{ print $2 }')
1121                 [ ! -z $lastid2 ] && break;
1122                 sleep 1
1123         done
1124
1125         echo "the on-disk LAST_ID should be smaller than the expected one"
1126         [ $lastid1 -gt $lastid2 ] ||
1127                 error "(4) expect lastid1 [ $lastid1 ] > lastid2 [ $lastid2 ]"
1128
1129         echo "trigger LFSCK for layout on ost1 to rebuild the on-disk LAST_ID"
1130         $START_LAYOUT_ON_OST || error "(5) Fail to start LFSCK on OST!"
1131
1132         wait_update_facet ost1 "$LCTL get_param -n \
1133                 obdfilter.${OST_DEV}.lfsck_layout |
1134                 awk '/^status/ { print \\\$2 }'" "completed" 3 || {
1135                 $SHOW_LAYOUT_ON_OST
1136                 return 6
1137         }
1138
1139         echo "stop ost1"
1140         stop ost1 || error "(7) Fail to stop ost1"
1141
1142         echo "start ost1"
1143         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1144                 error "(8) Fail to start ost1"
1145
1146         echo "the on-disk LAST_ID should have been rebuilt"
1147         wait_update_facet ost1 "$LCTL get_param -n \
1148                 obdfilter.${ost1_svc}.last_id | grep 0x100000000 |
1149                 awk -F: '{ print \\\$2 }'" "$lastid1" 60 || {
1150                 $LCTL get_param -n obdfilter.${ost1_svc}.last_id
1151                 error "(9) expect lastid1 0x100000000:$lastid1"
1152         }
1153
1154         do_facet ost1 $LCTL set_param fail_loc=0
1155 }
1156 run_test 11b "LFSCK can rebuild crashed last_id"
1157
1158 test_12() {
1159         [ $MDSCOUNT -lt 2 ] &&
1160                 skip "We need at least 2 MDSes for test_12" && exit 0
1161
1162         echo "stopall"
1163         stopall > /dev/null
1164         echo "formatall"
1165         formatall > /dev/null
1166         echo "setupall"
1167         setupall > /dev/null
1168
1169         echo "All the LFSCK targets should be in 'init' status."
1170         for k in $(seq $MDSCOUNT); do
1171                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1172                                 mdd.$(facet_svc mds${k}).lfsck_layout |
1173                                 awk '/^status/ { print $2 }')
1174                 [ "$STATUS" == "init" ] ||
1175                         error "(1) MDS${k} Expect 'init', but got '$STATUS'"
1176
1177                 $LFS mkdir -i $((k - 1)) $DIR/${k}
1178                 createmany -o $DIR/${k}/f 100
1179         done
1180
1181         echo "Trigger LFSCK on all targets by single command (limited speed)."
1182         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1183                 -s 10 || error "(2) Fail to start LFSCK on all devices!"
1184
1185         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1186         for k in $(seq $MDSCOUNT); do
1187                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1188                                 mdd.$(facet_svc mds${k}).lfsck_layout |
1189                                 awk '/^status/ { print $2 }')
1190                 [ "$STATUS" == "scanning-phase1" ] ||
1191                 error "(3) MDS${k} Expect 'scanning-phase1', but got '$STATUS'"
1192         done
1193
1194         echo "Stop layout LFSCK on all targets by single lctl command."
1195         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1196                 error "(4) Fail to stop LFSCK on all devices!"
1197
1198         echo "All the LFSCK targets should be in 'stopped' status."
1199         for k in $(seq $MDSCOUNT); do
1200                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1201                                 mdd.$(facet_svc mds${k}).lfsck_layout |
1202                                 awk '/^status/ { print $2 }')
1203                 [ "$STATUS" == "stopped" ] ||
1204                         error "(5) MDS${k} Expect 'stopped', but got '$STATUS'"
1205         done
1206
1207         for k in $(seq $OSTCOUNT); do
1208                 local STATUS=$(do_facet ost${k} $LCTL get_param -n \
1209                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1210                                 awk '/^status/ { print $2 }')
1211                 [ "$STATUS" == "stopped" ] ||
1212                         error "(6) OST${k} Expect 'stopped', but got '$STATUS'"
1213         done
1214
1215         echo "Re-trigger LFSCK on all targets by single command (full speed)."
1216         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1217                 -s 0 || error "(7) Fail to start LFSCK on all devices!"
1218
1219         echo "All the LFSCK targets should be in 'completed' status."
1220         for k in $(seq $MDSCOUNT); do
1221                 # The LFSCK status query internal is 30 seconds. For the case
1222                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1223                 # time to guarantee the status sync up.
1224                 wait_update_facet mds${k} "$LCTL get_param -n \
1225                         mdd.$(facet_svc mds${k}).lfsck_layout |
1226                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
1227                         error "(8) MDS${k} is not the expected 'completed'"
1228         done
1229 }
1230 run_test 12 "single command to trigger LFSCK on all devices"
1231
1232 $LCTL set_param debug=-lfsck > /dev/null || true
1233
1234 # restore MDS/OST size
1235 MDSSIZE=${SAVED_MDSSIZE}
1236 OSTSIZE=${SAVED_OSTSIZE}
1237
1238 # cleanup the system at last
1239 formatall
1240
1241 complete $SECONDS
1242 exit_status