Whamcloud - gitweb
e2173fefd66339a710dede32893f3fe402ac6c83
[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
11 LUSTRE=${LUSTRE:-$(dirname $0)/..}
12 . $LUSTRE/tests/test-framework.sh
13 init_test_env "$@"
14 init_logging
15
16 # bug number for skipped test:
17 ALWAYS_EXCEPT="$SANITY_LFSCK_EXCEPT "
18 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
19
20 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
21 build_test_filter
22
23 require_dsh_mds || exit 0
24
25 load_modules
26
27 if ! check_versions; then
28         skip "It is NOT necessary to test lfsck under interoperation mode"
29         exit 0
30 fi
31
32 (( $MDS1_VERSION >= $(version_code 2.3.60) )) ||
33         skip "Need MDS version at least 2.3.60"
34
35 LTIME=${LTIME:-120}
36
37 SAVED_MDSSIZE=${MDSSIZE}
38 SAVED_OSTSIZE=${OSTSIZE}
39 SAVED_OSTCOUNT=${OSTCOUNT}
40 # use small MDS + OST size to speed formatting time
41 # do not use too small MDSSIZE/OSTSIZE, which affect the default journal size
42 MDSSIZE=100000
43 [ "$mds1_FSTYPE" == zfs ] && MDSSIZE=300000
44 OSTSIZE=100000
45 [ "$ost1_FSTYPE" == zfs ] && OSTSIZE=300000
46
47 # no need too many OSTs, to reduce the format/start/stop overhead
48 cleanupall
49 [ $OSTCOUNT -gt 4 ] && OSTCOUNT=4
50
51 # build up a clean test environment.
52 REFORMAT="yes" check_and_setup_lustre
53
54 MDT_DEV=$(devicelabel $SINGLEMDS $(facet_device $SINGLEMDS))
55 OST_DEV="${FSNAME}-OST0000"
56 START_NAMESPACE="do_facet $SINGLEMDS \
57                 $LCTL lfsck_start -M ${MDT_DEV} -t namespace"
58 START_LAYOUT="do_facet $SINGLEMDS \
59                 $LCTL lfsck_start -M ${MDT_DEV} -t layout"
60 START_LAYOUT_ON_OST="do_facet ost1 $LCTL lfsck_start -M ${OST_DEV} -t layout"
61 STOP_LFSCK="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
62 SHOW_NAMESPACE="do_facet $SINGLEMDS \
63                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace"
64 SHOW_LAYOUT="do_facet $SINGLEMDS \
65                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout"
66 SHOW_LAYOUT_ON_OST="do_facet ost1 \
67                 $LCTL get_param -n obdfilter.${OST_DEV}.lfsck_layout"
68 MOUNT_OPTS_SCRUB="$MDS_MOUNT_OPTS -o user_xattr"
69 MOUNT_OPTS_NOSCRUB="$MDS_MOUNT_OPTS -o user_xattr,noscrub"
70 MOUNT_OPTS_SKIP_LFSCK="$MDS_MOUNT_OPTS -o user_xattr,skip_lfsck"
71
72 lfsck_prep() {
73         local ndirs=$1
74         local nfiles=$2
75         local igif=$3
76
77         check_mount_and_prep
78
79         echo "preparing... $nfiles * $ndirs files will be created $(date)."
80         if [ ! -z $igif ]; then
81                 #define OBD_FAIL_FID_IGIF       0x1504
82                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
83         fi
84
85         cp $LUSTRE/tests/*.sh $DIR/$tdir/
86         if [ $ndirs -gt 0 ]; then
87                 createmany -d $DIR/$tdir/d $ndirs
88                 createmany -m $DIR/$tdir/f $ndirs
89                 if [ $nfiles -gt 0 ]; then
90                         for ((i = 0; i < $ndirs; i++)); do
91                                 createmany -m $DIR/$tdir/d${i}/f $nfiles > \
92                                         /dev/null || error "createmany $nfiles"
93                         done
94                 fi
95                 createmany -d $DIR/$tdir/e $ndirs
96         fi
97
98         if [ ! -z $igif ]; then
99                 touch $DIR/$tdir/dummy
100                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0
101         fi
102
103         echo "prepared $(date)."
104 }
105
106 start_facet () {
107         local facet=$1
108         local opts=$2
109         local err=$3
110         local dev=$(facet_device $facet)
111
112         start $facet $dev $opts > /dev/null ||
113                 error "($err) Fail to start $facet!"
114 }
115
116 run_e2fsck_on_mds_facet() {
117         [ $mds1_FSTYPE == ldiskfs ] || return 0
118
119         local mds=$1
120
121         stop $mds > /dev/null || error "(0) Fail to the stop $mds"
122         local host=$(facet_active_host $mds)
123         local dev=$(facet_device $mds)
124
125         run_e2fsck $host $dev "-n" |
126                 grep "Fix? no" && {
127                 run_e2fsck $host $dev "-n"
128                 error "(2) Detected inconsistency on $mds"
129         }
130         start_facet $mds "$MOUNT_OPTS_NOSCRUB" 3
131 }
132
133 wait_all_targets_blocked() {
134         local com=$1
135         local status=$2
136         local err=$3
137
138         local count=$(do_facet mds1 \
139                      "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000 -w |
140                       awk '/^${com}_mdts_${status}/ { print \\\$2 }'")
141         [[ $count -eq $MDSCOUNT ]] || {
142                 do_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000"
143                 error "($err) only $count of $MDSCOUNT MDTs are in ${status}"
144         }
145 }
146
147 wait_all_targets() {
148         local com=$1
149         local status=$2
150         local err=$3
151
152         wait_update_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000 |
153                 awk '/^${com}_mdts_${status}/ { print \\\$2 }'" \
154                 "$MDSCOUNT" $LTIME || {
155                 do_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000"
156                 error "($err) some MDTs are not in ${status}"
157         }
158 }
159
160 test_0() {
161         lfsck_prep 3 3
162
163         #define OBD_FAIL_LFSCK_DELAY1           0x1600
164         do_facet $SINGLEMDS $LCTL set_param fail_val=3 fail_loc=0x1600
165         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
166
167         $SHOW_NAMESPACE || error "Fail to monitor LFSCK (3)"
168
169         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
170         [ "$STATUS" == "scanning-phase1" ] ||
171                 error "(4) Expect 'scanning-phase1', but got '$STATUS'"
172
173         $STOP_LFSCK || error "(5) Fail to stop LFSCK!"
174
175         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
176         [ "$STATUS" == "stopped" ] ||
177                 error "(6) Expect 'stopped', but got '$STATUS'"
178
179         $START_NAMESPACE || error "(7) Fail to start LFSCK for namespace!"
180
181         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
182         [ "$STATUS" == "scanning-phase1" ] ||
183                 error "(8) Expect 'scanning-phase1', but got '$STATUS'"
184
185         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
186         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
187                 mdd.${MDT_DEV}.lfsck_namespace |
188                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
189                 $SHOW_NAMESPACE
190                 error "(9) unexpected status"
191         }
192
193         local repaired=$($SHOW_NAMESPACE |
194                          awk '/^updated_phase1/ { print $2 }')
195         [ $repaired -eq 0 ] ||
196                 error "(10) Expect nothing to be repaired, but got: $repaired"
197
198         local scanned1=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
199         $START_NAMESPACE -r || error "(11) Fail to reset LFSCK!"
200         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
201                 mdd.${MDT_DEV}.lfsck_namespace |
202                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
203                 $SHOW_NAMESPACE
204                 error "(12) unexpected status"
205         }
206
207         local scanned2=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
208         [ $((scanned1 + 1)) -eq $scanned2 ] ||
209                 error "(13) Expect success $((scanned1 + 1)), but got $scanned2"
210
211         echo "stopall, should NOT crash LU-3649"
212         stopall || error "(14) Fail to stopall"
213 }
214 run_test 0 "Control LFSCK manually"
215
216 test_1a() {
217         lfsck_prep 1 1
218
219         #define OBD_FAIL_FID_INDIR      0x1501
220         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1501
221         touch $DIR/$tdir/dummy
222
223         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
224         umount_client $MOUNT
225         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
226         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
227                 mdd.${MDT_DEV}.lfsck_namespace |
228                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
229                 $SHOW_NAMESPACE
230                 error "(4) unexpected status"
231         }
232
233         local repaired=$($SHOW_NAMESPACE |
234                          awk '/^dirent_repaired/ { print $2 }')
235         # for interop with old server
236         [ -z "$repaired" ] &&
237                 repaired=$($SHOW_NAMESPACE |
238                          awk '/^updated_phase1/ { print $2 }')
239
240         [ $repaired -eq 1 ] ||
241                 error "(5) Fail to repair crashed FID-in-dirent: $repaired"
242
243         run_e2fsck_on_mds_facet $SINGLEMDS
244
245         mount_client $MOUNT || error "(6) Fail to start client!"
246
247         #define OBD_FAIL_FID_LOOKUP     0x1505
248         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
249         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
250
251         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
252 }
253 run_test 1a "LFSCK can find out and repair crashed FID-in-dirent"
254
255 test_1b()
256 {
257         [ "$mds1_FSTYPE" != ldiskfs ] &&
258                 skip "OI Scrub not implemented for ZFS"
259
260         lfsck_prep 1 1
261
262         #define OBD_FAIL_FID_INLMA      0x1502
263         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1502
264         touch $DIR/$tdir/dummy
265
266         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
267         umount_client $MOUNT
268         #define OBD_FAIL_FID_NOLMA      0x1506
269         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1506
270         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
271         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
272                 mdd.${MDT_DEV}.lfsck_namespace |
273                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
274                 $SHOW_NAMESPACE
275                 error "(4) unexpected status"
276         }
277
278         local repaired=$($SHOW_NAMESPACE |
279                          awk '/^dirent_repaired/ { print $2 }')
280         # for interop with old server
281         [ -z "$repaired" ] &&
282                 repaired=$($SHOW_NAMESPACE |
283                          awk '/^updated_phase1/ { print $2 }')
284
285         [ $repaired -eq 1 ] ||
286                 error "(5) Fail to repair the missing FID-in-LMA: $repaired"
287
288         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
289         run_e2fsck_on_mds_facet $SINGLEMDS
290
291         mount_client $MOUNT || error "(6) Fail to start client!"
292
293         #define OBD_FAIL_FID_LOOKUP     0x1505
294         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
295         stat $DIR/$tdir/dummy > /dev/null || error "(7) no FID-in-LMA."
296
297         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
298 }
299 run_test 1b "LFSCK can find out and repair the missing FID-in-LMA"
300
301 test_1c() {
302         lfsck_prep 1 1
303
304         #define OBD_FAIL_FID_IGIF       0x1504
305         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
306         touch $DIR/$tdir/dummy
307
308         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
309         umount_client $MOUNT
310         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
311         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
312                 mdd.${MDT_DEV}.lfsck_namespace |
313                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
314                 $SHOW_NAMESPACE
315                 error "(4) unexpected status"
316         }
317
318         local repaired=$($SHOW_NAMESPACE |
319                          awk '/^dirent_repaired/ { print $2 }')
320         # for interop with old server
321         [ -z "$repaired" ] &&
322                 repaired=$($SHOW_NAMESPACE |
323                          awk '/^updated_phase1/ { print $2 }')
324
325         [ $repaired -eq 1 ] ||
326                 error "(5) Fail to repair lost FID-in-dirent: $repaired"
327
328         run_e2fsck_on_mds_facet $SINGLEMDS
329
330         mount_client $MOUNT || error "(6) Fail to start client!"
331
332         #define OBD_FAIL_FID_LOOKUP     0x1505
333         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
334         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
335
336         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
337 }
338 run_test 1c "LFSCK can find out and repair lost FID-in-dirent"
339
340 test_1d() {
341         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
342                 skip "MDS older than 2.13.57"
343         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
344
345         check_mount_and_prep
346
347         touch $DIR/$tdir/$tfile
348         mkdir $DIR/$tdir/subdir
349         $LFS mkdir -i 1 $DIR/$tdir/remotedir
350         $LFS path2fid $DIR/$tdir
351         ll_decode_linkea $DIR/$tdir/$tfile
352         ll_decode_linkea $DIR/$tdir/subdir
353         ll_decode_linkea $DIR/$tdir/remotedir
354
355         local mntpt=$(facet_mntpt mds1)
356
357         # unlink OI files to remove the stale entry
358         local saved_opts=$MDS_MOUNT_OPTS
359
360         stopall
361         mount_fstype mds1 $mntpt
362         # increase $tdir FID oid in LMA
363         do_facet mds1 "getfattr -d -m trusted.lma -e hex \
364                 --absolute-names $mntpt/ROOT/$tdir | \
365                 sed -E 's/0(.{8})$/1\1/' | setfattr --restore=-"
366         unmount_fstype mds1 $mntpt
367         setupall
368
369         # the FID oid in LMA was increased above, and it's not in OI table,
370         # run scrub first to generate mapping in OI, so the following namespace
371         # check can fix linkea correctly, this is not necessary normally.
372         do_facet mds1 $LCTL lfsck_start -M ${MDT_DEV} -t scrub ||
373                 error "failed to start LFSCK for scrub!"
374         wait_update_facet mds1 "$LCTL get_param -n \
375                 osd-*.$(facet_svc mds1).oi_scrub |
376                 awk '/^status/ { print \\\$2 }'" "completed" 32 ||
377                 error "unexpected status"
378
379         $START_NAMESPACE -r -A || error "fail to start LFSCK for namespace!"
380         wait_update_facet mds1 "$LCTL get_param -n \
381                 mdd.${MDT_DEV}.lfsck_namespace |
382                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
383                 $SHOW_NAMESPACE
384                 error "unexpected status"
385         }
386         $LFS path2fid $DIR/$tdir
387         ll_decode_linkea $DIR/$tdir/$tfile
388         ll_decode_linkea $DIR/$tdir/subdir
389         ll_decode_linkea $DIR/$tdir/remotedir
390
391         local pfid
392         local fid
393
394         fid=$($LFS path2fid $DIR/$tdir)
395         for f in $tfile subdir remotedir; do
396                 pfid=$(ll_decode_linkea $DIR/$tdir/$f |
397                         awk '/pfid/ { print $3 }')
398                 pfid=${pfid%,}
399                 [ "$pfid" == "$fid" ] || error "$fid in LMA != $pfid in linkea"
400         done
401 }
402 run_test 1d "LFSCK can fix mismatch of FID in LMA and FID in child linkea"
403
404 test_2a() {
405         lfsck_prep 1 1
406
407         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
408         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
409         touch $DIR/$tdir/dummy
410
411         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
412         umount_client $MOUNT
413         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
414         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
415                 mdd.${MDT_DEV}.lfsck_namespace |
416                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
417                 $SHOW_NAMESPACE
418                 error "(4) unexpected status"
419         }
420
421         local repaired=$($SHOW_NAMESPACE |
422                          awk '/^linkea_repaired/ { print $2 }')
423         # for interop with old server
424         [ -z "$repaired" ] &&
425                 repaired=$($SHOW_NAMESPACE |
426                          awk '/^updated_phase2/ { print $2 }')
427
428         [ $repaired -eq 1 ] ||
429                 error "(5) Fail to repair crashed linkEA: $repaired"
430
431         run_e2fsck_on_mds_facet $SINGLEMDS
432
433         mount_client $MOUNT || error "(6) Fail to start client!"
434
435         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
436                 error "(7) Fail to stat $DIR/$tdir/dummy"
437
438         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
439         local dummyname=$($LFS fid2path $DIR $dummyfid)
440         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
441                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
442 }
443 run_test 2a "LFSCK can find out and repair crashed linkEA entry"
444
445 test_2b()
446 {
447         lfsck_prep 1 1
448
449         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
450         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
451         touch $DIR/$tdir/dummy
452
453         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
454         umount_client $MOUNT
455         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
456         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
457                 mdd.${MDT_DEV}.lfsck_namespace |
458                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
459                 $SHOW_NAMESPACE
460                 error "(4) unexpected status"
461         }
462
463         local repaired=$($SHOW_NAMESPACE |
464                          awk '/^updated_phase2/ { print $2 }')
465         [ $repaired -eq 1 ] ||
466                 error "(5) Fail to repair crashed linkEA: $repaired"
467
468         run_e2fsck_on_mds_facet $SINGLEMDS
469
470         mount_client $MOUNT || error "(6) Fail to start client!"
471
472         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
473                 error "(7) Fail to stat $DIR/$tdir/dummy"
474
475         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
476         local dummyname=$($LFS fid2path $DIR $dummyfid)
477         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
478                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
479 }
480 run_test 2b "LFSCK can find out and remove invalid linkEA entry"
481
482 test_2c()
483 {
484         (( $MDS1_VERSION > $(version_code 2.4.90) )) ||
485                 skip "MDS older than 2.4.90"
486
487         lfsck_prep 1 1
488
489         #define OBD_FAIL_LFSCK_LINKEA_MORE2     0x1605
490         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1605
491         touch $DIR/$tdir/dummy
492
493         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
494         umount_client $MOUNT
495         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
496         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
497                 mdd.${MDT_DEV}.lfsck_namespace |
498                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
499                 $SHOW_NAMESPACE
500                 error "(4) unexpected status"
501         }
502
503         local repaired=$($SHOW_NAMESPACE |
504                          awk '/^updated_phase2/ { print $2 }')
505         [ $repaired -eq 1 ] ||
506                 error "(5) Fail to repair crashed linkEA: $repaired"
507
508         run_e2fsck_on_mds_facet $SINGLEMDS
509
510         mount_client $MOUNT || error "(6) Fail to start client!"
511
512         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
513                 error "(7) Fail to stat $DIR/$tdir/dummy"
514
515         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
516         local dummyname=$($LFS fid2path $DIR $dummyfid)
517         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
518                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
519 }
520 run_test 2c "LFSCK can find out and remove repeated linkEA entry"
521
522 test_2d()
523 {
524         (( $MDS1_VERSION > $(version_code 2.6.50) )) ||
525                 skip "MDS older than 2.6.50, LU-4788"
526
527         lfsck_prep 1 1
528
529         #define OBD_FAIL_LFSCK_NO_LINKEA        0x161d
530         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161d
531         touch $DIR/$tdir/dummy
532
533         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
534         umount_client $MOUNT
535         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
536         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
537                 mdd.${MDT_DEV}.lfsck_namespace |
538                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
539                 $SHOW_NAMESPACE
540                 error "(4) unexpected status"
541         }
542
543         local repaired=$($SHOW_NAMESPACE |
544                          awk '/^linkea_repaired/ { print $2 }')
545         [ $repaired -eq 1 ] ||
546                 error "(5) Fail to repair crashed linkEA: $repaired"
547
548         run_e2fsck_on_mds_facet $SINGLEMDS
549
550         mount_client $MOUNT || error "(6) Fail to start client!"
551
552         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
553                 error "(7) Fail to stat $DIR/$tdir/dummy"
554
555         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
556         local dummyname=$($LFS fid2path $DIR $dummyfid)
557         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
558                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
559 }
560 run_test 2d "LFSCK can recover the missing linkEA entry"
561
562 test_2e()
563 {
564         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
565         (( $MDS1_VERSION > $(version_code 2.6.50) )) ||
566                 skip "MDS older than 2.6.50, LU-5511"
567
568         check_mount_and_prep
569
570         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT1"
571
572         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
573         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
574         $LFS mkdir -i 0 $DIR/$tdir/d0/d1 || error "(2) Fail to mkdir d1 on MDT0"
575         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
576
577         $START_NAMESPACE -r -A || error "(3) Fail to start LFSCK for namespace!"
578
579         wait_all_targets_blocked namespace completed 4
580
581         local repaired=$($SHOW_NAMESPACE |
582                          awk '/^linkea_repaired/ { print $2 }')
583         [ $repaired -eq 1 ] ||
584                 error "(5) Fail to repair crashed linkEA: $repaired"
585
586         local fid=$($LFS path2fid $DIR/$tdir/d0/d1)
587         local name=$($LFS fid2path $DIR $fid)
588         [ "$name" == "$DIR/$tdir/d0/d1" ] ||
589                 error "(6) Fail to repair linkEA: $fid $name"
590 }
591 run_test 2e "namespace LFSCK can verify remote object linkEA"
592
593 test_3()
594 {
595         (( $MDS1_VERSION > $(version_code 2.6.50) )) ||
596                 skip "MDS older than 2.6.50, LU-4788"
597
598         lfsck_prep 4 4
599
600         mkdir $DIR/$tdir/dummy || error "(1) Fail to mkdir"
601         ln $DIR/$tdir/d0/f0 $DIR/$tdir/dummy/f0 || error "(2) Fail to hardlink"
602         ln $DIR/$tdir/d0/f1 $DIR/$tdir/dummy/f1 || error "(3) Fail to hardlink"
603
604         $LFS mkdir -i 0 $DIR/$tdir/edir || error "(4) Fail to mkdir"
605         touch $DIR/$tdir/edir/f0 || error "(5) Fail to touch"
606         touch $DIR/$tdir/edir/f1 || error "(6) Fail to touch"
607
608         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
609         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
610         ln $DIR/$tdir/edir/f0 $DIR/$tdir/edir/w0 || error "(7) Fail to hardlink"
611
612         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
613         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
614         ln $DIR/$tdir/edir/f1 $DIR/$tdir/edir/w1 || error "(8) Fail to hardlink"
615
616         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
617
618         $START_NAMESPACE -r || error "(9) Fail to start LFSCK for namespace!"
619         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
620                 mdd.${MDT_DEV}.lfsck_namespace |
621                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
622                 $SHOW_NAMESPACE
623                 error "(10) unexpected status"
624         }
625
626         local checked=$($SHOW_NAMESPACE |
627                         awk '/^checked_phase2/ { print $2 }')
628         [ $checked -ge 4 ] ||
629                 error "(11) Fail to check multiple-linked object: $checked"
630
631         local repaired=$($SHOW_NAMESPACE |
632                          awk '/^multiple_linked_repaired/ { print $2 }')
633         [ $repaired -ge 2 ] ||
634                 error "(12) Fail to repair multiple-linked object: $repaired"
635 }
636 run_test 3 "LFSCK can verify multiple-linked objects"
637
638 test_4()
639 {
640         [ "$mds1_FSTYPE" != ldiskfs ] &&
641                 skip "OI Scrub not implemented for ZFS"
642
643         lfsck_prep 3 3
644         cleanup_mount $MOUNT || error "(0.1) Fail to stop client!"
645         stop $SINGLEMDS > /dev/null || error "(0.2) Fail to stop $SINGLEMDS!"
646
647         mds_backup_restore $SINGLEMDS || error "(1) Fail to backup/restore!"
648         echo "start $SINGLEMDS with disabling OI scrub"
649         start_facet $SINGLEMDS "$MOUNT_OPTS_NOSCRUB" 2
650
651         #define OBD_FAIL_LFSCK_DELAY2           0x1601
652         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
653         $START_NAMESPACE -r || error "(4) Fail to start LFSCK for namespace!"
654         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
655                 mdd.${MDT_DEV}.lfsck_namespace |
656                 awk '/^flags/ { print \\\$2 }'" "inconsistent" 32 || {
657                 $SHOW_NAMESPACE
658                 error "(5) unexpected status"
659         }
660
661         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
662         [ "$STATUS" == "scanning-phase1" ] ||
663                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
664
665         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
666         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
667                 mdd.${MDT_DEV}.lfsck_namespace |
668                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
669                 $SHOW_NAMESPACE
670                 error "(7) unexpected status"
671         }
672
673         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
674         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
675
676         local repaired=$($SHOW_NAMESPACE |
677                          awk '/^dirent_repaired/ { print $2 }')
678         # for interop with old server
679         [ -z "$repaired" ] &&
680                 repaired=$($SHOW_NAMESPACE |
681                          awk '/^updated_phase1/ { print $2 }')
682
683         [ $repaired -ge 9 ] ||
684                 error "(9) Fail to re-generate FID-in-dirent: $repaired"
685
686         run_e2fsck_on_mds_facet $SINGLEMDS
687
688         mount_client $MOUNT || error "(10) Fail to start client!"
689
690         #define OBD_FAIL_FID_LOOKUP     0x1505
691         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
692         ls $DIR/$tdir/ > /dev/null || error "(11) no FID-in-dirent."
693         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
694 }
695 run_test 4 "FID-in-dirent can be rebuilt after MDT file-level backup/restore"
696
697 test_5()
698 {
699         [ "$mds1_FSTYPE" != ldiskfs ] &&
700                 skip "OI Scrub not implemented for ZFS"
701
702         lfsck_prep 1 1 1
703         cleanup_mount $MOUNT || error "(0.1) Fail to stop client!"
704         stop $SINGLEMDS > /dev/null || error "(0.2) Fail to stop $SINGLEMDS!"
705
706         mds_backup_restore $SINGLEMDS 1 || error "(1) Fail to backup/restore!"
707         echo "start $SINGLEMDS with disabling OI scrub"
708         start_facet $SINGLEMDS "$MOUNT_OPTS_NOSCRUB" 2
709
710         #define OBD_FAIL_LFSCK_DELAY2           0x1601
711         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
712         $START_NAMESPACE -r || error "(4) Fail to start LFSCK for namespace!"
713         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
714                 mdd.${MDT_DEV}.lfsck_namespace |
715                 awk '/^flags/ { print \\\$2 }'" "inconsistent,upgrade" 32 || {
716                 $SHOW_NAMESPACE
717                 error "(5) unexpected status"
718         }
719
720         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
721         [ "$STATUS" == "scanning-phase1" ] ||
722                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
723
724         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
725         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
726                 mdd.${MDT_DEV}.lfsck_namespace |
727                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
728                 $SHOW_NAMESPACE
729                 error "(7) unexpected status"
730         }
731
732         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
733         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
734
735         local repaired=$($SHOW_NAMESPACE |
736                          awk '/^dirent_repaired/ { print $2 }')
737         # for interop with old server
738         [ -z "$repaired" ] &&
739                 repaired=$($SHOW_NAMESPACE |
740                          awk '/^updated_phase1/ { print $2 }')
741
742         [ $repaired -ge 2 ] ||
743                 error "(9) Fail to generate FID-in-dirent for IGIF: $repaired"
744
745         run_e2fsck_on_mds_facet $SINGLEMDS
746
747         mount_client $MOUNT || error "(10) Fail to start client!"
748
749         #define OBD_FAIL_FID_LOOKUP     0x1505
750         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
751         stat $DIR/$tdir/dummy > /dev/null || error "(11) no FID-in-LMA."
752
753         ls $DIR/$tdir/ > /dev/null || error "(12) no FID-in-dirent."
754
755         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
756         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
757         local dummyname=$($LFS fid2path $DIR $dummyfid)
758         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
759                 error "(13) Fail to generate linkEA: $dummyfid $dummyname"
760 }
761 run_test 5 "LFSCK can handle IGIF object upgrading"
762
763 test_6a() {
764         lfsck_prep 5 5
765
766         #define OBD_FAIL_LFSCK_DELAY1           0x1600
767         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
768         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
769
770         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
771         [ "$STATUS" == "scanning-phase1" ] ||
772                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
773
774         # Sleep 3 sec to guarantee at least one object processed by LFSCK
775         sleep 3
776         # Fail the LFSCK to guarantee there is at least one checkpoint
777         #define OBD_FAIL_LFSCK_FATAL1           0x1608
778         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001608
779         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
780                 mdd.${MDT_DEV}.lfsck_namespace |
781                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
782                 $SHOW_NAMESPACE
783                 error "(4) unexpected status"
784         }
785
786         local POS0=$($SHOW_NAMESPACE |
787                      awk '/^last_checkpoint_position/ { print $2 }' |
788                      tr -d ',')
789
790         #define OBD_FAIL_LFSCK_DELAY1           0x1600
791         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
792         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
793
794         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
795         [ "$STATUS" == "scanning-phase1" ] ||
796                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
797
798         local POS1=$($SHOW_NAMESPACE |
799                      awk '/^latest_start_position/ { print $2 }' |
800                      tr -d ',')
801         [[ $POS0 -lt $POS1 ]] ||
802                 error "(7) Expect larger than: $POS0, but got $POS1"
803
804         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
805         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
806                 mdd.${MDT_DEV}.lfsck_namespace |
807                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
808                 $SHOW_NAMESPACE
809                 error "(8) unexpected status"
810         }
811 }
812 run_test 6a "LFSCK resumes from last checkpoint (1)"
813
814 test_6b() {
815         lfsck_prep 5 5
816
817         #define OBD_FAIL_LFSCK_DELAY2           0x1601
818         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
819         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
820
821         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
822         [ "$STATUS" == "scanning-phase1" ] ||
823                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
824
825         # Sleep 5 sec to guarantee that we are in the directory scanning
826         sleep 5
827         # Fail the LFSCK to guarantee there is at least one checkpoint
828         #define OBD_FAIL_LFSCK_FATAL2           0x1609
829         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
830         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
831                 mdd.${MDT_DEV}.lfsck_namespace |
832                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
833                 $SHOW_NAMESPACE
834                 error "(4) unexpected status"
835         }
836
837         local O_POS0=$($SHOW_NAMESPACE |
838                        awk '/^last_checkpoint_position/ { print $2 }' |
839                        tr -d ',')
840
841         local D_POS0=$($SHOW_NAMESPACE |
842                        awk '/^last_checkpoint_position/ { print $4 }')
843
844         #define OBD_FAIL_LFSCK_DELAY2           0x1601
845         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
846         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
847
848         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
849         [ "$STATUS" == "scanning-phase1" ] ||
850                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
851
852         local O_POS1=$($SHOW_NAMESPACE |
853                        awk '/^latest_start_position/ { print $2 }' |
854                        tr -d ',')
855         local D_POS1=$($SHOW_NAMESPACE |
856                        awk '/^latest_start_position/ { print $4 }')
857
858         echo "Additional debug for 6b"
859         $SHOW_NAMESPACE
860         if [ "$D_POS0" == "N/A" -o "$D_POS0" == "0x0" \
861              -o "$D_POS1" == "0x0" -o "$D_POS1" == "N/A" ]; then
862                 [[ $O_POS0 -lt $O_POS1 ]] ||
863                         error "(7.1) $O_POS1 is not larger than $O_POS0"
864         else
865                 [[ $D_POS0 -lt $D_POS1 ]] ||
866                         error "(7.2) $D_POS1 is not larger than $D_POS0"
867         fi
868
869         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
870         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
871                 mdd.${MDT_DEV}.lfsck_namespace |
872                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
873                 $SHOW_NAMESPACE
874                 error "(8) unexpected status"
875         }
876 }
877 run_test 6b "LFSCK resumes from last checkpoint (2)"
878
879 test_7a()
880 {
881         lfsck_prep 5 5
882         umount_client $MOUNT
883
884         #define OBD_FAIL_LFSCK_DELAY2           0x1601
885         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
886         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
887
888         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
889         [ "$STATUS" == "scanning-phase1" ] ||
890                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
891
892         # Sleep 3 sec to guarantee at least one object processed by LFSCK
893         sleep 3
894         echo "stop $SINGLEMDS"
895         stop $SINGLEMDS > /dev/null || error "(4) Fail to stop $SINGLEMDS!"
896
897         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
898         echo "start $SINGLEMDS"
899         start_facet $SINGLEMDS "$MOUNT_OPTS_SCRUB" 5
900
901         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
902                 mdd.${MDT_DEV}.lfsck_namespace |
903                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
904                 $SHOW_NAMESPACE
905                 error "(6) unexpected status"
906         }
907 }
908 run_test 7a "non-stopped LFSCK should auto restarts after MDS remount (1)"
909
910 test_7b()
911 {
912         lfsck_prep 2 2
913
914         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
915         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
916         for ((i = 0; i < 20; i++)); do
917                 touch $DIR/$tdir/dummy${i}
918         done
919
920         #define OBD_FAIL_LFSCK_DELAY3           0x1602
921         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1602
922         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
923         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
924                 mdd.${MDT_DEV}.lfsck_namespace |
925                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
926                 $SHOW_NAMESPACE
927                 error "(4) unexpected status"
928         }
929
930         umount_client $MOUNT
931         echo "stop $SINGLEMDS"
932         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop $SINGLEMDS!"
933
934         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
935         echo "start $SINGLEMDS"
936         start_facet $SINGLEMDS "$MOUNT_OPTS_SCRUB" 6
937
938         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
939                 mdd.${MDT_DEV}.lfsck_namespace |
940                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
941                 $SHOW_NAMESPACE
942                 error "(7) unexpected status"
943         }
944 }
945 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
946
947 namespace_error()
948 {
949         $SHOW_NAMESPACE
950         error "$@"
951 }
952
953 test_8()
954 {
955         echo "formatall"
956         formatall > /dev/null
957         echo "setupall"
958         setupall > /dev/null
959
960         lfsck_prep 20 20
961
962         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
963         [ "$STATUS" == "init" ] ||
964                 namespace_error "(2) Expect 'init', but got '$STATUS'"
965
966         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
967         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
968         mkdir $DIR/$tdir/crashed
969
970         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
971         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
972         for ((i = 0; i < 5; i++)); do
973                 touch $DIR/$tdir/dummy${i}
974         done
975
976         umount_client $MOUNT || error "(3) Fail to stop client!"
977
978         #define OBD_FAIL_LFSCK_DELAY2           0x1601
979         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1601
980         $START_NAMESPACE ||
981                 namespace_error "(4) Fail to start LFSCK for namespace!"
982
983         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
984         [ "$STATUS" == "scanning-phase1" ] ||
985                 namespace_error "(5) Expect 'scanning-phase1', but got '$STATUS'"
986
987         $STOP_LFSCK || namespace_error "(6) Fail to stop LFSCK!"
988
989         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
990         [ "$STATUS" == "stopped" ] ||
991                 namespace_error "(7) Expect 'stopped', but got '$STATUS'"
992
993         $START_NAMESPACE ||
994                 namespace_error "(8) Fail to start LFSCK for namespace!"
995
996         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
997         [ "$STATUS" == "scanning-phase1" ] ||
998                 namespace_error "(9) Expect 'scanning-phase1', but got '$STATUS'"
999
1000         #define OBD_FAIL_LFSCK_FATAL2           0x1609
1001         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
1002         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1003                 mdd.${MDT_DEV}.lfsck_namespace |
1004                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
1005                 $SHOW_NAMESPACE
1006                 namespace_error "(10) unexpected status"
1007         }
1008
1009         #define OBD_FAIL_LFSCK_DELAY1           0x1600
1010         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
1011         $START_NAMESPACE ||
1012                 namespace_error "(11) Fail to start LFSCK for namespace!"
1013
1014         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1015         [ "$STATUS" == "scanning-phase1" ] ||
1016                 namespace_error "(12) Expect 'scanning-phase1', but got '$STATUS'"
1017
1018         #define OBD_FAIL_LFSCK_CRASH            0x160a
1019         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
1020         sleep 5
1021
1022         echo "stop $SINGLEMDS"
1023         stop $SINGLEMDS > /dev/null || namespace_error "(13) Fail to stop MDS!"
1024
1025         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
1026         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
1027
1028         echo "start $SINGLEMDS"
1029         start_facet $SINGLEMDS "$MOUNT_OPTS_SCRUB" 14
1030
1031         local timeout=$(max_recovery_time)
1032         local timer=0
1033
1034         while [ $timer -lt $timeout ]; do
1035                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1036                         mdt.${MDT_DEV}.recovery_status |
1037                         awk '/^status/ { print \\\$2 }'")
1038                 [ "$STATUS" != "RECOVERING" ] && break;
1039                 sleep 1
1040                 timer=$((timer + 1))
1041         done
1042
1043         [ $timer != $timeout ] || (
1044                 do_facet $SINGLEMDS "$LCTL get_param -n \
1045                         mdt.${MDT_DEV}.recovery_status"
1046                 error "(14.1) recovery timeout"
1047                 )
1048
1049         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1050         [ "$STATUS" == "crashed" ] ||
1051                 namespace_error "(15) Expect 'crashed', but got '$STATUS'"
1052
1053         #define OBD_FAIL_LFSCK_DELAY2           0x1601
1054         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
1055         $START_NAMESPACE ||
1056                 namespace_error "(16) Fail to start LFSCK for namespace!"
1057
1058         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1059         [ "$STATUS" == "scanning-phase1" ] ||
1060                 namespace_error "(17) Expect 'scanning-phase1', but got '$STATUS'"
1061
1062         echo "stop $SINGLEMDS"
1063         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop $SINGLEMDS!"
1064
1065         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
1066         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
1067
1068         echo "start $SINGLEMDS"
1069         start_facet $SINGLEMDS "$MOUNT_OPTS_SCRUB" 19
1070
1071         timer=0
1072         while [ $timer -lt $timeout ]; do
1073                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1074                         mdt.${MDT_DEV}.recovery_status |
1075                         awk '/^status/ { print \\\$2 }'")
1076                 [ "$STATUS" != "RECOVERING" ] && break;
1077                 sleep 1
1078                 timer=$((timer + 1))
1079         done
1080
1081         [ $timer != $timeout ] || (
1082                 do_facet $SINGLEMDS "$LCTL get_param -n \
1083                         mdt.${MDT_DEV}.recovery_status"
1084                 error "(19.1) recovery timeout"
1085                 )
1086
1087         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1088         [ "$STATUS" == "paused" ] ||
1089                 namespace_error "(20) Expect 'paused', but got '$STATUS'"
1090
1091         echo "stop $SINGLEMDS"
1092         stop $SINGLEMDS > /dev/null || error "(20.1) Fail to stop MDS!"
1093
1094         echo "start $SINGLEMDS without resume LFSCK"
1095         start_facet $SINGLEMDS "$MOUNT_OPTS_SKIP_LFSCK" 20.2
1096
1097         timer=0
1098         while [ $timer -lt $timeout ]; do
1099                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1100                         mdt.${MDT_DEV}.recovery_status |
1101                         awk '/^status/ { print \\\$2 }'")
1102                 [ "$STATUS" != "RECOVERING" ] && break;
1103                 sleep 1
1104                 timer=$((timer + 1))
1105         done
1106
1107         [ $timer != $timeout ] || (
1108                 do_facet $SINGLEMDS "$LCTL get_param -n \
1109                         mdt.${MDT_DEV}.recovery_status"
1110                 error "(20.3) recovery timeout"
1111                 )
1112
1113         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1114         [ "$STATUS" == "paused" ] ||
1115                 namespace_error "(20.4) Expect 'paused', but got '$STATUS'"
1116
1117         #define OBD_FAIL_LFSCK_DELAY3           0x1602
1118         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1602
1119
1120         $START_NAMESPACE ||
1121                 namespace_error "(21) Fail to start LFSCK for namespace!"
1122         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1123                 mdd.${MDT_DEV}.lfsck_namespace |
1124                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
1125                 $SHOW_NAMESPACE
1126                 namespace_error "(22) unexpected status"
1127         }
1128
1129         # wait to process one inode at least (OBD_FAIL_LFSCK_DELAY3)
1130         sleep 3
1131
1132         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1133         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
1134                 namespace_error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
1135
1136         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1137         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1138                 mdd.${MDT_DEV}.lfsck_namespace |
1139                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1140                 $SHOW_NAMESPACE
1141                 namespace_error "(24) unexpected status"
1142         }
1143
1144         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1145         [ -z "$FLAGS" ] ||
1146                 namespace_error "(25) Expect empty flags, but got '$FLAGS'"
1147 }
1148 run_test 8 "LFSCK state machine"
1149
1150 test_9a() {
1151         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1152                 skip "Testing on UP system, the speed may be inaccurate."
1153                 return 0
1154         fi
1155
1156         check_mount_and_prep
1157         $LFS mkdir -i 0 $DIR/$tdir/lfsck || error "(1) Fail to mkdir lfsck"
1158         $LFS setstripe -c 1 -i -1 $DIR/$tdir/lfsck
1159         createmany -o $DIR/$tdir/lfsck/f 5000
1160
1161         local BASE_SPEED1=100
1162         local RUN_TIME1=10
1163         $START_LAYOUT -r -s $BASE_SPEED1 || error "(2) Fail to start LFSCK!"
1164
1165         sleep $RUN_TIME1
1166         STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
1167         [ "$STATUS" == "scanning-phase1" ] ||
1168                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
1169
1170         local SPEED=$($SHOW_LAYOUT |
1171                       awk '/^average_speed_phase1/ { print $2 }')
1172
1173         # There may be time error, normally it should be less than 2 seconds.
1174         # We allow another 20% schedule error.
1175         local TIME_DIFF=2
1176         # MAX_MARGIN = 1.3 = 13 / 10
1177         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) /
1178                            RUN_TIME1 * 13 / 10))
1179         [ $SPEED -lt $MAX_SPEED ] || {
1180                 $SHOW_LAYOUT
1181                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1182                 error "(4) Speed $SPEED, expected < $MAX_SPEED"
1183         }
1184
1185         # adjust speed limit
1186         local BASE_SPEED2=300
1187         local RUN_TIME2=10
1188         do_facet $SINGLEMDS \
1189                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1190         sleep $RUN_TIME2
1191
1192         SPEED=$($SHOW_LAYOUT | awk '/^average_speed_phase1/ { print $2 }')
1193         # MIN_MARGIN = 0.7 = 7 / 10
1194         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) +
1195                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) /
1196                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1197         [ $SPEED -gt $MIN_SPEED ] || {
1198                 if [ $mds1_FSTYPE != ldiskfs ]; then
1199                         error_ignore LU-5624 \
1200                         "(5.1) Got speed $SPEED, expected more than $MIN_SPEED"
1201                 else
1202                         error \
1203                         "(5.2) Got speed $SPEED, expected more than $MIN_SPEED"
1204                 fi
1205         }
1206
1207         # MAX_MARGIN = 1.3 = 13 / 10
1208         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) +
1209                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) /
1210                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1211         [ $SPEED -lt $MAX_SPEED ] || {
1212                 $SHOW_LAYOUT
1213                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1214                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1215                 error "(6) Speed $SPEED, expected < $MAX_SPEED"
1216         }
1217
1218         do_nodes $(comma_list $(mdts_nodes)) \
1219                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1220         do_nodes $(comma_list $(osts_nodes)) \
1221                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1222
1223         wait_update_facet $SINGLEMDS \
1224                 "$LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout |
1225                 awk '/^status/ { print \\\$2 }'" "completed" 30 ||
1226                 error "(7) Failed to get expected 'completed'"
1227 }
1228 run_test 9a "LFSCK speed control (1)"
1229
1230 test_9b() {
1231         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1232                 skip "Testing on UP system, the speed may be inaccurate."
1233                 return 0
1234         fi
1235
1236         lfsck_prep 0 0
1237
1238         echo "Preparing another 50 * 50 files (with error) at $(date)."
1239         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1240         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1241         createmany -d $DIR/$tdir/d 50
1242         createmany -m $DIR/$tdir/f 50
1243         for ((i = 0; i < 50; i++)); do
1244                 createmany -m $DIR/$tdir/d${i}/f 50 > /dev/null
1245         done
1246
1247         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
1248         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
1249         $START_NAMESPACE -r || error "(4) Fail to start LFSCK!"
1250         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1251                 mdd.${MDT_DEV}.lfsck_namespace |
1252                 awk '/^status/ { print \\\$2 }'" "stopped" 10 || {
1253                 $SHOW_NAMESPACE
1254                 error "(5) unexpected status"
1255         }
1256
1257         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1258         echo "Prepared at $(date)."
1259
1260         local BASE_SPEED1=50
1261         local RUN_TIME1=10
1262         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
1263
1264         sleep $RUN_TIME1
1265         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1266         [ "$STATUS" == "scanning-phase2" ] ||
1267                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
1268
1269         local SPEED=$($SHOW_NAMESPACE |
1270                       awk '/^average_speed_phase2/ { print $2 }')
1271         # There may be time error, normally it should be less than 2 seconds.
1272         # We allow another 20% schedule error.
1273         local TIME_DIFF=2
1274         # MAX_MARGIN = 1.3 = 13 / 10
1275         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) /
1276                           RUN_TIME1 * 13 / 10))
1277         [ $SPEED -lt $MAX_SPEED ] || {
1278                 $SHOW_NAMESPACE
1279                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1280                 error "(8) Speed $SPEED, expected < $MAX_SPEED"
1281         }
1282
1283         # adjust speed limit
1284         local BASE_SPEED2=150
1285         local RUN_TIME2=10
1286         do_facet $SINGLEMDS \
1287                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1288         sleep $RUN_TIME2
1289
1290         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
1291         # MIN_MARGIN = 0.7 = 7 / 10
1292         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) +
1293                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) /
1294                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1295         [ $SPEED -gt $MIN_SPEED ] || {
1296                 if [ $mds1_FSTYPE != ldiskfs ]; then
1297                         error_ignore LU-5624 \
1298                         "(9.1) Got speed $SPEED, expected more than $MIN_SPEED"
1299                 else
1300                         error \
1301                         "(9.2) Got speed $SPEED, expected more than $MIN_SPEED"
1302                 fi
1303         }
1304
1305         # MAX_MARGIN = 1.3 = 13 / 10
1306         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) +
1307                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) /
1308                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1309         [ $SPEED -lt $MAX_SPEED ] || {
1310                 $SHOW_NAMESPACE
1311                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1312                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1313                 error "(10) Speed $SPEED, expected < $MAX_SPEED"
1314         }
1315
1316         do_nodes $(comma_list $(mdts_nodes)) \
1317                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1318         do_nodes $(comma_list $(osts_nodes)) \
1319                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1320         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1321                 mdd.${MDT_DEV}.lfsck_namespace |
1322                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1323                 $SHOW_NAMESPACE
1324                 error "(11) unexpected status"
1325         }
1326 }
1327 run_test 9b "LFSCK speed control (2)"
1328
1329 test_10()
1330 {
1331         [[ $mds1_FSTYPE == ldiskfs ]] || skip "lookup(..)/linkea on ZFS issue"
1332
1333         lfsck_prep 1 1
1334
1335         echo "Preparing more files with error at $(date)."
1336         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
1337         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
1338
1339         for ((i = 0; i < 1000; i = $((i+2)))); do
1340                 mkdir -p $DIR/$tdir/d${i}
1341                 touch $DIR/$tdir/f${i}
1342                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1343         done
1344
1345         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1346         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1347
1348         for ((i = 1; i < 1000; i = $((i+2)))); do
1349                 mkdir -p $DIR/$tdir/d${i}
1350                 touch $DIR/$tdir/f${i}
1351                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1352         done
1353
1354         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1355         echo "Prepared at $(date)."
1356
1357         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
1358
1359         umount_client $MOUNT
1360         mount_client $MOUNT || error "(3) Fail to start client!"
1361
1362         $START_NAMESPACE -r -s 100 || error "(5) Fail to start LFSCK!"
1363
1364         sleep 10
1365         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1366         [ "$STATUS" == "scanning-phase1" ] ||
1367                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
1368
1369         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
1370
1371         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
1372
1373         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
1374
1375         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
1376
1377         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
1378
1379         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
1380
1381         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
1382
1383         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
1384                 error "(14) Fail to softlink!"
1385
1386         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1387         [ "$STATUS" == "scanning-phase1" ] ||
1388                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
1389
1390         do_nodes $(comma_list $(mdts_nodes)) \
1391                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1392         do_nodes $(comma_list $(osts_nodes)) \
1393                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1394         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1395                 mdd.${MDT_DEV}.lfsck_namespace |
1396                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1397                 $SHOW_NAMESPACE
1398                 error "(16) unexpected status"
1399         }
1400 }
1401 run_test 10 "System is available during LFSCK scanning"
1402
1403 # remove LAST_ID
1404 ost_remove_lastid() {
1405         local ost=$1
1406         local idx=$2
1407         local rcmd="do_facet ost${ost}"
1408
1409         echo "remove LAST_ID on ost${ost}: idx=${idx}"
1410
1411         # step 1: local mount
1412         mount_fstype ost${ost} || return 1
1413         # step 2: remove the specified LAST_ID
1414         ${rcmd} rm -fv $(facet_mntpt ost${ost})/O/${idx}/{LAST_ID,d0/0}
1415         # step 3: umount
1416         unmount_fstype ost${ost} || return 2
1417 }
1418
1419 test_11a() {
1420         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1421                 skip "MDS older than 2.5.55, LU-1267"
1422
1423         check_mount_and_prep
1424         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1425         createmany -o $DIR/$tdir/f 64 || error "(0) Fail to create 64 files."
1426
1427         echo "stopall"
1428         stopall > /dev/null
1429
1430         ost_remove_lastid 1 0 || error "(1) Fail to remove LAST_ID"
1431
1432         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
1433                 error "(2) Fail to start ost1"
1434
1435         #define OBD_FAIL_LFSCK_DELAY4           0x160e
1436         do_facet ost1 $LCTL set_param fail_val=3 fail_loc=0x160e
1437
1438         echo "trigger LFSCK for layout on ost1 to rebuild the LAST_ID(s)"
1439         $START_LAYOUT_ON_OST -r || error "(4) Fail to start LFSCK on OST!"
1440
1441         wait_update_facet ost1 "$LCTL get_param -n \
1442                 obdfilter.${OST_DEV}.lfsck_layout |
1443                 awk '/^flags/ { print \\\$2 }'" "crashed_lastid" 60 || {
1444                 $SHOW_LAYOUT_ON_OST
1445                 error "(5) unexpected status"
1446         }
1447
1448         do_facet ost1 $LCTL set_param fail_val=0 fail_loc=0
1449
1450         wait_update_facet ost1 "$LCTL get_param -n \
1451                 obdfilter.${OST_DEV}.lfsck_layout |
1452                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1453                 $SHOW_LAYOUT_ON_OST
1454                 error "(6) unexpected status"
1455         }
1456
1457         echo "the LAST_ID(s) should have been rebuilt"
1458         FLAGS=$($SHOW_LAYOUT_ON_OST | awk '/^flags/ { print $2 }')
1459         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
1460 }
1461 run_test 11a "LFSCK can rebuild lost last_id"
1462
1463 test_11b() {
1464         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1465                 skip "MDS older than 2.5.55, LU-1267"
1466
1467         check_mount_and_prep
1468         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1469
1470         echo "set fail_loc=0x160d to skip the updating LAST_ID on-disk"
1471         #define OBD_FAIL_LFSCK_SKIP_LASTID      0x160d
1472         do_facet ost1 $LCTL set_param fail_loc=0x160d
1473
1474         local count=$(precreated_ost_obj_count 0 0)
1475
1476         createmany -o $DIR/$tdir/f $((count + 32))
1477
1478         local proc_path="${FSNAME}-OST0000-osc-MDT0000"
1479         local seq=$(do_facet mds1 $LCTL get_param -n \
1480                     osp.${proc_path}.prealloc_last_seq)
1481         local id_used=$(do_facet mds1 $LCTL get_param -n \
1482                         osp.${proc_path}.prealloc_last_id)
1483
1484         umount_client $MOUNT
1485         stop ost1 || error "(1) Fail to stop ost1"
1486
1487         #define OBD_FAIL_OST_ENOSPC              0x215
1488         do_facet ost1 $LCTL set_param fail_loc=0x215
1489
1490         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1491                 error "(2) Fail to start ost1"
1492
1493         for ((i = 0; i < 60; i++)); do
1494                 id_ost1=$(do_facet ost1 \
1495                           "$LCTL get_param -n obdfilter.$ost1_svc.last_id" |
1496                           awk -F: "/$seq/ { print \$2 }")
1497                 [ -n "$id_ost1" ] && break
1498                 sleep 1
1499         done
1500
1501         echo "the on-disk LAST_ID should be smaller than the expected one"
1502         [ $id_used -gt $id_ost1 ] ||
1503                 error "(4) expect id_used '$id_used' > id_ost1 '$id_ost1'"
1504
1505         echo "trigger LFSCK for layout on ost1 to rebuild the on-disk LAST_ID"
1506         $START_LAYOUT_ON_OST -r || error "(5) Fail to start LFSCK on OST!"
1507
1508         wait_update_facet ost1 \
1509                 "$LCTL get_param -n obdfilter.$ost1_svc.lfsck_layout |
1510                  awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1511                 $SHOW_LAYOUT_ON_OST
1512                 error "(6) unexpected status"
1513         }
1514
1515         stop ost1 || error "(7) Fail to stop ost1"
1516
1517         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1518                 error "(8) Fail to start ost1"
1519
1520         echo "the on-disk LAST_ID should have been rebuilt"
1521         # last_id may be larger than $id_used if objects were created/skipped
1522         wait_update_facet_cond ost1 \
1523                 "$LCTL get_param -n obdfilter.$ost1_svc.last_id |
1524                  awk -F: '/$seq/ { print \\\$2 }'" "-ge" "$id_used" 60 || {
1525                 do_facet ost1 $LCTL get_param obdfilter.$ost1_svc.last_id
1526                 error "(9) expect last_id >= id_used $seq:$id_used"
1527         }
1528
1529         do_facet ost1 $LCTL set_param fail_loc=0
1530         stopall || error "(10) Fail to stopall"
1531 }
1532 run_test 11b "LFSCK can rebuild crashed last_id"
1533
1534 test_12a() {
1535         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1536         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1537                 skip "MDS older than 2.5.55, LU-3950"
1538
1539         check_mount_and_prep
1540         for k in $(seq $MDSCOUNT); do
1541                 $LFS mkdir -i $((k - 1)) $DIR/$tdir/${k}
1542                 createmany -o $DIR/$tdir/${k}/f 100 ||
1543                         error "(0) Fail to create 100 files."
1544         done
1545
1546         echo "Start namespace LFSCK on all targets by single command (-s 1)."
1547         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1548                 -s 1 -r || error "(2) Fail to start LFSCK on all devices!"
1549
1550         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1551         wait_all_targets namespace scanning-phase1 3
1552
1553         echo "Stop namespace LFSCK on all targets by single lctl command."
1554         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1555                 error "(4) Fail to stop LFSCK on all devices!"
1556
1557         echo "All the LFSCK targets should be in 'stopped' status."
1558         wait_all_targets_blocked namespace stopped 5
1559
1560         echo "Re-start namespace LFSCK on all targets by single command (-s 0)."
1561         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1562                 -s 0 -r || error "(6) Fail to start LFSCK on all devices!"
1563
1564         echo "All the LFSCK targets should be in 'completed' status."
1565         wait_all_targets_blocked namespace completed 7
1566
1567         start_full_debug_logging
1568
1569         echo "Start layout LFSCK on all targets by single command (-s 1)."
1570         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1571                 -s 1 -r || error "(8) Fail to start LFSCK on all devices!"
1572
1573         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1574         wait_all_targets layout scanning-phase1 9
1575
1576         echo "Stop layout LFSCK on all targets by single lctl command."
1577         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1578                 error "(10) Fail to stop LFSCK on all devices!"
1579
1580         echo "All the LFSCK targets should be in 'stopped' status."
1581         wait_all_targets_blocked layout stopped 11
1582
1583         for k in $(seq $OSTCOUNT); do
1584                 local STATUS=$(do_facet ost${k} $LCTL get_param -n \
1585                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1586                                 awk '/^status/ { print $2 }')
1587                 [ "$STATUS" == "stopped" ] ||
1588                         error "(12) OST${k} Expect 'stopped', but got '$STATUS'"
1589         done
1590
1591         echo "Re-start layout LFSCK on all targets by single command (-s 0)."
1592         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1593                 -s 0 -r || error "(13) Fail to start LFSCK on all devices!"
1594
1595         echo "All the LFSCK targets should be in 'completed' status."
1596         wait_all_targets_blocked layout completed 14
1597
1598         stop_full_debug_logging
1599 }
1600 run_test 12a "single command to trigger LFSCK on all devices"
1601
1602 test_12b() {
1603         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1604                 skip "MDS older than 2.5.55, LU-3950"
1605
1606         check_mount_and_prep
1607
1608         echo "Start LFSCK without '-M' specified."
1609         do_facet mds1 $LCTL lfsck_start -A -r ||
1610                 error "(0) Fail to start LFSCK without '-M'"
1611
1612         wait_all_targets_blocked namespace completed 1
1613         wait_all_targets_blocked layout completed 2
1614
1615         local count=$(do_facet mds1 $LCTL dl |
1616                       awk '{ print $3 }' | grep mdt | wc -l)
1617         if [ $count -gt 1 ]; then
1618                 echo
1619                 echo "Start layout LFSCK on the node with multipe targets,"
1620                 echo "but not specify '-M'/'-A' option. Should get failure."
1621                 echo
1622                 do_facet mds1 $LCTL lfsck_start -t layout -r &&
1623                         error "(3) Start layout LFSCK should fail" || true
1624         fi
1625 }
1626 run_test 12b "auto detect Lustre device"
1627
1628 test_13() {
1629         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1630                 skip "MDS older than 2.5.55, LU-3593"
1631
1632         echo "#####"
1633         echo "The lmm_oi in layout EA should be consistent with the MDT-object"
1634         echo "FID; otherwise, the LFSCK should re-generate the lmm_oi from the"
1635         echo "MDT-object FID."
1636         echo "#####"
1637
1638         check_mount_and_prep
1639
1640         echo "Inject failure stub to simulate bad lmm_oi"
1641         #define OBD_FAIL_LFSCK_BAD_LMMOI        0x160f
1642         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160f
1643         createmany -o $DIR/$tdir/f 1
1644         $LFS setstripe -E 1M -S 1M -E -1 $DIR/$tdir/f1 ||
1645                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1646         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1647
1648         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
1649         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1650
1651         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1652                 mdd.${MDT_DEV}.lfsck_layout |
1653                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1654                 $SHOW_LAYOUT
1655                 error "(2) unexpected status"
1656         }
1657
1658         local repaired=$($SHOW_LAYOUT |
1659                          awk '/^repaired_others/ { print $2 }')
1660         [ $repaired -eq 2 ] ||
1661                 error "(3) Fail to repair crashed lmm_oi: $repaired"
1662 }
1663 run_test 13 "LFSCK can repair crashed lmm_oi"
1664
1665 test_14a() {
1666         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1667                 skip "MDS older than 2.5.55, LU-3590"
1668
1669         echo "#####"
1670         echo "The OST-object referenced by the MDT-object should be there;"
1671         echo "otherwise, the LFSCK should re-create the missing OST-object."
1672         echo "without '--delay-create-ostobj' option."
1673         echo "#####"
1674
1675         check_mount_and_prep
1676         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1677
1678         echo "Inject failure stub to simulate dangling referenced MDT-object"
1679         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1680         do_facet ost1 $LCTL set_param fail_loc=0x1610
1681         local count=$(precreated_ost_obj_count 0 0)
1682
1683         createmany -o $DIR/$tdir/f $((count + 16)) ||
1684                 error "(0.1) Fail to create $DIR/$tdir/fx"
1685         touch $DIR/$tdir/guard0
1686
1687         for ((i = 0; i < 16; i++)); do
1688                 $LFS setstripe -E 512K -S 256K -o 0 -E 2M \
1689                         $DIR/$tdir/f_comp${i} ||
1690                         error "(0.2) Fail to create $DIR/$tdir/f_comp${i}"
1691         done
1692         touch $DIR/$tdir/guard1
1693
1694         do_facet ost1 $LCTL set_param fail_loc=0
1695
1696         start_full_debug_logging
1697
1698         # exhaust other pre-created dangling cases
1699         count=$(precreated_ost_obj_count 0 0)
1700         createmany -o $DIR/$tdir/a $count ||
1701                 error "(0.5) Fail to create $count files."
1702
1703         echo "'ls' should fail because of dangling referenced MDT-object"
1704         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1705
1706         echo "Trigger layout LFSCK to find out dangling reference"
1707         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1708
1709         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1710                 mdd.${MDT_DEV}.lfsck_layout |
1711                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1712                 $SHOW_LAYOUT
1713                 error "(3) unexpected status"
1714         }
1715
1716         local repaired=$($SHOW_LAYOUT |
1717                          awk '/^repaired_dangling/ { print $2 }')
1718         [ $repaired -ge 32 ] ||
1719                 error "(4) Fail to repair dangling reference: $repaired"
1720
1721         echo "'stat' should fail because of not repair dangling by default"
1722         stat $DIR/$tdir/guard0 > /dev/null 2>&1 &&
1723                 error "(5.1) stat should fail"
1724         stat $DIR/$tdir/guard1 > /dev/null 2>&1 &&
1725                 error "(5.2) stat should fail"
1726
1727         echo "Trigger layout LFSCK to repair dangling reference"
1728         $START_LAYOUT -r -c || error "(6) Fail to start LFSCK for layout!"
1729
1730         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1731                 mdd.${MDT_DEV}.lfsck_layout |
1732                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1733                 $SHOW_LAYOUT
1734                 error "(7) unexpected status"
1735         }
1736
1737         # There may be some async LFSCK updates in processing, wait for
1738         # a while until the target reparation has been done. LU-4970.
1739
1740         echo "'stat' should success after layout LFSCK repairing"
1741         wait_update_facet client "stat $DIR/$tdir/guard0 |
1742                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1743                 stat $DIR/$tdir/guard0
1744                 $SHOW_LAYOUT
1745                 error "(8.1) unexpected size"
1746         }
1747
1748         wait_update_facet client "stat $DIR/$tdir/guard1 |
1749                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1750                 stat $DIR/$tdir/guard1
1751                 $SHOW_LAYOUT
1752                 error "(8.2) unexpected size"
1753         }
1754
1755         repaired=$($SHOW_LAYOUT |
1756                          awk '/^repaired_dangling/ { print $2 }')
1757         [ $repaired -ge 32 ] ||
1758                 error "(9) Fail to repair dangling reference: $repaired"
1759
1760         stop_full_debug_logging
1761
1762         echo "stopall to cleanup object cache"
1763         stopall > /dev/null
1764         echo "setupall"
1765         setupall > /dev/null
1766 }
1767 run_test 14a "LFSCK can repair MDT-object with dangling LOV EA reference (1)"
1768
1769 test_14b() {
1770         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1771                 skip "MDS older than 2.5.55, LU-3590"
1772
1773         echo "#####"
1774         echo "The OST-object referenced by the MDT-object should be there;"
1775         echo "otherwise, the LFSCK should re-create the missing OST-object."
1776         echo "with '--delay-create-ostobj' option."
1777         echo "#####"
1778
1779         check_mount_and_prep
1780         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1781
1782         echo "Inject failure stub to simulate dangling referenced MDT-object"
1783         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1784         do_facet ost1 $LCTL set_param fail_loc=0x1610
1785         local count=$(precreated_ost_obj_count 0 0)
1786
1787         createmany -o $DIR/$tdir/f $((count + 31))
1788         touch $DIR/$tdir/guard
1789         do_facet ost1 $LCTL set_param fail_loc=0
1790
1791         start_full_debug_logging
1792
1793         # exhaust other pre-created dangling cases
1794         count=$(precreated_ost_obj_count 0 0)
1795         createmany -o $DIR/$tdir/a $count ||
1796                 error "(0) Fail to create $count files."
1797
1798         echo "'ls' should fail because of dangling referenced MDT-object"
1799         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1800
1801         echo "Trigger layout LFSCK to find out dangling reference"
1802         $START_LAYOUT -r -o -d || error "(2) Fail to start LFSCK for layout!"
1803
1804         wait_all_targets_blocked layout completed 3
1805
1806         local repaired=$($SHOW_LAYOUT |
1807                          awk '/^repaired_dangling/ { print $2 }')
1808         [ $repaired -ge 32 ] ||
1809                 error "(4) Fail to repair dangling reference: $repaired"
1810
1811         echo "'stat' should fail because of not repair dangling by default"
1812         stat $DIR/$tdir/guard > /dev/null 2>&1 && error "(5) stat should fail"
1813
1814         echo "Trigger layout LFSCK to repair dangling reference"
1815         $START_LAYOUT -r -o -c -d || error "(6) Fail to start LFSCK for layout!"
1816
1817         wait_all_targets_blocked layout completed 7
1818
1819         # There may be some async LFSCK updates in processing, wait for
1820         # a while until the target reparation has been done. LU-4970.
1821
1822         echo "'stat' should success after layout LFSCK repairing"
1823         wait_update_facet client "stat $DIR/$tdir/guard |
1824                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1825                 stat $DIR/$tdir/guard
1826                 $SHOW_LAYOUT
1827                 error "(8) unexpected size"
1828         }
1829
1830         repaired=$($SHOW_LAYOUT |
1831                          awk '/^repaired_dangling/ { print $2 }')
1832         [ $repaired -ge 32 ] ||
1833                 error "(9) Fail to repair dangling reference: $repaired"
1834
1835         stop_full_debug_logging
1836
1837         echo "stopall to cleanup object cache"
1838         stopall > /dev/null
1839         echo "setupall"
1840         setupall > /dev/null
1841 }
1842 run_test 14b "LFSCK can repair MDT-object with dangling LOV EA reference (2)"
1843
1844 test_15a() {
1845         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1846                 skip "MDS older than 2.5.55, LU-3591"
1847
1848         echo "#####"
1849         echo "If the OST-object referenced by the MDT-object back points"
1850         echo "to some non-exist MDT-object, then the LFSCK should repair"
1851         echo "the OST-object to back point to the right MDT-object."
1852         echo "#####"
1853
1854         check_mount_and_prep
1855         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1856
1857         echo "Inject failure stub to make the OST-object to back point to"
1858         echo "non-exist MDT-object."
1859         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
1860
1861         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
1862         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1863         $LFS setstripe -E 1M -S 256K -c 1 -E -1 -S 512K -c $OSTCOUNT \
1864                 $DIR/$tdir/f1 ||
1865                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1866         # 'dd' will trigger punch RPC firstly on every OST-objects.
1867         # So even though some OST-object will not be write by 'dd',
1868         # as long as it is allocated (may be NOT allocated in pfl_3b)
1869         # its layout information will be set also.
1870         dd if=/dev/zero of=$DIR/$tdir/f1 bs=4K count=257
1871         cancel_lru_locks osc
1872         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1873
1874         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1875         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1876
1877         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1878                 mdd.${MDT_DEV}.lfsck_layout |
1879                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1880                 $SHOW_LAYOUT
1881                 error "(2) unexpected status"
1882         }
1883
1884         local repaired=$($SHOW_LAYOUT |
1885                          awk '/^repaired_unmatched_pair/ { print $2 }')
1886         [ $repaired -ge 3 ] ||
1887                 error "(3) Fail to repair unmatched pair: $repaired"
1888 }
1889 run_test 15a "LFSCK can repair unmatched MDT-object/OST-object pairs (1)"
1890
1891 test_15b() {
1892         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1893                 skip "MDS older than 2.5.55, LU-3591"
1894
1895         echo "#####"
1896         echo "If the OST-object referenced by the MDT-object back points"
1897         echo "to other MDT-object that doesn't recognize the OST-object,"
1898         echo "then the LFSCK should repair it to back point to the right"
1899         echo "MDT-object (the first one)."
1900         echo "#####"
1901
1902         check_mount_and_prep
1903         mkdir -p $DIR/$tdir/0
1904         $LFS setstripe -c 1 -i 0 $DIR/$tdir/0
1905         dd if=/dev/zero of=$DIR/$tdir/0/guard bs=1M count=1
1906         cancel_lru_locks osc
1907
1908         echo "Inject failure stub to make the OST-object to back point to"
1909         echo "other MDT-object"
1910
1911         local stripes=1
1912         [ $OSTCOUNT -ge 2 ] && stripes=2
1913
1914         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR2  0x1612
1915         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1612
1916         dd if=/dev/zero of=$DIR/$tdir/0/f0 bs=1M count=1
1917         $LFS setstripe -E 1M -S 256K -c $stripes -E 2M -S 512K -c 1 \
1918                 $DIR/$tdir/f1 ||
1919                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1920         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2
1921         cancel_lru_locks osc
1922         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1923
1924         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1925         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1926
1927         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1928                 mdd.${MDT_DEV}.lfsck_layout |
1929                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1930                 $SHOW_LAYOUT
1931                 error "(2) unexpected status"
1932         }
1933
1934         local repaired=$($SHOW_LAYOUT |
1935                          awk '/^repaired_unmatched_pair/ { print $2 }')
1936         [ $repaired -eq 4 ] ||
1937                 error "(3) Fail to repair unmatched pair: $repaired"
1938 }
1939 run_test 15b "LFSCK can repair unmatched MDT-object/OST-object pairs (2)"
1940
1941 test_15c() {
1942         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1943         (( $MDS1_VERSION < $(version_code 2.7.55) )) ||
1944                 skip "MDS newer than 2.7.55, LU-6475"
1945         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1946                 skip "MDS older than 2.5.55, LU-3591"
1947
1948         echo "#####"
1949         echo "According to current metadata migration implementation,"
1950         echo "before the old MDT-object is removed, both the new MDT-object"
1951         echo "and old MDT-object will reference the same LOV layout. Then if"
1952         echo "the layout LFSCK finds the new MDT-object by race, it will"
1953         echo "regard related OST-object(s) as multiple referenced case, and"
1954         echo "will try to create new OST-object(s) for the new MDT-object."
1955         echo "To avoid such trouble, the layout LFSCK needs to lock the old"
1956         echo "MDT-object before confirm the multiple referenced case."
1957         echo "#####"
1958
1959         check_mount_and_prep
1960         $LFS mkdir -i 1 $DIR/$tdir/a1
1961         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
1962         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=1
1963         cancel_lru_locks osc
1964
1965         echo "Inject failure stub on MDT1 to delay the migration"
1966
1967         #define OBD_FAIL_MIGRATE_DELAY                  0x1803
1968         do_facet mds2 $LCTL set_param fail_val=5 fail_loc=0x1803
1969         echo "Migrate $DIR/$tdir/a1 from MDT1 to MDT0 with delay"
1970         $LFS migrate -m 0 $DIR/$tdir/a1 &
1971
1972         sleep 1
1973         echo "Trigger layout LFSCK to race with the migration"
1974         $START_LAYOUT -A -r || error "(1) Fail to start layout LFSCK!"
1975
1976         wait_all_targets_blocked layout completed 2
1977
1978         do_facet mds2 $LCTL set_param fail_loc=0 fail_val=0
1979         local repaired=$($SHOW_LAYOUT |
1980                          awk '/^repaired_unmatched_pair/ { print $2 }')
1981         [ $repaired -eq 1 ] ||
1982                 error "(3) Fail to repair unmatched pair: $repaired"
1983
1984         repaired=$($SHOW_LAYOUT |
1985                    awk '/^repaired_multiple_referenced/ { print $2 }')
1986         [ $repaired -eq 0 ] ||
1987                 error "(4) Unexpectedly repaird multiple references: $repaired"
1988 }
1989 run_test 15c "LFSCK can repair unmatched MDT-object/OST-object pairs (3)"
1990
1991 test_16() {
1992         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1993                 skip "MDS older than 2.5.55, LU-3594"
1994
1995         echo "#####"
1996         echo "If the OST-object's owner information does not match the owner"
1997         echo "information stored in the MDT-object, then the LFSCK trust the"
1998         echo "MDT-object and update the OST-object's owner information."
1999         echo "#####"
2000
2001         check_mount_and_prep
2002         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2003         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
2004         cancel_lru_locks osc
2005
2006         # created but no setattr or write to the file.
2007         mkdir $DIR/$tdir/d1
2008         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/d1
2009         $RUNAS createmany -o $DIR/$tdir/d1/o 100 || error "create failed"
2010
2011         echo "Inject failure stub to skip OST-object owner changing"
2012         #define OBD_FAIL_LFSCK_BAD_OWNER        0x1613
2013         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1613
2014         chown 1.1 $DIR/$tdir/f0
2015         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2016
2017         echo "Trigger layout LFSCK to find out inconsistent OST-object owner"
2018         echo "and fix them"
2019
2020         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
2021
2022         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2023                 mdd.${MDT_DEV}.lfsck_layout |
2024                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2025                 $SHOW_LAYOUT
2026                 error "(2) unexpected status"
2027         }
2028
2029         local repaired=$($SHOW_LAYOUT |
2030                          awk '/^repaired_inconsistent_owner/ { print $2 }')
2031         [ $repaired -eq 1 ] ||
2032                 error "(3) Fail to repair inconsistent owner: $repaired"
2033 }
2034 run_test 16 "LFSCK can repair inconsistent MDT-object/OST-object owner"
2035
2036 test_17() {
2037         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2038                 skip "MDS older than 2.5.55, LU-3594"
2039
2040         echo "#####"
2041         echo "If more than one MDT-objects reference the same OST-object,"
2042         echo "and the OST-object only recognizes one MDT-object, then the"
2043         echo "LFSCK should create new OST-objects for such non-recognized"
2044         echo "MDT-objects."
2045         echo "#####"
2046
2047         check_mount_and_prep
2048         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2049
2050         echo "Inject failure stub to make two MDT-objects to refernce"
2051         echo "the OST-object"
2052
2053         #define OBD_FAIL_LFSCK_MULTIPLE_REF     0x1614
2054         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0x1614
2055         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
2056         cancel_lru_locks mdc
2057         cancel_lru_locks osc
2058
2059         createmany -o $DIR/$tdir/f 1
2060         cancel_lru_locks mdc
2061         cancel_lru_locks osc
2062
2063         $LFS setstripe -E 2M -S 256K -o 0 -E 4M -S 512K -o 0 \
2064                 $DIR/$tdir/f1 ||
2065                 error "(0) Fail to create PFL $DIR/$tdir/f1"
2066         cancel_lru_locks mdc
2067         cancel_lru_locks osc
2068         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
2069
2070         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard use the same OST-objects"
2071         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard use the same OST-objects"
2072         local size=$(ls -l $DIR/$tdir/f0 | awk '{ print $5 }')
2073         [ $size -eq 1048576 ] ||
2074                 error "(1.1) f0 (wrong) size should be 1048576, but got $size"
2075
2076         size=$(ls -l $DIR/$tdir/f1 | awk '{ print $5 }')
2077         [ $size -eq 1048576 ] ||
2078                 error "(1.2) f1 (wrong) size should be 1048576, but got $size"
2079
2080         echo "Trigger layout LFSCK to find out multiple refenced MDT-objects"
2081         echo "and fix them"
2082
2083         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
2084
2085         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2086                 mdd.${MDT_DEV}.lfsck_layout |
2087                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2088                 $SHOW_LAYOUT
2089                 error "(3) unexpected status"
2090         }
2091
2092         local repaired=$($SHOW_LAYOUT |
2093                          awk '/^repaired_multiple_referenced/ { print $2 }')
2094         [ $repaired -eq 2 ] ||
2095                 error "(4) Fail to repair multiple references: $repaired"
2096
2097         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard should use diff OST-objects"
2098         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=2 ||
2099                 error "(5) Fail to write f0."
2100         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
2101         [ $size -eq 1048576 ] ||
2102                 error "(6) guard size should be 1048576, but got $size"
2103
2104         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard should use diff OST-objects"
2105         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2 ||
2106                 error "(7) Fail to write f1."
2107         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
2108         [ $size -eq 1048576 ] ||
2109                 error "(8) guard size should be 1048576, but got $size"
2110 }
2111 run_test 17 "LFSCK can repair multiple references"
2112
2113 $LCTL set_param debug=+cache > /dev/null
2114
2115 test_18a() {
2116         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2117                 skip "MDS older than 2.5.55, LU-3336"
2118
2119         echo "#####"
2120         echo "The target MDT-object is there, but related stripe information"
2121         echo "is lost or partly lost. The LFSCK should regenerate the missing"
2122         echo "layout EA entries."
2123         echo "#####"
2124
2125         check_mount_and_prep
2126         $LFS mkdir -i 0 $DIR/$tdir/a1
2127         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2128         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2129
2130         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2131
2132         $LFS path2fid $DIR/$tdir/a1/f1
2133         $LFS getstripe $DIR/$tdir/a1/f1
2134
2135         if [ $MDSCOUNT -ge 2 ]; then
2136                 $LFS mkdir -i 1 $DIR/$tdir/a2
2137                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2138                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2139                 $LFS path2fid $DIR/$tdir/a2/f2
2140                 $LFS getstripe $DIR/$tdir/a2/f2
2141         fi
2142
2143         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2144                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2145
2146         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2147
2148         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2149
2150         $LFS path2fid $DIR/$tdir/f3
2151         $LFS getstripe $DIR/$tdir/f3
2152
2153         cancel_lru_locks osc
2154
2155         echo "Inject failure, to make the MDT-object lost its layout EA"
2156         #define OBD_FAIL_LFSCK_LOST_STRIPE 0x1615
2157         do_facet mds1 $LCTL set_param fail_loc=0x1615
2158         chown 1.1 $DIR/$tdir/a1/f1
2159
2160         if [ $MDSCOUNT -ge 2 ]; then
2161                 do_facet mds2 $LCTL set_param fail_loc=0x1615
2162                 chown 1.1 $DIR/$tdir/a2/f2
2163         fi
2164
2165         chown 1.1 $DIR/$tdir/f3
2166
2167         sync
2168         sleep 2
2169
2170         do_facet mds1 $LCTL set_param fail_loc=0
2171         if [ $MDSCOUNT -ge 2 ]; then
2172                 do_facet mds2 $LCTL set_param fail_loc=0
2173         fi
2174
2175         cancel_lru_locks mdc
2176         cancel_lru_locks osc
2177
2178         echo "The file size should be incorrect since layout EA is lost"
2179         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2180         [ "$cur_size" != "$saved_size1" ] ||
2181                 error "(1) Expect incorrect file1 size"
2182
2183         if [ $MDSCOUNT -ge 2 ]; then
2184                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2185                 [ "$cur_size" != "$saved_size1" ] ||
2186                         error "(2) Expect incorrect file2 size"
2187         fi
2188
2189         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2190         [ "$cur_size" != "$saved_size2" ] ||
2191                 error "(1.2) Expect incorrect file3 size"
2192
2193         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2194         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
2195
2196         for k in $(seq $MDSCOUNT); do
2197                 # The LFSCK status query internal is 30 seconds. For the case
2198                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2199                 # time to guarantee the status sync up.
2200                 wait_update_facet mds${k} "$LCTL get_param -n \
2201                         mdd.$(facet_svc mds${k}).lfsck_layout |
2202                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2203                         error "(4) MDS${k} is not the expected 'completed'"
2204         done
2205
2206         for k in $(seq $OSTCOUNT); do
2207                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2208                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2209                                 awk '/^status/ { print $2 }')
2210                 [ "$cur_status" == "completed" ] ||
2211                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2212         done
2213
2214         local repaired=$(do_facet mds1 $LCTL get_param -n \
2215                          mdd.$(facet_svc mds1).lfsck_layout |
2216                          awk '/^repaired_orphan/ { print $2 }')
2217         [ $repaired -eq 3 ] ||
2218         error "(6.1) Expect 3 fixed on mds1, but got: $repaired"
2219
2220         if [ $MDSCOUNT -ge 2 ]; then
2221                 repaired=$(do_facet mds2 $LCTL get_param -n \
2222                          mdd.$(facet_svc mds2).lfsck_layout |
2223                                  awk '/^repaired_orphan/ { print $2 }')
2224                 [ $repaired -eq 2 ] ||
2225                 error "(6.2) Expect 2 fixed on mds2, but got: $repaired"
2226         fi
2227
2228         $LFS path2fid $DIR/$tdir/a1/f1
2229         $LFS getstripe $DIR/$tdir/a1/f1
2230
2231         if [ $MDSCOUNT -ge 2 ]; then
2232                 $LFS path2fid $DIR/$tdir/a2/f2
2233                 $LFS getstripe $DIR/$tdir/a2/f2
2234         fi
2235
2236         $LFS path2fid $DIR/$tdir/f3
2237         $LFS getstripe $DIR/$tdir/f3
2238
2239         echo "The file size should be correct after layout LFSCK scanning"
2240         cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2241         [ "$cur_size" == "$saved_size1" ] ||
2242                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2243
2244         if [ $MDSCOUNT -ge 2 ]; then
2245                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2246                 [ "$cur_size" == "$saved_size1" ] ||
2247                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2248         fi
2249
2250         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2251         [ "$cur_size" == "$saved_size2" ] ||
2252                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2253 }
2254 run_test 18a "Find out orphan OST-object and repair it (1)"
2255
2256 test_18b() {
2257         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2258         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2259                 skip "MDS older than 2.5.55, LU-3336"
2260
2261         echo "#####"
2262         echo "The target MDT-object is lost. The LFSCK should re-create the"
2263         echo "MDT-object under .lustre/lost+found/MDTxxxx. The admin should"
2264         echo "can move it back to normal namespace manually."
2265         echo "#####"
2266
2267         check_mount_and_prep
2268         $LFS mkdir -i 0 $DIR/$tdir/a1
2269         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2270         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2271         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2272         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2273         echo ${fid1}
2274         $LFS getstripe $DIR/$tdir/a1/f1
2275
2276         if [ $MDSCOUNT -ge 2 ]; then
2277                 $LFS mkdir -i 1 $DIR/$tdir/a2
2278                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2279                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2280                 fid2=$($LFS path2fid $DIR/$tdir/a2/f2)
2281                 echo ${fid2}
2282                 $LFS getstripe $DIR/$tdir/a2/f2
2283         fi
2284
2285         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2286                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2287
2288         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2289
2290         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2291         local fid3=$($LFS path2fid $DIR/$tdir/f3)
2292         echo ${fid3}
2293         $LFS getstripe $DIR/$tdir/f3
2294
2295         cancel_lru_locks osc
2296
2297         echo "Inject failure, to simulate the case of missing the MDT-object"
2298         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2299         do_facet mds1 $LCTL set_param fail_loc=0x1616
2300         rm -f $DIR/$tdir/a1/f1
2301
2302         if [ $MDSCOUNT -ge 2 ]; then
2303                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2304                 rm -f $DIR/$tdir/a2/f2
2305         fi
2306
2307         rm -f $DIR/$tdir/f3
2308
2309         sync
2310         sleep 2
2311
2312         do_facet mds1 $LCTL set_param fail_loc=0
2313         if [ $MDSCOUNT -ge 2 ]; then
2314                 do_facet mds2 $LCTL set_param fail_loc=0
2315         fi
2316
2317         cancel_lru_locks mdc
2318         cancel_lru_locks osc
2319
2320         # dryrun mode only check orphans, not repaie
2321         echo "Trigger layout LFSCK --dryrun to find out orphan OST-object"
2322         $START_LAYOUT --dryrun -o -r ||
2323                 error "Fail to start layout LFSCK in dryrun mode"
2324         wait_all_targets_blocked layout completed 2
2325
2326         local PARAMS=$($SHOW_LAYOUT | awk '/^param/ { print $2 }')
2327         [ "$PARAMS" == "dryrun,all_targets,orphan" ] ||
2328                 error "Expect 'dryrun,all_targets,orphan', got '$PARAMS'"
2329
2330         local orphans=$(do_facet mds1 $LCTL get_param -n \
2331                         mdd.$(facet_svc mds1).lfsck_layout |
2332                         awk '/^inconsistent_orphan/ { print $2 }')
2333         [ $orphans -eq 3 ] ||
2334                 error "Expect 3 found on mds1, but got: $orphans"
2335
2336         # orphan parents should not be created
2337         local subdir
2338         for subdir in $MOUNT/.lustre/lost+found/*; do
2339                 [ ! "$(ls -A $subdir)" ] || error "$subdir not empty"
2340         done
2341
2342         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2343         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2344
2345         for k in $(seq $MDSCOUNT); do
2346                 # The LFSCK status query internal is 30 seconds. For the case
2347                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2348                 # time to guarantee the status sync up.
2349                 wait_update_facet mds${k} "$LCTL get_param -n \
2350                         mdd.$(facet_svc mds${k}).lfsck_layout |
2351                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2352                         error "(2) MDS${k} is not the expected 'completed'"
2353         done
2354
2355         for k in $(seq $OSTCOUNT); do
2356                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2357                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2358                                 awk '/^status/ { print $2 }')
2359                 [ "$cur_status" == "completed" ] ||
2360                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2361         done
2362
2363         local repaired=$(do_facet mds1 $LCTL get_param -n \
2364                          mdd.$(facet_svc mds1).lfsck_layout |
2365                          awk '/^repaired_orphan/ { print $2 }')
2366         [ $repaired -eq 3 ] ||
2367         error "(4.1) Expect 3 fixed on mds1, but got: $repaired"
2368
2369         if [ $MDSCOUNT -ge 2 ]; then
2370                 repaired=$(do_facet mds2 $LCTL get_param -n \
2371                          mdd.$(facet_svc mds2).lfsck_layout |
2372                          awk '/^repaired_orphan/ { print $2 }')
2373                 [ $repaired -eq 2 ] ||
2374                 error "(4.2) Expect 2 fixed on mds2, but got: $repaired"
2375         fi
2376
2377         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2378         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2379         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2380
2381         if [ $MDSCOUNT -ge 2 ]; then
2382                 local name=$MOUNT/.lustre/lost+found/MDT0001/${fid2}-R-0
2383                 mv $name $DIR/$tdir/a2/f2 || error "(6) Fail to move $name"
2384         fi
2385
2386         mv $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0 $DIR/$tdir/f3 ||
2387         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
2388
2389         $LFS path2fid $DIR/$tdir/a1/f1
2390         $LFS getstripe $DIR/$tdir/a1/f1
2391
2392         if [ $MDSCOUNT -ge 2 ]; then
2393                 $LFS path2fid $DIR/$tdir/a2/f2
2394                 $LFS getstripe $DIR/$tdir/a2/f2
2395         fi
2396
2397         $LFS path2fid $DIR/$tdir/f3
2398         $LFS getstripe $DIR/$tdir/f3
2399
2400         echo "The file size should be correct after layout LFSCK scanning"
2401         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2402         [ "$cur_size" == "$saved_size1" ] ||
2403                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2404
2405         if [ $MDSCOUNT -ge 2 ]; then
2406                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2407                 [ "$cur_size" == "$saved_size1" ] ||
2408                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2409         fi
2410
2411         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2412         [ "$cur_size" == "$saved_size2" ] ||
2413                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2414 }
2415 run_test 18b "Find out orphan OST-object and repair it (2)"
2416
2417 test_18c() {
2418         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2419         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2420                 skip "MDS older than 2.5.55, LU-3336"
2421
2422         echo "#####"
2423         echo "The target MDT-object is lost, and the OST-object FID is missing."
2424         echo "The LFSCK should re-create the MDT-object with new FID under the "
2425         echo "directory .lustre/lost+found/MDTxxxx."
2426         echo "#####"
2427
2428         check_mount_and_prep
2429         $LFS mkdir -i 0 $DIR/$tdir/a1
2430         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2431
2432         echo "Inject failure, to simulate the case of missing parent FID"
2433         #define OBD_FAIL_LFSCK_NOPFID           0x1617
2434         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1617
2435
2436         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2437         $LFS getstripe $DIR/$tdir/a1/f1
2438
2439         if [ $MDSCOUNT -ge 2 ]; then
2440                 $LFS mkdir -i 1 $DIR/$tdir/a2
2441                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a2
2442                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2443                 $LFS getstripe $DIR/$tdir/a2/f2
2444         fi
2445
2446         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2447                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2448
2449         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2450         $LFS getstripe $DIR/$tdir/f3
2451
2452         cancel_lru_locks osc
2453         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
2454
2455         echo "Inject failure, to simulate the case of missing the MDT-object"
2456         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2457         do_facet mds1 $LCTL set_param fail_loc=0x1616
2458         rm -f $DIR/$tdir/a1/f1
2459
2460         if [ $MDSCOUNT -ge 2 ]; then
2461                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2462                 rm -f $DIR/$tdir/a2/f2
2463         fi
2464
2465         rm -f $DIR/$tdir/f3
2466
2467         sync
2468         sleep 2
2469
2470         do_facet mds1 $LCTL set_param fail_loc=0
2471         if [ $MDSCOUNT -ge 2 ]; then
2472                 do_facet mds2 $LCTL set_param fail_loc=0
2473         fi
2474
2475         cancel_lru_locks mdc
2476         cancel_lru_locks osc
2477
2478         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2479         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2480
2481         for k in $(seq $MDSCOUNT); do
2482                 # The LFSCK status query internal is 30 seconds. For the case
2483                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2484                 # time to guarantee the status sync up.
2485                 wait_update_facet mds${k} "$LCTL get_param -n \
2486                         mdd.$(facet_svc mds${k}).lfsck_layout |
2487                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2488                         error "(2) MDS${k} is not the expected 'completed'"
2489         done
2490
2491         for k in $(seq $OSTCOUNT); do
2492                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2493                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2494                                 awk '/^status/ { print $2 }')
2495                 [ "$cur_status" == "completed" ] ||
2496                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2497         done
2498
2499         if [ $MDSCOUNT -ge 2 ]; then
2500                 expected=4
2501         else
2502                 expected=3
2503         fi
2504
2505         local repaired=$(do_facet mds1 $LCTL get_param -n \
2506                          mdd.$(facet_svc mds1).lfsck_layout |
2507                          awk '/^repaired_orphan/ { print $2 }')
2508         [ $repaired -eq $expected ] ||
2509                 error "(4) Expect $expected fixed on mds1, but got: $repaired"
2510
2511         if [ $MDSCOUNT -ge 2 ]; then
2512                 repaired=$(do_facet mds2 $LCTL get_param -n \
2513                            mdd.$(facet_svc mds2).lfsck_layout |
2514                            awk '/^repaired_orphan/ { print $2 }')
2515                 [ $repaired -eq 0 ] ||
2516                         error "(5) Expect 0 fixed on mds2, but got: $repaired"
2517         fi
2518
2519         ls -ail $MOUNT/.lustre/lost+found/
2520
2521         echo "There should NOT be some stub under .lustre/lost+found/MDT0001/"
2522         if [ -d $MOUNT/.lustre/lost+found/MDT0001 ]; then
2523                 cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-N-*)
2524                 [ -z "$cname" ] ||
2525                         error "(6) .lustre/lost+found/MDT0001/ should be empty"
2526         fi
2527
2528         echo "There should be some stub under .lustre/lost+found/MDT0000/"
2529         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2530                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2531
2532         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-N-*)
2533         [ ! -z "$cname" ] ||
2534                 error "(8) .lustre/lost+found/MDT0000/ should not be empty"
2535 }
2536 run_test 18c "Find out orphan OST-object and repair it (3)"
2537
2538 test_18d() {
2539         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2540                 skip "MDS older than 2.5.55, LU-3336"
2541
2542         echo "#####"
2543         echo "The target MDT-object layout EA is corrupted, but the right"
2544         echo "OST-object is still alive as orphan. The layout LFSCK will"
2545         echo "not create new OST-object to occupy such slot."
2546         echo "#####"
2547
2548         check_mount_and_prep
2549         mkdir $DIR/$tdir/a1
2550         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2551         echo "guard" > $DIR/$tdir/a1/f1
2552         echo "foo" > $DIR/$tdir/a1/f2
2553
2554         echo "guard" > $DIR/$tdir/a1/f3
2555         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2556                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2557         echo "foo" > $DIR/$tdir/a1/f4
2558
2559         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2560         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2561         $LFS path2fid $DIR/$tdir/a1/f1
2562         $LFS getstripe $DIR/$tdir/a1/f1
2563         $LFS path2fid $DIR/$tdir/a1/f2
2564         $LFS getstripe $DIR/$tdir/a1/f2
2565         $LFS path2fid $DIR/$tdir/a1/f3
2566         $LFS getstripe $DIR/$tdir/a1/f3
2567         $LFS path2fid $DIR/$tdir/a1/f4
2568         $LFS getstripe $DIR/$tdir/a1/f4
2569         cancel_lru_locks osc
2570
2571         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2572         echo "to reference the same OST-object (which is f1's OST-obejct)."
2573         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2574         echo "dangling reference case, but f2's old OST-object is there."
2575
2576         echo "The failure also makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2577         echo "to reference the same OST-object (which is f3's OST-obejct)."
2578         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2579         echo "dangling reference case, but f4's old OST-object is there."
2580         echo
2581
2582         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2583         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2584         chown 1.1 $DIR/$tdir/a1/f2
2585         chown 1.1 $DIR/$tdir/a1/f4
2586         rm -f $DIR/$tdir/a1/f1
2587         rm -f $DIR/$tdir/a1/f3
2588         sync
2589         sleep 2
2590         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2591
2592         echo "stopall to cleanup object cache"
2593         stopall > /dev/null
2594         echo "setupall"
2595         setupall > /dev/null
2596
2597         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2598         $START_LAYOUT -r -o -c -d || error "(2) Fail to start LFSCK for layout!"
2599
2600         for k in $(seq $MDSCOUNT); do
2601                 # The LFSCK status query internal is 30 seconds. For the case
2602                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2603                 # time to guarantee the status sync up.
2604                 wait_update_facet mds${k} "$LCTL get_param -n \
2605                         mdd.$(facet_svc mds${k}).lfsck_layout |
2606                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2607                         error "(3) MDS${k} is not the expected 'completed'"
2608         done
2609
2610         for k in $(seq $OSTCOUNT); do
2611                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2612                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2613                                 awk '/^status/ { print $2 }')
2614                 [ "$cur_status" == "completed" ] ||
2615                 error "(4) OST${k} Expect 'completed', but got '$cur_status'"
2616         done
2617
2618         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2619                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2620                          awk '/^repaired_orphan/ { print $2 }')
2621         [ $repaired -eq 2 ] ||
2622                 error "(5) Expect 2 orphans have been fixed, but got: $repaired"
2623
2624         repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2625                    mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2626                    awk '/^repaired_dangling/ { print $2 }')
2627         [ $repaired -eq 0 ] ||
2628                 error "(6) Expect 0 dangling has been fixed, but got: $repaired"
2629
2630         echo "The file size should be correct after layout LFSCK scanning"
2631         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2632         [ "$cur_size" == "$saved_size1" ] ||
2633                 error "(7) Expect file2 size $saved_size1, but got $cur_size"
2634
2635         cur_size=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2636         [ "$cur_size" == "$saved_size2" ] ||
2637                 error "(8) Expect file4 size $saved_size2, but got $cur_size"
2638
2639         echo "The LFSCK should find back the original data."
2640         cat $DIR/$tdir/a1/f2
2641         $LFS path2fid $DIR/$tdir/a1/f2
2642         $LFS getstripe $DIR/$tdir/a1/f2
2643         cat $DIR/$tdir/a1/f4
2644         $LFS path2fid $DIR/$tdir/a1/f4
2645         $LFS getstripe $DIR/$tdir/a1/f4
2646 }
2647 run_test 18d "Find out orphan OST-object and repair it (4)"
2648
2649 test_18e() {
2650         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2651         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2652                 skip "MDS older than 2.5.55, LU-3336"
2653
2654         echo "#####"
2655         echo "The target MDT-object layout EA slot is occpuied by some new"
2656         echo "created OST-object when repair dangling reference case. Such"
2657         echo "conflict OST-object has been modified by others. To keep the"
2658         echo "new data, the LFSCK will create a new file to refernece this"
2659         echo "old orphan OST-object."
2660         echo "#####"
2661
2662         check_mount_and_prep
2663         mkdir $DIR/$tdir/a1
2664         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2665         echo "guard" > $DIR/$tdir/a1/f1
2666         echo "foo" > $DIR/$tdir/a1/f2
2667
2668         echo "guard" > $DIR/$tdir/a1/f3
2669         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2670                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2671         echo "foo" > $DIR/$tdir/a1/f4
2672
2673         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2674         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2675
2676         $LFS path2fid $DIR/$tdir/a1/f1
2677         $LFS getstripe $DIR/$tdir/a1/f1
2678         $LFS path2fid $DIR/$tdir/a1/f2
2679         $LFS getstripe $DIR/$tdir/a1/f2
2680         $LFS path2fid $DIR/$tdir/a1/f3
2681         $LFS getstripe $DIR/$tdir/a1/f3
2682         $LFS path2fid $DIR/$tdir/a1/f4
2683         $LFS getstripe $DIR/$tdir/a1/f4
2684         cancel_lru_locks osc
2685
2686         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2687         echo "to reference the same OST-object (which is f1's OST-obejct)."
2688         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2689         echo "dangling reference case, but f2's old OST-object is there."
2690
2691         echo "Also the failure makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2692         echo "to reference the same OST-object (which is f3's OST-obejct)."
2693         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2694         echo "dangling reference case, but f4's old OST-object is there."
2695         echo
2696
2697         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2698         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2699         chown 1.1 $DIR/$tdir/a1/f2
2700         chown 1.1 $DIR/$tdir/a1/f4
2701         rm -f $DIR/$tdir/a1/f1
2702         rm -f $DIR/$tdir/a1/f3
2703         sync
2704         sleep 2
2705         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2706
2707         echo "stopall to cleanup object cache"
2708         stopall > /dev/null
2709         echo "setupall"
2710         setupall > /dev/null
2711
2712         #define OBD_FAIL_LFSCK_DELAY3           0x1602
2713         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
2714
2715         start_full_debug_logging
2716
2717         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2718         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
2719
2720         wait_update_facet mds1 "$LCTL get_param -n \
2721                 mdd.$(facet_svc mds1).lfsck_layout |
2722                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" $LTIME ||
2723                 error "(3) MDS1 is not the expected 'scanning-phase2'"
2724
2725         # to guarantee all updates are synced.
2726         sync
2727         sleep 2
2728
2729         echo "Write new data to f2/f4 to modify the new created OST-object."
2730         echo "dummy" >> $DIR/$tdir/a1/f2 || error "write a1/f2 failed"
2731         echo "dummy" >> $DIR/$tdir/a1/f4 || error "write a1/f4 failed"
2732
2733         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2734
2735         for k in $(seq $MDSCOUNT); do
2736                 # The LFSCK status query internal is 30 seconds. For the case
2737                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2738                 # time to guarantee the status sync up.
2739                 wait_update_facet mds${k} "$LCTL get_param -n \
2740                         mdd.$(facet_svc mds${k}).lfsck_layout |
2741                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2742                         error "(4) MDS${k} is not the expected 'completed'"
2743         done
2744
2745         for k in $(seq $OSTCOUNT); do
2746                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2747                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2748                                 awk '/^status/ { print $2 }')
2749                 [ "$cur_status" == "completed" ] ||
2750                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2751         done
2752
2753         stop_full_debug_logging
2754
2755         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2756                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2757                          awk '/^repaired_orphan/ { print $2 }')
2758         [ $repaired -eq 2 ] ||
2759                 error "(6) Expect 2 orphans have been fixed, but got: $repaired"
2760
2761         echo "There should be stub file under .lustre/lost+found/MDT0000/"
2762         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2763                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2764
2765         local count=$(ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-* | wc -l)
2766         if [ $count -ne 2 ]; then
2767                 ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-*
2768                 error "(8) Expect 2 stubs under lost+found, but got $count"
2769         fi
2770
2771         echo "The stub file should keep the original f2 or f4 data"
2772         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | head -n 1)
2773         local cur_size=$(ls -il $cname | awk '{ print $6 }')
2774         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2775                 error "(9) Got unexpected $cur_size"
2776
2777         cat $cname
2778         $LFS path2fid $cname
2779         $LFS getstripe $cname
2780
2781         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | tail -n 1)
2782         cur_size=$(ls -il $cname | awk '{ print $6 }')
2783         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2784                 error "(10) Got unexpected $cur_size"
2785
2786         cat $cname
2787         $LFS path2fid $cname
2788         $LFS getstripe $cname
2789
2790         echo "The f2/f4 should contains new data."
2791         cat $DIR/$tdir/a1/f2
2792         $LFS path2fid $DIR/$tdir/a1/f2
2793         $LFS getstripe $DIR/$tdir/a1/f2
2794         cat $DIR/$tdir/a1/f4
2795         $LFS path2fid $DIR/$tdir/a1/f4
2796         $LFS getstripe $DIR/$tdir/a1/f4
2797 }
2798 run_test 18e "Find out orphan OST-object and repair it (5)"
2799
2800 test_18f() {
2801         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2802
2803         echo "#####"
2804         echo "The target MDT-object is lost. The LFSCK should re-create the"
2805         echo "MDT-object under .lustre/lost+found/MDTxxxx. If some OST fail"
2806         echo "to verify some OST-object(s) during the first stage-scanning,"
2807         echo "the LFSCK should skip orphan OST-objects for such OST. Others"
2808         echo "should not be affected."
2809         echo "#####"
2810
2811         check_mount_and_prep
2812         $LFS mkdir -i 0 $DIR/$tdir/a1
2813         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2814         dd if=/dev/zero of=$DIR/$tdir/a1/guard bs=1M count=2
2815         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2816         $LFS mkdir -i 0 $DIR/$tdir/a2
2817         $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a2
2818         dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2819         $LFS getstripe $DIR/$tdir/a1/f1
2820         $LFS getstripe $DIR/$tdir/a2/f2
2821
2822         if [ $MDSCOUNT -ge 2 ]; then
2823                 $LFS mkdir -i 1 $DIR/$tdir/a3
2824                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a3
2825                 dd if=/dev/zero of=$DIR/$tdir/a3/guard bs=1M count=2
2826                 dd if=/dev/zero of=$DIR/$tdir/a3/f3 bs=1M count=2
2827                 $LFS mkdir -i 1 $DIR/$tdir/a4
2828                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a4
2829                 dd if=/dev/zero of=$DIR/$tdir/a4/f4 bs=1M count=2
2830                 $LFS getstripe $DIR/$tdir/a3/f3
2831                 $LFS getstripe $DIR/$tdir/a4/f4
2832         fi
2833
2834         cancel_lru_locks osc
2835
2836         echo "Inject failure, to simulate the case of missing the MDT-object"
2837         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2838         do_facet mds1 $LCTL set_param fail_loc=0x1616
2839         rm -f $DIR/$tdir/a1/f1
2840         rm -f $DIR/$tdir/a2/f2
2841
2842         if [ $MDSCOUNT -ge 2 ]; then
2843                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2844                 rm -f $DIR/$tdir/a3/f3
2845                 rm -f $DIR/$tdir/a4/f4
2846         fi
2847
2848         sync
2849         sleep 2
2850
2851         do_facet mds1 $LCTL set_param fail_loc=0
2852         if [ $MDSCOUNT -ge 2 ]; then
2853                 do_facet mds2 $LCTL set_param fail_loc=0
2854         fi
2855
2856         cancel_lru_locks mdc
2857         cancel_lru_locks osc
2858
2859         echo "Inject failure, to simulate the OST0 fail to handle"
2860         echo "MDT0 LFSCK request during the first-stage scanning."
2861         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
2862         do_facet mds1 $LCTL set_param fail_loc=0x161c fail_val=0
2863
2864         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2865         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2866
2867         for k in $(seq $MDSCOUNT); do
2868                 # The LFSCK status query internal is 30 seconds. For the case
2869                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2870                 # time to guarantee the status sync up.
2871                 wait_update_facet mds${k} "$LCTL get_param -n \
2872                         mdd.$(facet_svc mds${k}).lfsck_layout |
2873                         awk '/^status/ { print \\\$2 }'" "partial" $LTIME ||
2874                         error "(2) MDS${k} is not the expected 'partial'"
2875         done
2876
2877         wait_update_facet ost1 "$LCTL get_param -n \
2878                 obdfilter.$(facet_svc ost1).lfsck_layout |
2879                 awk '/^status/ { print \\\$2 }'" "partial" $LTIME || {
2880                 error "(3) OST1 is not the expected 'partial'"
2881         }
2882
2883         wait_update_facet ost2 "$LCTL get_param -n \
2884                 obdfilter.$(facet_svc ost2).lfsck_layout |
2885                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME || {
2886                 error "(4) OST2 is not the expected 'completed'"
2887         }
2888
2889         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2890
2891         local repaired=$(do_facet mds1 $LCTL get_param -n \
2892                          mdd.$(facet_svc mds1).lfsck_layout |
2893                          awk '/^repaired_orphan/ { print $2 }')
2894         [ $repaired -eq 1 ] ||
2895                 error "(5) Expect 1 fixed on mds{1}, but got: $repaired"
2896
2897         if [ $MDSCOUNT -ge 2 ]; then
2898                 repaired=$(do_facet mds2 $LCTL get_param -n \
2899                          mdd.$(facet_svc mds2).lfsck_layout |
2900                          awk '/^repaired_orphan/ { print $2 }')
2901                 [ $repaired -eq 1 ] ||
2902                 error "(6) Expect 1 fixed on mds{2}, but got: $repaired"
2903         fi
2904
2905         echo "Trigger layout LFSCK on all devices again to cleanup"
2906         $START_LAYOUT -r -o || error "(7) Fail to start LFSCK for layout!"
2907
2908         for k in $(seq $MDSCOUNT); do
2909                 # The LFSCK status query internal is 30 seconds. For the case
2910                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2911                 # time to guarantee the status sync up.
2912                 wait_update_facet mds${k} "$LCTL get_param -n \
2913                         mdd.$(facet_svc mds${k}).lfsck_layout |
2914                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2915                         error "(8) MDS${k} is not the expected 'completed'"
2916         done
2917
2918         for k in $(seq $OSTCOUNT); do
2919                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2920                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2921                              awk '/^status/ { print $2 }')
2922                 [ "$cur_status" == "completed" ] ||
2923                 error "(9) OST${k} Expect 'completed', but got '$cur_status'"
2924
2925         done
2926
2927         local repaired=$(do_facet mds1 $LCTL get_param -n \
2928                          mdd.$(facet_svc mds1).lfsck_layout |
2929                          awk '/^repaired_orphan/ { print $2 }')
2930         [ $repaired -eq 2 ] ||
2931                 error "(10) Expect 2 fixed on mds{1}, but got: $repaired"
2932
2933         if [ $MDSCOUNT -ge 2 ]; then
2934                 repaired=$(do_facet mds2 $LCTL get_param -n \
2935                          mdd.$(facet_svc mds2).lfsck_layout |
2936                          awk '/^repaired_orphan/ { print $2 }')
2937                 [ $repaired -eq 2 ] ||
2938                 error "(11) Expect 2 fixed on mds{2}, but got: $repaired"
2939         fi
2940 }
2941 run_test 18f "Skip the failed OST(s) when handle orphan OST-objects"
2942
2943 test_18g() {
2944         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2945
2946         echo "#####"
2947         echo "The target MDT-object is lost, but related OI mapping is there"
2948         echo "The LFSCK should recreate the lost MDT-object without affected"
2949         echo "by the stale OI mapping."
2950         echo "#####"
2951
2952         check_mount_and_prep
2953         $LFS mkdir -i 0 $DIR/$tdir/a1
2954         $LFS setstripe -c -1 -i 0 -S 1M $DIR/$tdir/a1
2955         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=$OSTCOUNT
2956         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2957         echo ${fid1}
2958         $LFS getstripe $DIR/$tdir/a1/f1
2959         cancel_lru_locks osc
2960
2961         echo "Inject failure to simulate lost MDT-object but keep OI mapping"
2962         #define OBD_FAIL_LFSCK_LOST_MDTOBJ2     0x162e
2963         do_facet mds1 $LCTL set_param fail_loc=0x162e
2964         rm -f $DIR/$tdir/a1/f1
2965
2966         do_facet mds1 $LCTL set_param fail_loc=0
2967         cancel_lru_locks mdc
2968         cancel_lru_locks osc
2969
2970         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2971         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2972
2973         for k in $(seq $MDSCOUNT); do
2974                 # The LFSCK status query internal is 30 seconds. For the case
2975                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2976                 # time to guarantee the status sync up.
2977                 wait_update_facet mds${k} "$LCTL get_param -n \
2978                         mdd.$(facet_svc mds${k}).lfsck_layout |
2979                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2980                         error "(2) MDS${k} is not the expected 'completed'"
2981         done
2982
2983         for k in $(seq $OSTCOUNT); do
2984                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2985                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2986                                 awk '/^status/ { print $2 }')
2987                 [ "$cur_status" == "completed" ] ||
2988                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2989         done
2990
2991         local repaired=$(do_facet mds1 $LCTL get_param -n \
2992                          mdd.$(facet_svc mds1).lfsck_layout |
2993                          awk '/^repaired_orphan/ { print $2 }')
2994         [ $repaired -eq $OSTCOUNT ] ||
2995                 error "(4) Expect $OSTCOUNT fixed, but got: $repaired"
2996
2997         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2998         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2999         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
3000
3001         $LFS path2fid $DIR/$tdir/a1/f1
3002         $LFS getstripe $DIR/$tdir/a1/f1
3003 }
3004 run_test 18g "Find out orphan OST-object and repair it (7)"
3005
3006 test_18h() {
3007         echo "#####"
3008         echo "The PFL extent crashed. During the first cycle LFSCK scanning,"
3009         echo "the layout LFSCK will keep the bad PFL file(s) there without"
3010         echo "scanning its OST-object(s). Then in the second stage scanning,"
3011         echo "the OST will return related OST-object(s) to the MDT as orphan."
3012         echo "And then the LFSCK on the MDT can rebuild the PFL extent with"
3013         echo "the 'orphan(s)' stripe information."
3014         echo "#####"
3015
3016         check_mount_and_prep
3017
3018         $LFS setstripe -E 2M -S 1M -c 1 -E -1 $DIR/$tdir/f0 ||
3019                 error "(0) Fail to create PFL $DIR/$tdir/f0"
3020
3021         cat $LUSTRE/tests/test-framework.sh > $DIR/$tdir/f0 ||
3022                 error "(1.1) Fail to write $DIR/$tdir/f0"
3023
3024         dd if=$LUSTRE/tests/test-framework.sh of=$DIR/$tdir/f0 bs=1M seek=2 ||
3025                 error "(1.2) Fail to write $DIR/$tdir/f0"
3026
3027         cp $DIR/$tdir/f0 $DIR/$tdir/guard
3028
3029         echo "Inject failure stub to simulate bad PFL extent range"
3030         #define OBD_FAIL_LFSCK_BAD_PFL_RANGE    0x162f
3031         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162f
3032
3033         chown 1.1 $DIR/$tdir/f0
3034
3035         cancel_lru_locks mdc
3036         cancel_lru_locks osc
3037         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3038
3039         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 &&
3040                 error "(2) Write to bad PFL file should fail"
3041
3042         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
3043         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
3044
3045         for k in $(seq $MDSCOUNT); do
3046                 # The LFSCK status query internal is 30 seconds. For the case
3047                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3048                 # time to guarantee the status sync up.
3049                 wait_update_facet mds${k} "$LCTL get_param -n \
3050                         mdd.$(facet_svc mds${k}).lfsck_layout |
3051                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
3052                         error "(4.1) MDS${k} is not the expected 'completed'"
3053         done
3054
3055         for k in $(seq $OSTCOUNT); do
3056                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
3057                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
3058                              awk '/^status/ { print $2 }')
3059                 [ "$cur_status" == "completed" ] ||
3060                 error "(4.2) OST${k} Expect 'completed', but got '$cur_status'"
3061
3062         done
3063
3064         local repaired=$($SHOW_LAYOUT |
3065                          awk '/^repaired_orphan/ { print $2 }')
3066         [ $repaired -eq 2 ] ||
3067                 error "(5) Fail to repair crashed PFL range: $repaired"
3068
3069         echo "Data in $DIR/$tdir/f0 should not be broken"
3070         diff $DIR/$tdir/f0 $DIR/$tdir/guard ||
3071                 error "(6) Data in $DIR/$tdir/f0 is broken"
3072
3073         echo "Write should succeed after LFSCK repairing the bad PFL range"
3074         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 ||
3075                 error "(7) Write should succeed after LFSCK"
3076 }
3077 run_test 18h "LFSCK can repair crashed PFL extent range"
3078
3079 $LCTL set_param debug=-cache > /dev/null
3080
3081 test_19a() {
3082         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3083                 skip "MDS older than 2.5.55, LU-3951"
3084
3085         check_mount_and_prep
3086         $LFS setstripe -c 1 -i 0 $DIR/$tdir
3087
3088         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3089                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3090
3091         echo "foo1" > $DIR/$tdir/a0
3092         $LFS setstripe -E 512K -S 512K -o 0 -E -1 -S 1M $DIR/$tdir/a1 ||
3093                 error "(0) Fail to create PFL $DIR/$tdir/a1"
3094         echo "foo2" > $DIR/$tdir/a1
3095         echo "guard" > $DIR/$tdir/a2
3096         cancel_lru_locks osc
3097
3098         echo "Inject failure, then client will offer wrong parent FID when read"
3099         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3100                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
3101
3102         #define OBD_FAIL_LFSCK_INVALID_PFID     0x1619
3103         $LCTL set_param fail_loc=0x1619
3104
3105         echo "Read RPC with wrong parent FID should be denied"
3106         cat $DIR/$tdir/a0 && error "(3.1) Read a0 should be denied!"
3107         cat $DIR/$tdir/a1 && error "(3.2) Read a1 should be denied!"
3108         $LCTL set_param fail_loc=0
3109 }
3110 run_test 19a "OST-object inconsistency self detect"
3111
3112 test_19b() {
3113         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3114                 skip "MDS older than 2.5.55, LU-3951"
3115
3116         check_mount_and_prep
3117         $LFS setstripe -c 1 -i 0 $DIR/$tdir
3118
3119         echo "Inject failure stub to make the OST-object to back point to"
3120         echo "non-exist MDT-object"
3121
3122         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3123                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3124
3125         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
3126         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
3127         echo "foo1" > $DIR/$tdir/f0
3128         $LFS setstripe -E 1M -S 1M -o 0 -E 4M -S 256K $DIR/$tdir/f1 ||
3129                 error "(0) Fail to create PFL $DIR/$tdir/f1"
3130         echo "foo2" > $DIR/$tdir/f1
3131         cancel_lru_locks osc
3132         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
3133
3134         do_facet ost1 $LCTL set_param -n \
3135                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3136         echo "Nothing should be fixed since self detect and repair is disabled"
3137         local repaired=$(do_facet ost1 $LCTL get_param -n \
3138                         obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
3139                         awk '/^repaired/ { print $2 }')
3140         [ $repaired -eq 0 ] ||
3141                 error "(1) Expected 0 repaired, but got $repaired"
3142
3143         echo "Read RPC with right parent FID should be accepted,"
3144         echo "and cause parent FID on OST to be fixed"
3145
3146         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3147                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
3148
3149         cat $DIR/$tdir/f0 || error "(2.1) Read f0 should not be denied!"
3150         cat $DIR/$tdir/f1 || error "(2.2) Read f1 should not be denied!"
3151
3152         repaired=$(do_facet ost1 $LCTL get_param -n \
3153                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
3154                 awk '/^repaired/ { print $2 }')
3155         [ $repaired -eq 2 ] ||
3156                 error "(3) Expected 1 repaired, but got $repaired"
3157 }
3158 run_test 19b "OST-object inconsistency self repair"
3159
3160 PATTERN_WITH_HOLE="40000001"
3161 PATTERN_WITHOUT_HOLE="raid0"
3162
3163 test_20a() {
3164         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
3165         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
3166         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3167                 skip "MDS older than 2.5.55, LU-4887"
3168
3169         echo "#####"
3170         echo "The target MDT-object and some of its OST-object are lost."
3171         echo "The LFSCK should find out the left OST-objects and re-create"
3172         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
3173         echo "with the partial OST-objects (LOV EA hole)."
3174
3175         echo "New client can access the file with LOV EA hole via normal"
3176         echo "system tools or commands without crash the system."
3177
3178         echo "For old client, even though it cannot access the file with"
3179         echo "LOV EA hole, it should not cause the system crash."
3180         echo "#####"
3181
3182         check_mount_and_prep
3183         $LFS mkdir -i 0 $DIR/$tdir/a1
3184         if [ $OSTCOUNT -gt 2 ]; then
3185                 $LFS setstripe -c 3 -i 0 -S 1M $DIR/$tdir/a1
3186                 bcount=513
3187         else
3188                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a1
3189                 bcount=257
3190         fi
3191
3192         # 256 blocks on the stripe0.
3193         # 1 block on the stripe1 for 2 OSTs case.
3194         # 256 blocks on the stripe1 for other cases.
3195         # 1 block on the stripe2 if OSTs > 2
3196         dd if=/dev/zero of=$DIR/$tdir/a1/f0 bs=4096 count=$bcount
3197         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=4096 count=$bcount
3198         dd if=/dev/zero of=$DIR/$tdir/a1/f2 bs=4096 count=$bcount
3199
3200         local fid0=$($LFS path2fid $DIR/$tdir/a1/f0)
3201         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
3202         local fid2=$($LFS path2fid $DIR/$tdir/a1/f2)
3203
3204         echo ${fid0}
3205         $LFS getstripe $DIR/$tdir/a1/f0
3206         echo ${fid1}
3207         $LFS getstripe $DIR/$tdir/a1/f1
3208         echo ${fid2}
3209         $LFS getstripe $DIR/$tdir/a1/f2
3210
3211         if [ $OSTCOUNT -gt 2 ]; then
3212                 dd if=/dev/zero of=$DIR/$tdir/a1/f3 bs=4096 count=$bcount
3213                 fid3=$($LFS path2fid $DIR/$tdir/a1/f3)
3214                 echo ${fid3}
3215                 $LFS getstripe $DIR/$tdir/a1/f3
3216         fi
3217
3218         cancel_lru_locks osc
3219
3220         echo "Inject failure..."
3221         echo "To simulate f0 lost MDT-object"
3222         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
3223         do_facet mds1 $LCTL set_param fail_loc=0x1616
3224         rm -f $DIR/$tdir/a1/f0
3225
3226         echo "To simulate f1 lost MDT-object and OST-object0"
3227         #define OBD_FAIL_LFSCK_LOST_SPEOBJ      0x161a
3228         do_facet mds1 $LCTL set_param fail_loc=0x161a
3229         rm -f $DIR/$tdir/a1/f1
3230
3231         echo "To simulate f2 lost MDT-object and OST-object1"
3232         do_facet mds1 $LCTL set_param fail_val=1
3233         rm -f $DIR/$tdir/a1/f2
3234
3235         if [ $OSTCOUNT -gt 2 ]; then
3236                 echo "To simulate f3 lost MDT-object and OST-object2"
3237                 do_facet mds1 $LCTL set_param fail_val=2
3238                 rm -f $DIR/$tdir/a1/f3
3239         fi
3240
3241         umount_client $MOUNT
3242         sync
3243         sleep 2
3244         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
3245
3246         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
3247         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
3248
3249         for k in $(seq $MDSCOUNT); do
3250                 # The LFSCK status query internal is 30 seconds. For the case
3251                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3252                 # time to guarantee the status sync up.
3253                 wait_update_facet mds${k} "$LCTL get_param -n \
3254                         mdd.$(facet_svc mds${k}).lfsck_layout |
3255                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
3256                         error "(2) MDS${k} is not the expected 'completed'"
3257         done
3258
3259         for k in $(seq $OSTCOUNT); do
3260                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
3261                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
3262                                 awk '/^status/ { print $2 }')
3263                 [ "$cur_status" == "completed" ] ||
3264                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
3265         done
3266
3267         local repaired=$(do_facet mds1 $LCTL get_param -n \
3268                          mdd.$(facet_svc mds1).lfsck_layout |
3269                          awk '/^repaired_orphan/ { print $2 }')
3270         if [ $OSTCOUNT -gt 2 ]; then
3271                 [ $repaired -eq 9 ] ||
3272                         error "(4.1) Expect 9 fixed on mds1, but got: $repaired"
3273         else
3274                 [ $repaired -eq 4 ] ||
3275                         error "(4.2) Expect 4 fixed on mds1, but got: $repaired"
3276         fi
3277
3278         mount_client $MOUNT || error "(5.0) Fail to start client!"
3279
3280         LOV_PATTERN_F_HOLE=0x40000000
3281
3282         #
3283         # ${fid0}-R-0 is the old f0
3284         #
3285         local name="$MOUNT/.lustre/lost+found/MDT0000/${fid0}-R-0"
3286         echo "Check $name, which is the old f0"
3287
3288         $LFS getstripe -v $name || error "(5.1) cannot getstripe on $name"
3289
3290         local pattern=$($LFS getstripe -L $name)
3291         [[ "$pattern" = "$PATTERN_WITHOUT_HOLE" ]] ||
3292                 error "(5.2) NOT expect pattern flag hole, but got $pattern"
3293
3294         local stripes=$($LFS getstripe -c $name)
3295         if [ $OSTCOUNT -gt 2 ]; then
3296                 [ $stripes -eq 3 ] ||
3297                 error "(5.3.1) expect the stripe count is 3, but got $stripes"
3298         else
3299                 [ $stripes -eq 2 ] ||
3300                 error "(5.3.2) expect the stripe count is 2, but got $stripes"
3301         fi
3302
3303         local size=$(stat $name | awk '/Size:/ { print $2 }')
3304         [ $size -eq $((4096 * $bcount)) ] ||
3305                 error "(5.4) expect the size $((4096 * $bcount)), but got $size"
3306
3307         cat $name > /dev/null || error "(5.5) cannot read $name"
3308
3309         echo "dummy" >> $name || error "(5.6) cannot write $name"
3310
3311         chown $RUNAS_ID:$RUNAS_GID $name || error "(5.7) cannot chown on $name"
3312
3313         touch $name || error "(5.8) cannot touch $name"
3314
3315         rm -f $name || error "(5.9) cannot unlink $name"
3316
3317         #
3318         # ${fid1}-R-0 contains the old f1's stripe1 (and stripe2 if OSTs > 2)
3319         #
3320         name="$MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
3321         if [ $OSTCOUNT -gt 2 ]; then
3322                 echo "Check $name, it contains the old f1's stripe1 and stripe2"
3323         else
3324                 echo "Check $name, it contains the old f1's stripe1"
3325         fi
3326
3327         $LFS getstripe -v $name || error "(6.1) cannot getstripe on $name"
3328
3329         pattern=$($LFS getstripe -L $name)
3330         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3331                 error "(6.2) expect pattern flag hole, but got $pattern"
3332
3333         stripes=$($LFS getstripe -c $name)
3334         if [ $OSTCOUNT -gt 2 ]; then
3335                 [ $stripes -eq 3 ] ||
3336                 error "(6.3.1) expect the stripe count is 3, but got $stripes"
3337         else
3338                 [ $stripes -eq 2 ] ||
3339                 error "(6.3.2) expect the stripe count is 2, but got $stripes"
3340         fi
3341
3342         size=$(stat $name | awk '/Size:/ { print $2 }')
3343         [ $size -eq $((4096 * $bcount)) ] ||
3344                 error "(6.4) expect the size $((4096 * $bcount)), but got $size"
3345
3346         cat $name > /dev/null && error "(6.5) normal read $name should fail"
3347
3348         local failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3349                          bs=4096 2>&1 | grep "Input/output error" | wc -l)
3350
3351         # stripe0 is dummy
3352         [ $failures -eq 256 ] ||
3353                 error "(6.6) expect 256 IO failures, but get $failures"
3354
3355         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3356         [ $size -eq $((4096 * $bcount)) ] ||
3357                 error "(6.7) expect the size $((4096 * $bcount)), but got $size"
3358
3359         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 &&
3360                 error "(6.8) write to the LOV EA hole should fail"
3361
3362         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 seek=300 ||
3363                 error "(6.9) write to normal stripe should NOT fail"
3364
3365         echo "foo" >> $name && error "(6.10) append write $name should fail"
3366
3367         chown $RUNAS_ID:$RUNAS_GID $name || error "(6.11) cannot chown on $name"
3368
3369         touch $name || error "(6.12) cannot touch $name"
3370
3371         rm -f $name || error "(6.13) cannot unlink $name"
3372
3373         #
3374         # ${fid2}-R-0 it contains the old f2's stripe0 (and stripe2 if OSTs > 2)
3375         #
3376         name="$MOUNT/.lustre/lost+found/MDT0000/${fid2}-R-0"
3377         if [ $OSTCOUNT -gt 2 ]; then
3378                 echo "Check $name, it contains the old f2's stripe0 and stripe2"
3379         else
3380                 echo "Check $name, it contains the old f2's stripe0"
3381         fi
3382
3383         $LFS getstripe -v $name || error "(7.1) cannot getstripe on $name"
3384
3385         pattern=$($LFS getstripe -L $name)
3386         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3387                 error "(7.2) expect pattern flag hole, but got $pattern"
3388
3389         stripes=$($LFS getstripe -c $name)
3390         size=$(stat $name | awk '/Size:/ { print $2 }')
3391         if [ $OSTCOUNT -gt 2 ]; then
3392                 [ $stripes -eq 3 ] ||
3393                 error "(7.3.1) expect the stripe count is 3, but got $stripes"
3394
3395                 [ $size -eq $((4096 * $bcount)) ] ||
3396                 error "(7.4.1) expect size $((4096 * $bcount)), but got $size"
3397
3398                 cat $name > /dev/null &&
3399                         error "(7.5.1) normal read $name should fail"
3400
3401                 failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3402                            bs=4096 2>&1 | grep "Input/output error" | wc -l)
3403                 # stripe1 is dummy
3404                 [ $failures -eq 256 ] ||
3405                         error "(7.6) expect 256 IO failures, but get $failures"
3406
3407                 size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3408                 [ $size -eq $((4096 * $bcount)) ] ||
3409                 error "(7.7) expect the size $((4096 * $bcount)), but got $size"
3410
3411                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
3412                 seek=300 && error "(7.8.0) write to the LOV EA hole should fail"
3413
3414                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 ||
3415                 error "(7.8.1) write to normal stripe should NOT fail"
3416
3417                 echo "foo" >> $name &&
3418                         error "(7.8.3) append write $name should fail"
3419
3420                 chown $RUNAS_ID:$RUNAS_GID $name ||
3421                         error "(7.9.1) cannot chown on $name"
3422
3423                 touch $name || error "(7.10.1) cannot touch $name"
3424         else
3425                 [ $stripes -eq 2 ] ||
3426                 error "(7.3.2) expect the stripe count is 2, but got $stripes"
3427
3428                 # stripe1 is dummy
3429                 [ $size -eq $((4096 * (256 + 0))) ] ||
3430                 error "(7.4.2) expect the size $((4096 * 256)), but got $size"
3431
3432                 cat $name > /dev/null &&
3433                         error "(7.5.2) normal read $name should fail"
3434
3435                 failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3436                            bs=4096 2>&1 | grep "Input/output error" | wc -l)
3437                 [ $failures -eq 256 ] ||
3438                 error "(7.6.2) expect 256 IO failures, but get $failures"
3439
3440                 bcount=$((256 * 2))
3441                 size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3442                 [ $size -eq $((4096 * $bcount)) ] ||
3443                 error "(7.7.2) expect the size $((4096 * $bcount)), got $size"
3444
3445                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
3446                 seek=256 && error "(7.8.2) write to the LOV EA hole should fail"
3447
3448                 chown $RUNAS_ID:$RUNAS_GID $name ||
3449                         error "(7.9.2) cannot chown on $name"
3450
3451                 touch $name || error "(7.10.2) cannot touch $name"
3452         fi
3453
3454         rm -f $name || error "(7.11) cannot unlink $name"
3455
3456         [ $OSTCOUNT -le 2 ] && return
3457
3458         #
3459         # ${fid3}-R-0 should contains the old f3's stripe0 and stripe1
3460         #
3461         name="$MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
3462         echo "Check $name, which contains the old f3's stripe0 and stripe1"
3463
3464         $LFS getstripe -v $name || error "(8.1) cannot getstripe on $name"
3465
3466         pattern=$($LFS getstripe -L $name)
3467         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3468                 error "(8.2) expect pattern flag hole, but got $pattern"
3469
3470         stripes=$($LFS getstripe -c $name)
3471         [ $stripes -eq 3 ] ||
3472                 error "(8.3) expect the stripe count is 3, but got $stripes"
3473
3474         size=$(stat $name | awk '/Size:/ { print $2 }')
3475         # stripe2 is lost
3476         [ $size -eq $((4096 * (256 + 256 + 0))) ] ||
3477                 error "(8.4) expect the size $((4096 * 512)), but got $size"
3478
3479         cat $name > /dev/null &&
3480                 error "(8.5) normal read $name should fail"
3481
3482         failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3483                    bs=4096 2>&1 | grep "Input/output error" | wc -l)
3484         # stripe2 is dummy
3485         [ $failures -eq 256 ] ||
3486                 error "(8.6) expect 256 IO failures, but get $failures"
3487
3488         bcount=$((256 * 3))
3489         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3490         [ $size -eq $((4096 * $bcount)) ] ||
3491                 error "(8.7) expect the size $((4096 * $bcount)), but got $size"
3492
3493         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
3494                 seek=512 && error "(8.8) write to the LOV EA hole should fail"
3495
3496         chown $RUNAS_ID:$RUNAS_GID $name ||
3497                 error "(8.9) cannot chown on $name"
3498
3499         touch $name || error "(8.10) cannot touch $name"
3500
3501         rm -f $name || error "(8.11) cannot unlink $name"
3502 }
3503 run_test 20a "Handle the orphan with dummy LOV EA slot properly"
3504
3505 test_20b() {
3506         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
3507         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
3508         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3509                 skip "MDS older than 2.5.55, LU-4887"
3510
3511         echo "#####"
3512         echo "The target MDT-object and some of its OST-object are lost."
3513         echo "The LFSCK should find out the left OST-objects and re-create"
3514         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
3515         echo "with the partial OST-objects (LOV EA hole)."
3516
3517         echo "New client can access the file with LOV EA hole via normal"
3518         echo "system tools or commands without crash the system - PFL case."
3519         echo "#####"
3520
3521         check_mount_and_prep
3522
3523         $LFS setstripe -E 2M -S 1M -c 2 -E -1 -S 1M -c 2 $DIR/$tdir/f0 ||
3524                 error "(0) Fail to create PFL file $DIR/$tdir/f0"
3525         $LFS setstripe -E 2M -S 1M -c 2 -E -1 -S 1M -c 2 $DIR/$tdir/f1 ||
3526                 error "(1) Fail to create PFL file $DIR/$tdir/f1"
3527         $LFS setstripe -E 2M -S 1M -c 2 -E -1 -S 1M -c 2 $DIR/$tdir/f2 ||
3528                 error "(2) Fail to create PFL file $DIR/$tdir/f2"
3529
3530         local bcount=$((256 * 3 + 1))
3531
3532         dd if=/dev/zero of=$DIR/$tdir/f0 bs=4096 count=$bcount
3533         dd if=/dev/zero of=$DIR/$tdir/f1 bs=4096 count=$bcount
3534         dd if=/dev/zero of=$DIR/$tdir/f2 bs=4096 count=$bcount
3535
3536         local fid0=$($LFS path2fid $DIR/$tdir/f0)
3537         local fid1=$($LFS path2fid $DIR/$tdir/f1)
3538         local fid2=$($LFS path2fid $DIR/$tdir/f2)
3539
3540         echo ${fid0}
3541         $LFS getstripe $DIR/$tdir/f0
3542         echo ${fid1}
3543         $LFS getstripe $DIR/$tdir/f1
3544         echo ${fid2}
3545         $LFS getstripe $DIR/$tdir/f2
3546
3547         cancel_lru_locks mdc
3548         cancel_lru_locks osc
3549
3550         echo "Inject failure..."
3551         echo "To simulate f0 lost MDT-object"
3552         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
3553         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1616
3554         rm -f $DIR/$tdir/f0
3555
3556         echo "To simulate the case of f1 lost MDT-object and "
3557         echo "the first OST-object in each PFL component"
3558         #define OBD_FAIL_LFSCK_LOST_SPEOBJ      0x161a
3559         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161a
3560         rm -f $DIR/$tdir/f1
3561
3562         echo "To simulate the case of f2 lost MDT-object and "
3563         echo "the second OST-object in each PFL component"
3564         do_facet $SINGLEMDS $LCTL set_param fail_val=1
3565         rm -f $DIR/$tdir/f2
3566
3567         sync
3568         sleep 2
3569         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
3570
3571         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
3572         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
3573
3574         for k in $(seq $MDSCOUNT); do
3575                 # The LFSCK status query internal is 30 seconds. For the case
3576                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3577                 # time to guarantee the status sync up.
3578                 wait_update_facet mds${k} "$LCTL get_param -n \
3579                         mdd.$(facet_svc mds${k}).lfsck_layout |
3580                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
3581                         error "(4) MDS${k} is not the expected 'completed'"
3582         done
3583
3584         for k in $(seq $OSTCOUNT); do
3585                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
3586                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
3587                                 awk '/^status/ { print $2 }')
3588                 [ "$cur_status" == "completed" ] ||
3589                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
3590         done
3591
3592         local repaired=$(do_facet mds1 $LCTL get_param -n \
3593                          mdd.$(facet_svc mds1).lfsck_layout |
3594                          awk '/^repaired_orphan/ { print $2 }')
3595         [ $repaired -eq 8 ] ||
3596                 error "(6) Expect 8 fixed on mds1, but got: $repaired"
3597
3598         #
3599         # ${fid0}-R-0 is the old f0
3600         #
3601         local name="$MOUNT/.lustre/lost+found/MDT0000/${fid0}-R-0"
3602         echo "Check $name, which is the old f0"
3603
3604         $LFS getstripe -v $name || error "(7.1) cannot getstripe on $name"
3605
3606         local pattern=$($LFS getstripe -L -I1 $name)
3607         [[ "$pattern" = "$PATTERN_WITHOUT_HOLE" ]] ||
3608                 error "(7.2.1) NOT expect pattern flag hole, but got $pattern"
3609
3610         pattern=$($LFS getstripe -L -I2 $name)
3611         [[ "$pattern" = "$PATTERN_WITHOUT_HOLE" ]] ||
3612                 error "(7.2.2) NOT expect pattern flag hole, but got $pattern"
3613
3614         local stripes=$($LFS getstripe -c -I1 $name)
3615         [ $stripes -eq 2 ] ||
3616                 error "(7.3.1) expect 2 stripes, but got $stripes"
3617
3618         stripes=$($LFS getstripe -c -I2 $name)
3619         [ $stripes -eq 2 ] ||
3620                 error "(7.3.2) expect 2 stripes, but got $stripes"
3621
3622         local e_start=$($LFS getstripe -I1 $name |
3623                         awk '/lcme_extent.e_start:/ { print $2 }')
3624         [ $e_start -eq 0 ] ||
3625                 error "(7.4.1) expect the COMP1 start at 0, got $e_start"
3626
3627         local e_end=$($LFS getstripe -I1 $name |
3628                       awk '/lcme_extent.e_end:/ { print $2 }')
3629         [ $e_end -eq 2097152 ] ||
3630                 error "(7.4.2) expect the COMP1 end at 2097152, got $e_end"
3631
3632         e_start=$($LFS getstripe -I2 $name |
3633                   awk '/lcme_extent.e_start:/ { print $2 }')
3634         [ $e_start -eq 2097152 ] ||
3635                 error "(7.5.1) expect the COMP2 start at 2097152, got $e_start"
3636
3637         e_end=$($LFS getstripe -I2 $name |
3638                 awk '/lcme_extent.e_end:/ { print $2 }')
3639         [ "$e_end" = "EOF" ] ||
3640                 error "(7.5.2) expect the COMP2 end at (EOF), got $e_end"
3641
3642         local size=$(stat $name | awk '/Size:/ { print $2 }')
3643         [ $size -eq $((4096 * $bcount)) ] ||
3644                 error "(7.6) expect the size $((4096 * $bcount)), but got $size"
3645
3646         cat $name > /dev/null || error "(7.7) cannot read $name"
3647
3648         echo "dummy" >> $name || error "(7.8) cannot write $name"
3649
3650         chown $RUNAS_ID:$RUNAS_GID $name || error "(7.9) cannot chown on $name"
3651
3652         touch $name || error "(7.10) cannot touch $name"
3653
3654         rm -f $name || error "(7.11) cannot unlink $name"
3655
3656         #
3657         # ${fid1}-R-0 contains the old f1's second stripe in each COMP
3658         #
3659         name="$MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
3660         echo "Check $name, it contains f1's second OST-object in each COMP"
3661
3662         $LFS getstripe -v $name || error "(8.1) cannot getstripe on $name"
3663
3664         pattern=$($LFS getstripe -L -I1 $name)
3665         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3666                 error "(8.2.1) expect pattern flag hole, but got $pattern"
3667
3668         pattern=$($LFS getstripe -L -I2 $name)
3669         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3670                 error "(8.2.2) expect pattern flag hole, but got $pattern"
3671
3672         stripes=$($LFS getstripe -c -I1 $name)
3673         [ $stripes -eq 2 ] ||
3674                 error "(8.3.2) expect 2 stripes, but got $stripes"
3675
3676         stripes=$($LFS getstripe -c -I2 $name)
3677         [ $stripes -eq 2 ] ||
3678                 error "(8.3.2) expect 2 stripes, but got $stripes"
3679
3680         e_start=$($LFS getstripe -I1 $name |