Whamcloud - gitweb
LU-16036 test: make sanity-lfsck 15d more robust
[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_15d() {
1992         (( $MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
1993
1994         check_mount_and_prep
1995         rm -rf $DIR/$tdir
1996         $LFS mkdir -c -1 $DIR/$tdir || error "create $tdir failed"
1997         $LFS setdirstripe -D -i -1 -c 1 $DIR/$tdir ||
1998                 error "setdirstripe failed"
1999
2000         createmany -o $DIR/$tdir/f 100 || error "create sub files failed"
2001         createmany -d $DIR/$tdir/s 100 || error "create sub dirs failed"
2002
2003         echo "Migrate $DIR/$tdir to MDT1"
2004         $LFS migrate -m 1 $DIR/$tdir &
2005         pid=$!
2006
2007         sleep 2
2008         # fail sub transactions on random MDTs, which may cause some file
2009         # inaccessible
2010         #define OBD_FAIL_OUT_EIO                0x1709
2011         for ((i = 0; i < $MDSCOUNT; i++)); do
2012                 do_facet mds$i $LCTL set_param fail_loc=0x1709
2013                 sleep 0.1
2014                 do_facet mds$i $LCTL set_param fail_loc=0
2015         done
2016
2017         wait $pid
2018
2019         # LFSCK can't fully fix migrating directories, and may leave some
2020         # files inaccessible, but it shouldn't cause crash
2021         $START_NAMESPACE -A -r ||
2022                 error "Fail to start LFSCK for namespace"
2023
2024         wait_all_targets_blocked namespace completed 1
2025
2026         # resume migration may fail because some file may be inaccessible, but
2027         # it shouldn't cause crash
2028         $LFS migrate -m 1 $DIR/$tdir
2029
2030         # rm $tdir to avoid cleanup failure in the end
2031         rm -rf $DIR/$tdir/*
2032         $LFS rm_entry $DIR/$tdir/*
2033         rm -rf $DIR/$tdir
2034         REFORMAT="yes" cleanup_and_setup_lustre
2035 }
2036 run_test 15d "LFSCK don't crash upon dir migration failure"
2037
2038 test_16() {
2039         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2040                 skip "MDS older than 2.5.55, LU-3594"
2041
2042         echo "#####"
2043         echo "If the OST-object's owner information does not match the owner"
2044         echo "information stored in the MDT-object, then the LFSCK trust the"
2045         echo "MDT-object and update the OST-object's owner information."
2046         echo "#####"
2047
2048         check_mount_and_prep
2049         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2050         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
2051         cancel_lru_locks osc
2052
2053         # created but no setattr or write to the file.
2054         mkdir $DIR/$tdir/d1
2055         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/d1
2056         $RUNAS createmany -o $DIR/$tdir/d1/o 100 || error "create failed"
2057
2058         echo "Inject failure stub to skip OST-object owner changing"
2059         #define OBD_FAIL_LFSCK_BAD_OWNER        0x1613
2060         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1613
2061         chown 1.1 $DIR/$tdir/f0
2062         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2063
2064         echo "Trigger layout LFSCK to find out inconsistent OST-object owner"
2065         echo "and fix them"
2066
2067         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
2068
2069         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2070                 mdd.${MDT_DEV}.lfsck_layout |
2071                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2072                 $SHOW_LAYOUT
2073                 error "(2) unexpected status"
2074         }
2075
2076         local repaired=$($SHOW_LAYOUT |
2077                          awk '/^repaired_inconsistent_owner/ { print $2 }')
2078         [ $repaired -eq 1 ] ||
2079                 error "(3) Fail to repair inconsistent owner: $repaired"
2080 }
2081 run_test 16 "LFSCK can repair inconsistent MDT-object/OST-object owner"
2082
2083 test_17() {
2084         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2085                 skip "MDS older than 2.5.55, LU-3594"
2086
2087         echo "#####"
2088         echo "If more than one MDT-objects reference the same OST-object,"
2089         echo "and the OST-object only recognizes one MDT-object, then the"
2090         echo "LFSCK should create new OST-objects for such non-recognized"
2091         echo "MDT-objects."
2092         echo "#####"
2093
2094         check_mount_and_prep
2095         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2096
2097         echo "Inject failure stub to make two MDT-objects to refernce"
2098         echo "the OST-object"
2099
2100         #define OBD_FAIL_LFSCK_MULTIPLE_REF     0x1614
2101         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0x1614
2102         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
2103         cancel_lru_locks mdc
2104         cancel_lru_locks osc
2105
2106         createmany -o $DIR/$tdir/f 1
2107         cancel_lru_locks mdc
2108         cancel_lru_locks osc
2109
2110         $LFS setstripe -E 2M -S 256K -o 0 -E 4M -S 512K -o 0 \
2111                 $DIR/$tdir/f1 ||
2112                 error "(0) Fail to create PFL $DIR/$tdir/f1"
2113         cancel_lru_locks mdc
2114         cancel_lru_locks osc
2115         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
2116
2117         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard use the same OST-objects"
2118         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard use the same OST-objects"
2119         local size=$(ls -l $DIR/$tdir/f0 | awk '{ print $5 }')
2120         [ $size -eq 1048576 ] ||
2121                 error "(1.1) f0 (wrong) size should be 1048576, but got $size"
2122
2123         size=$(ls -l $DIR/$tdir/f1 | awk '{ print $5 }')
2124         [ $size -eq 1048576 ] ||
2125                 error "(1.2) f1 (wrong) size should be 1048576, but got $size"
2126
2127         echo "Trigger layout LFSCK to find out multiple refenced MDT-objects"
2128         echo "and fix them"
2129
2130         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
2131
2132         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2133                 mdd.${MDT_DEV}.lfsck_layout |
2134                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2135                 $SHOW_LAYOUT
2136                 error "(3) unexpected status"
2137         }
2138
2139         local repaired=$($SHOW_LAYOUT |
2140                          awk '/^repaired_multiple_referenced/ { print $2 }')
2141         [ $repaired -eq 2 ] ||
2142                 error "(4) Fail to repair multiple references: $repaired"
2143
2144         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard should use diff OST-objects"
2145         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=2 ||
2146                 error "(5) Fail to write f0."
2147         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
2148         [ $size -eq 1048576 ] ||
2149                 error "(6) guard size should be 1048576, but got $size"
2150
2151         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard should use diff OST-objects"
2152         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2 ||
2153                 error "(7) Fail to write f1."
2154         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
2155         [ $size -eq 1048576 ] ||
2156                 error "(8) guard size should be 1048576, but got $size"
2157 }
2158 run_test 17 "LFSCK can repair multiple references"
2159
2160 $LCTL set_param debug=+cache > /dev/null
2161
2162 test_18a() {
2163         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2164                 skip "MDS older than 2.5.55, LU-3336"
2165
2166         echo "#####"
2167         echo "The target MDT-object is there, but related stripe information"
2168         echo "is lost or partly lost. The LFSCK should regenerate the missing"
2169         echo "layout EA entries."
2170         echo "#####"
2171
2172         check_mount_and_prep
2173         $LFS mkdir -i 0 $DIR/$tdir/a1
2174         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2175         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2176
2177         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2178
2179         $LFS path2fid $DIR/$tdir/a1/f1
2180         $LFS getstripe $DIR/$tdir/a1/f1
2181
2182         if [ $MDSCOUNT -ge 2 ]; then
2183                 $LFS mkdir -i 1 $DIR/$tdir/a2
2184                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2185                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2186                 $LFS path2fid $DIR/$tdir/a2/f2
2187                 $LFS getstripe $DIR/$tdir/a2/f2
2188         fi
2189
2190         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2191                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2192
2193         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2194
2195         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2196
2197         $LFS path2fid $DIR/$tdir/f3
2198         $LFS getstripe $DIR/$tdir/f3
2199
2200         cancel_lru_locks osc
2201
2202         echo "Inject failure, to make the MDT-object lost its layout EA"
2203         #define OBD_FAIL_LFSCK_LOST_STRIPE 0x1615
2204         do_facet mds1 $LCTL set_param fail_loc=0x1615
2205         chown 1.1 $DIR/$tdir/a1/f1
2206
2207         if [ $MDSCOUNT -ge 2 ]; then
2208                 do_facet mds2 $LCTL set_param fail_loc=0x1615
2209                 chown 1.1 $DIR/$tdir/a2/f2
2210         fi
2211
2212         chown 1.1 $DIR/$tdir/f3
2213
2214         sync
2215         sleep 2
2216
2217         do_facet mds1 $LCTL set_param fail_loc=0
2218         if [ $MDSCOUNT -ge 2 ]; then
2219                 do_facet mds2 $LCTL set_param fail_loc=0
2220         fi
2221
2222         cancel_lru_locks mdc
2223         cancel_lru_locks osc
2224
2225         echo "The file size should be incorrect since layout EA is lost"
2226         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2227         [ "$cur_size" != "$saved_size1" ] ||
2228                 error "(1) Expect incorrect file1 size"
2229
2230         if [ $MDSCOUNT -ge 2 ]; then
2231                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2232                 [ "$cur_size" != "$saved_size1" ] ||
2233                         error "(2) Expect incorrect file2 size"
2234         fi
2235
2236         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2237         [ "$cur_size" != "$saved_size2" ] ||
2238                 error "(1.2) Expect incorrect file3 size"
2239
2240         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2241         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
2242
2243         for k in $(seq $MDSCOUNT); do
2244                 # The LFSCK status query internal is 30 seconds. For the case
2245                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2246                 # time to guarantee the status sync up.
2247                 wait_update_facet mds${k} "$LCTL get_param -n \
2248                         mdd.$(facet_svc mds${k}).lfsck_layout |
2249                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2250                         error "(4) MDS${k} is not the expected 'completed'"
2251         done
2252
2253         for k in $(seq $OSTCOUNT); do
2254                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2255                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2256                                 awk '/^status/ { print $2 }')
2257                 [ "$cur_status" == "completed" ] ||
2258                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2259         done
2260
2261         local repaired=$(do_facet mds1 $LCTL get_param -n \
2262                          mdd.$(facet_svc mds1).lfsck_layout |
2263                          awk '/^repaired_orphan/ { print $2 }')
2264         [ $repaired -eq 3 ] ||
2265         error "(6.1) Expect 3 fixed on mds1, but got: $repaired"
2266
2267         if [ $MDSCOUNT -ge 2 ]; then
2268                 repaired=$(do_facet mds2 $LCTL get_param -n \
2269                          mdd.$(facet_svc mds2).lfsck_layout |
2270                                  awk '/^repaired_orphan/ { print $2 }')
2271                 [ $repaired -eq 2 ] ||
2272                 error "(6.2) Expect 2 fixed on mds2, but got: $repaired"
2273         fi
2274
2275         $LFS path2fid $DIR/$tdir/a1/f1
2276         $LFS getstripe $DIR/$tdir/a1/f1
2277
2278         if [ $MDSCOUNT -ge 2 ]; then
2279                 $LFS path2fid $DIR/$tdir/a2/f2
2280                 $LFS getstripe $DIR/$tdir/a2/f2
2281         fi
2282
2283         $LFS path2fid $DIR/$tdir/f3
2284         $LFS getstripe $DIR/$tdir/f3
2285
2286         echo "The file size should be correct after layout LFSCK scanning"
2287         cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2288         [ "$cur_size" == "$saved_size1" ] ||
2289                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2290
2291         if [ $MDSCOUNT -ge 2 ]; then
2292                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2293                 [ "$cur_size" == "$saved_size1" ] ||
2294                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2295         fi
2296
2297         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2298         [ "$cur_size" == "$saved_size2" ] ||
2299                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2300 }
2301 run_test 18a "Find out orphan OST-object and repair it (1)"
2302
2303 test_18b() {
2304         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2305         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2306                 skip "MDS older than 2.5.55, LU-3336"
2307
2308         echo "#####"
2309         echo "The target MDT-object is lost. The LFSCK should re-create the"
2310         echo "MDT-object under .lustre/lost+found/MDTxxxx. The admin should"
2311         echo "can move it back to normal namespace manually."
2312         echo "#####"
2313
2314         check_mount_and_prep
2315         $LFS mkdir -i 0 $DIR/$tdir/a1
2316         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2317         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2318         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2319         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2320         echo ${fid1}
2321         $LFS getstripe $DIR/$tdir/a1/f1
2322
2323         if [ $MDSCOUNT -ge 2 ]; then
2324                 $LFS mkdir -i 1 $DIR/$tdir/a2
2325                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2326                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2327                 fid2=$($LFS path2fid $DIR/$tdir/a2/f2)
2328                 echo ${fid2}
2329                 $LFS getstripe $DIR/$tdir/a2/f2
2330         fi
2331
2332         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2333                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2334
2335         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2336
2337         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2338         local fid3=$($LFS path2fid $DIR/$tdir/f3)
2339         echo ${fid3}
2340         $LFS getstripe $DIR/$tdir/f3
2341
2342         cancel_lru_locks osc
2343
2344         echo "Inject failure, to simulate the case of missing the MDT-object"
2345         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2346         do_facet mds1 $LCTL set_param fail_loc=0x1616
2347         rm -f $DIR/$tdir/a1/f1
2348
2349         if [ $MDSCOUNT -ge 2 ]; then
2350                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2351                 rm -f $DIR/$tdir/a2/f2
2352         fi
2353
2354         rm -f $DIR/$tdir/f3
2355
2356         sync
2357         sleep 2
2358
2359         do_facet mds1 $LCTL set_param fail_loc=0
2360         if [ $MDSCOUNT -ge 2 ]; then
2361                 do_facet mds2 $LCTL set_param fail_loc=0
2362         fi
2363
2364         cancel_lru_locks mdc
2365         cancel_lru_locks osc
2366
2367         # dryrun mode only check orphans, not repaie
2368         echo "Trigger layout LFSCK --dryrun to find out orphan OST-object"
2369         $START_LAYOUT --dryrun -o -r ||
2370                 error "Fail to start layout LFSCK in dryrun mode"
2371         wait_all_targets_blocked layout completed 2
2372
2373         local PARAMS=$($SHOW_LAYOUT | awk '/^param/ { print $2 }')
2374         [ "$PARAMS" == "dryrun,all_targets,orphan" ] ||
2375                 error "Expect 'dryrun,all_targets,orphan', got '$PARAMS'"
2376
2377         local orphans=$(do_facet mds1 $LCTL get_param -n \
2378                         mdd.$(facet_svc mds1).lfsck_layout |
2379                         awk '/^inconsistent_orphan/ { print $2 }')
2380         [ $orphans -eq 3 ] ||
2381                 error "Expect 3 found on mds1, but got: $orphans"
2382
2383         # orphan parents should not be created
2384         local subdir
2385         for subdir in $MOUNT/.lustre/lost+found/*; do
2386                 [ ! "$(ls -A $subdir)" ] || error "$subdir not empty"
2387         done
2388
2389         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2390         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2391
2392         for k in $(seq $MDSCOUNT); do
2393                 # The LFSCK status query internal is 30 seconds. For the case
2394                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2395                 # time to guarantee the status sync up.
2396                 wait_update_facet mds${k} "$LCTL get_param -n \
2397                         mdd.$(facet_svc mds${k}).lfsck_layout |
2398                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2399                         error "(2) MDS${k} is not the expected 'completed'"
2400         done
2401
2402         for k in $(seq $OSTCOUNT); do
2403                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2404                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2405                                 awk '/^status/ { print $2 }')
2406                 [ "$cur_status" == "completed" ] ||
2407                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2408         done
2409
2410         local repaired=$(do_facet mds1 $LCTL get_param -n \
2411                          mdd.$(facet_svc mds1).lfsck_layout |
2412                          awk '/^repaired_orphan/ { print $2 }')
2413         [ $repaired -eq 3 ] ||
2414         error "(4.1) Expect 3 fixed on mds1, but got: $repaired"
2415
2416         if [ $MDSCOUNT -ge 2 ]; then
2417                 repaired=$(do_facet mds2 $LCTL get_param -n \
2418                          mdd.$(facet_svc mds2).lfsck_layout |
2419                          awk '/^repaired_orphan/ { print $2 }')
2420                 [ $repaired -eq 2 ] ||
2421                 error "(4.2) Expect 2 fixed on mds2, but got: $repaired"
2422         fi
2423
2424         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2425         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2426         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2427
2428         if [ $MDSCOUNT -ge 2 ]; then
2429                 local name=$MOUNT/.lustre/lost+found/MDT0001/${fid2}-R-0
2430                 mv $name $DIR/$tdir/a2/f2 || error "(6) Fail to move $name"
2431         fi
2432
2433         mv $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0 $DIR/$tdir/f3 ||
2434         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
2435
2436         $LFS path2fid $DIR/$tdir/a1/f1
2437         $LFS getstripe $DIR/$tdir/a1/f1
2438
2439         if [ $MDSCOUNT -ge 2 ]; then
2440                 $LFS path2fid $DIR/$tdir/a2/f2
2441                 $LFS getstripe $DIR/$tdir/a2/f2
2442         fi
2443
2444         $LFS path2fid $DIR/$tdir/f3
2445         $LFS getstripe $DIR/$tdir/f3
2446
2447         echo "The file size should be correct after layout LFSCK scanning"
2448         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2449         [ "$cur_size" == "$saved_size1" ] ||
2450                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2451
2452         if [ $MDSCOUNT -ge 2 ]; then
2453                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2454                 [ "$cur_size" == "$saved_size1" ] ||
2455                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2456         fi
2457
2458         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2459         [ "$cur_size" == "$saved_size2" ] ||
2460                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2461 }
2462 run_test 18b "Find out orphan OST-object and repair it (2)"
2463
2464 test_18c() {
2465         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2466         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2467                 skip "MDS older than 2.5.55, LU-3336"
2468
2469         echo "#####"
2470         echo "The target MDT-object is lost, and the OST-object FID is missing."
2471         echo "The LFSCK should re-create the MDT-object with new FID under the "
2472         echo "directory .lustre/lost+found/MDTxxxx."
2473         echo "#####"
2474
2475         check_mount_and_prep
2476         $LFS mkdir -i 0 $DIR/$tdir/a1
2477         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2478
2479         echo "Inject failure, to simulate the case of missing parent FID"
2480         #define OBD_FAIL_LFSCK_NOPFID           0x1617
2481         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1617
2482
2483         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2484         $LFS getstripe $DIR/$tdir/a1/f1
2485
2486         if [ $MDSCOUNT -ge 2 ]; then
2487                 $LFS mkdir -i 1 $DIR/$tdir/a2
2488                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a2
2489                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2490                 $LFS getstripe $DIR/$tdir/a2/f2
2491         fi
2492
2493         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2494                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2495
2496         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2497         $LFS getstripe $DIR/$tdir/f3
2498
2499         cancel_lru_locks osc
2500         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
2501
2502         echo "Inject failure, to simulate the case of missing the MDT-object"
2503         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2504         do_facet mds1 $LCTL set_param fail_loc=0x1616
2505         rm -f $DIR/$tdir/a1/f1
2506
2507         if [ $MDSCOUNT -ge 2 ]; then
2508                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2509                 rm -f $DIR/$tdir/a2/f2
2510         fi
2511
2512         rm -f $DIR/$tdir/f3
2513
2514         sync
2515         sleep 2
2516
2517         do_facet mds1 $LCTL set_param fail_loc=0
2518         if [ $MDSCOUNT -ge 2 ]; then
2519                 do_facet mds2 $LCTL set_param fail_loc=0
2520         fi
2521
2522         cancel_lru_locks mdc
2523         cancel_lru_locks osc
2524
2525         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2526         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2527
2528         for k in $(seq $MDSCOUNT); do
2529                 # The LFSCK status query internal is 30 seconds. For the case
2530                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2531                 # time to guarantee the status sync up.
2532                 wait_update_facet mds${k} "$LCTL get_param -n \
2533                         mdd.$(facet_svc mds${k}).lfsck_layout |
2534                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2535                         error "(2) MDS${k} is not the expected 'completed'"
2536         done
2537
2538         for k in $(seq $OSTCOUNT); do
2539                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2540                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2541                                 awk '/^status/ { print $2 }')
2542                 [ "$cur_status" == "completed" ] ||
2543                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2544         done
2545
2546         if [ $MDSCOUNT -ge 2 ]; then
2547                 expected=4
2548         else
2549                 expected=3
2550         fi
2551
2552         local repaired=$(do_facet mds1 $LCTL get_param -n \
2553                          mdd.$(facet_svc mds1).lfsck_layout |
2554                          awk '/^repaired_orphan/ { print $2 }')
2555         [ $repaired -eq $expected ] ||
2556                 error "(4) Expect $expected fixed on mds1, but got: $repaired"
2557
2558         if [ $MDSCOUNT -ge 2 ]; then
2559                 repaired=$(do_facet mds2 $LCTL get_param -n \
2560                            mdd.$(facet_svc mds2).lfsck_layout |
2561                            awk '/^repaired_orphan/ { print $2 }')
2562                 [ $repaired -eq 0 ] ||
2563                         error "(5) Expect 0 fixed on mds2, but got: $repaired"
2564         fi
2565
2566         ls -ail $MOUNT/.lustre/lost+found/
2567
2568         echo "There should NOT be some stub under .lustre/lost+found/MDT0001/"
2569         if [ -d $MOUNT/.lustre/lost+found/MDT0001 ]; then
2570                 cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-N-*)
2571                 [ -z "$cname" ] ||
2572                         error "(6) .lustre/lost+found/MDT0001/ should be empty"
2573         fi
2574
2575         echo "There should be some stub under .lustre/lost+found/MDT0000/"
2576         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2577                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2578
2579         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-N-*)
2580         [ ! -z "$cname" ] ||
2581                 error "(8) .lustre/lost+found/MDT0000/ should not be empty"
2582 }
2583 run_test 18c "Find out orphan OST-object and repair it (3)"
2584
2585 test_18d() {
2586         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2587                 skip "MDS older than 2.5.55, LU-3336"
2588
2589         echo "#####"
2590         echo "The target MDT-object layout EA is corrupted, but the right"
2591         echo "OST-object is still alive as orphan. The layout LFSCK will"
2592         echo "not create new OST-object to occupy such slot."
2593         echo "#####"
2594
2595         check_mount_and_prep
2596         mkdir $DIR/$tdir/a1
2597         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2598         echo "guard" > $DIR/$tdir/a1/f1
2599         echo "foo" > $DIR/$tdir/a1/f2
2600
2601         echo "guard" > $DIR/$tdir/a1/f3
2602         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2603                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2604         echo "foo" > $DIR/$tdir/a1/f4
2605
2606         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2607         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2608         $LFS path2fid $DIR/$tdir/a1/f1
2609         $LFS getstripe $DIR/$tdir/a1/f1
2610         $LFS path2fid $DIR/$tdir/a1/f2
2611         $LFS getstripe $DIR/$tdir/a1/f2
2612         $LFS path2fid $DIR/$tdir/a1/f3
2613         $LFS getstripe $DIR/$tdir/a1/f3
2614         $LFS path2fid $DIR/$tdir/a1/f4
2615         $LFS getstripe $DIR/$tdir/a1/f4
2616         cancel_lru_locks osc
2617
2618         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2619         echo "to reference the same OST-object (which is f1's OST-obejct)."
2620         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2621         echo "dangling reference case, but f2's old OST-object is there."
2622
2623         echo "The failure also makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2624         echo "to reference the same OST-object (which is f3's OST-obejct)."
2625         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2626         echo "dangling reference case, but f4's old OST-object is there."
2627         echo
2628
2629         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2630         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2631         chown 1.1 $DIR/$tdir/a1/f2
2632         chown 1.1 $DIR/$tdir/a1/f4
2633         rm -f $DIR/$tdir/a1/f1
2634         rm -f $DIR/$tdir/a1/f3
2635         sync
2636         sleep 2
2637         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2638
2639         echo "stopall to cleanup object cache"
2640         stopall > /dev/null
2641         echo "setupall"
2642         setupall > /dev/null
2643
2644         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2645         $START_LAYOUT -r -o -c -d || error "(2) Fail to start LFSCK for layout!"
2646
2647         for k in $(seq $MDSCOUNT); do
2648                 # The LFSCK status query internal is 30 seconds. For the case
2649                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2650                 # time to guarantee the status sync up.
2651                 wait_update_facet mds${k} "$LCTL get_param -n \
2652                         mdd.$(facet_svc mds${k}).lfsck_layout |
2653                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2654                         error "(3) MDS${k} is not the expected 'completed'"
2655         done
2656
2657         for k in $(seq $OSTCOUNT); do
2658                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2659                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2660                                 awk '/^status/ { print $2 }')
2661                 [ "$cur_status" == "completed" ] ||
2662                 error "(4) OST${k} Expect 'completed', but got '$cur_status'"
2663         done
2664
2665         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2666                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2667                          awk '/^repaired_orphan/ { print $2 }')
2668         [ $repaired -eq 2 ] ||
2669                 error "(5) Expect 2 orphans have been fixed, but got: $repaired"
2670
2671         repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2672                    mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2673                    awk '/^repaired_dangling/ { print $2 }')
2674         [ $repaired -eq 0 ] ||
2675                 error "(6) Expect 0 dangling has been fixed, but got: $repaired"
2676
2677         echo "The file size should be correct after layout LFSCK scanning"
2678         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2679         [ "$cur_size" == "$saved_size1" ] ||
2680                 error "(7) Expect file2 size $saved_size1, but got $cur_size"
2681
2682         cur_size=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2683         [ "$cur_size" == "$saved_size2" ] ||
2684                 error "(8) Expect file4 size $saved_size2, but got $cur_size"
2685
2686         echo "The LFSCK should find back the original data."
2687         cat $DIR/$tdir/a1/f2
2688         $LFS path2fid $DIR/$tdir/a1/f2
2689         $LFS getstripe $DIR/$tdir/a1/f2
2690         cat $DIR/$tdir/a1/f4
2691         $LFS path2fid $DIR/$tdir/a1/f4
2692         $LFS getstripe $DIR/$tdir/a1/f4
2693 }
2694 run_test 18d "Find out orphan OST-object and repair it (4)"
2695
2696 test_18e() {
2697         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2698         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2699                 skip "MDS older than 2.5.55, LU-3336"
2700
2701         echo "#####"
2702         echo "The target MDT-object layout EA slot is occpuied by some new"
2703         echo "created OST-object when repair dangling reference case. Such"
2704         echo "conflict OST-object has been modified by others. To keep the"
2705         echo "new data, the LFSCK will create a new file to refernece this"
2706         echo "old orphan OST-object."
2707         echo "#####"
2708
2709         check_mount_and_prep
2710         mkdir $DIR/$tdir/a1
2711         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2712         echo "guard" > $DIR/$tdir/a1/f1
2713         echo "foo" > $DIR/$tdir/a1/f2
2714
2715         echo "guard" > $DIR/$tdir/a1/f3
2716         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2717                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2718         echo "foo" > $DIR/$tdir/a1/f4
2719
2720         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2721         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2722
2723         $LFS path2fid $DIR/$tdir/a1/f1
2724         $LFS getstripe $DIR/$tdir/a1/f1
2725         $LFS path2fid $DIR/$tdir/a1/f2
2726         $LFS getstripe $DIR/$tdir/a1/f2
2727         $LFS path2fid $DIR/$tdir/a1/f3
2728         $LFS getstripe $DIR/$tdir/a1/f3
2729         $LFS path2fid $DIR/$tdir/a1/f4
2730         $LFS getstripe $DIR/$tdir/a1/f4
2731         cancel_lru_locks osc
2732
2733         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2734         echo "to reference the same OST-object (which is f1's OST-obejct)."
2735         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2736         echo "dangling reference case, but f2's old OST-object is there."
2737
2738         echo "Also the failure makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2739         echo "to reference the same OST-object (which is f3's OST-obejct)."
2740         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2741         echo "dangling reference case, but f4's old OST-object is there."
2742         echo
2743
2744         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2745         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2746         chown 1.1 $DIR/$tdir/a1/f2
2747         chown 1.1 $DIR/$tdir/a1/f4
2748         rm -f $DIR/$tdir/a1/f1
2749         rm -f $DIR/$tdir/a1/f3
2750         sync
2751         sleep 2
2752         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2753
2754         echo "stopall to cleanup object cache"
2755         stopall > /dev/null
2756         echo "setupall"
2757         setupall > /dev/null
2758
2759         #define OBD_FAIL_LFSCK_DELAY3           0x1602
2760         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
2761
2762         start_full_debug_logging
2763
2764         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2765         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
2766
2767         wait_update_facet mds1 "$LCTL get_param -n \
2768                 mdd.$(facet_svc mds1).lfsck_layout |
2769                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" $LTIME ||
2770                 error "(3) MDS1 is not the expected 'scanning-phase2'"
2771
2772         # to guarantee all updates are synced.
2773         sync
2774         sleep 2
2775
2776         echo "Write new data to f2/f4 to modify the new created OST-object."
2777         echo "dummy" >> $DIR/$tdir/a1/f2 || error "write a1/f2 failed"
2778         echo "dummy" >> $DIR/$tdir/a1/f4 || error "write a1/f4 failed"
2779
2780         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2781
2782         for k in $(seq $MDSCOUNT); do
2783                 # The LFSCK status query internal is 30 seconds. For the case
2784                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2785                 # time to guarantee the status sync up.
2786                 wait_update_facet mds${k} "$LCTL get_param -n \
2787                         mdd.$(facet_svc mds${k}).lfsck_layout |
2788                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2789                         error "(4) MDS${k} is not the expected 'completed'"
2790         done
2791
2792         for k in $(seq $OSTCOUNT); do
2793                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2794                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2795                                 awk '/^status/ { print $2 }')
2796                 [ "$cur_status" == "completed" ] ||
2797                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2798         done
2799
2800         stop_full_debug_logging
2801
2802         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2803                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2804                          awk '/^repaired_orphan/ { print $2 }')
2805         [ $repaired -eq 2 ] ||
2806                 error "(6) Expect 2 orphans have been fixed, but got: $repaired"
2807
2808         echo "There should be stub file under .lustre/lost+found/MDT0000/"
2809         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2810                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2811
2812         local count=$(ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-* | wc -l)
2813         if [ $count -ne 2 ]; then
2814                 ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-*
2815                 error "(8) Expect 2 stubs under lost+found, but got $count"
2816         fi
2817
2818         echo "The stub file should keep the original f2 or f4 data"
2819         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | head -n 1)
2820         local cur_size=$(ls -il $cname | awk '{ print $6 }')
2821         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2822                 error "(9) Got unexpected $cur_size"
2823
2824         cat $cname
2825         $LFS path2fid $cname
2826         $LFS getstripe $cname
2827
2828         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | tail -n 1)
2829         cur_size=$(ls -il $cname | awk '{ print $6 }')
2830         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2831                 error "(10) Got unexpected $cur_size"
2832
2833         cat $cname
2834         $LFS path2fid $cname
2835         $LFS getstripe $cname
2836
2837         echo "The f2/f4 should contains new data."
2838         cat $DIR/$tdir/a1/f2
2839         $LFS path2fid $DIR/$tdir/a1/f2
2840         $LFS getstripe $DIR/$tdir/a1/f2
2841         cat $DIR/$tdir/a1/f4
2842         $LFS path2fid $DIR/$tdir/a1/f4
2843         $LFS getstripe $DIR/$tdir/a1/f4
2844 }
2845 run_test 18e "Find out orphan OST-object and repair it (5)"
2846
2847 test_18f() {
2848         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2849
2850         echo "#####"
2851         echo "The target MDT-object is lost. The LFSCK should re-create the"
2852         echo "MDT-object under .lustre/lost+found/MDTxxxx. If some OST fail"
2853         echo "to verify some OST-object(s) during the first stage-scanning,"
2854         echo "the LFSCK should skip orphan OST-objects for such OST. Others"
2855         echo "should not be affected."
2856         echo "#####"
2857
2858         check_mount_and_prep
2859         $LFS mkdir -i 0 $DIR/$tdir/a1
2860         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2861         dd if=/dev/zero of=$DIR/$tdir/a1/guard bs=1M count=2
2862         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2863         $LFS mkdir -i 0 $DIR/$tdir/a2
2864         $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a2
2865         dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2866         $LFS getstripe $DIR/$tdir/a1/f1
2867         $LFS getstripe $DIR/$tdir/a2/f2
2868
2869         if [ $MDSCOUNT -ge 2 ]; then
2870                 $LFS mkdir -i 1 $DIR/$tdir/a3
2871                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a3
2872                 dd if=/dev/zero of=$DIR/$tdir/a3/guard bs=1M count=2
2873                 dd if=/dev/zero of=$DIR/$tdir/a3/f3 bs=1M count=2
2874                 $LFS mkdir -i 1 $DIR/$tdir/a4
2875                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a4
2876                 dd if=/dev/zero of=$DIR/$tdir/a4/f4 bs=1M count=2
2877                 $LFS getstripe $DIR/$tdir/a3/f3
2878                 $LFS getstripe $DIR/$tdir/a4/f4
2879         fi
2880
2881         cancel_lru_locks osc
2882
2883         echo "Inject failure, to simulate the case of missing the MDT-object"
2884         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2885         do_facet mds1 $LCTL set_param fail_loc=0x1616
2886         rm -f $DIR/$tdir/a1/f1
2887         rm -f $DIR/$tdir/a2/f2
2888
2889         if [ $MDSCOUNT -ge 2 ]; then
2890                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2891                 rm -f $DIR/$tdir/a3/f3
2892                 rm -f $DIR/$tdir/a4/f4
2893         fi
2894
2895         sync
2896         sleep 2
2897
2898         do_facet mds1 $LCTL set_param fail_loc=0
2899         if [ $MDSCOUNT -ge 2 ]; then
2900                 do_facet mds2 $LCTL set_param fail_loc=0
2901         fi
2902
2903         cancel_lru_locks mdc
2904         cancel_lru_locks osc
2905
2906         echo "Inject failure, to simulate the OST0 fail to handle"
2907         echo "MDT0 LFSCK request during the first-stage scanning."
2908         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
2909         do_facet mds1 $LCTL set_param fail_loc=0x161c fail_val=0
2910
2911         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2912         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2913
2914         for k in $(seq $MDSCOUNT); do
2915                 # The LFSCK status query internal is 30 seconds. For the case
2916                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2917                 # time to guarantee the status sync up.
2918                 wait_update_facet mds${k} "$LCTL get_param -n \
2919                         mdd.$(facet_svc mds${k}).lfsck_layout |
2920                         awk '/^status/ { print \\\$2 }'" "partial" $LTIME ||
2921                         error "(2) MDS${k} is not the expected 'partial'"
2922         done
2923
2924         wait_update_facet ost1 "$LCTL get_param -n \
2925                 obdfilter.$(facet_svc ost1).lfsck_layout |
2926                 awk '/^status/ { print \\\$2 }'" "partial" $LTIME || {
2927                 error "(3) OST1 is not the expected 'partial'"
2928         }
2929
2930         wait_update_facet ost2 "$LCTL get_param -n \
2931                 obdfilter.$(facet_svc ost2).lfsck_layout |
2932                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME || {
2933                 error "(4) OST2 is not the expected 'completed'"
2934         }
2935
2936         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2937
2938         local repaired=$(do_facet mds1 $LCTL get_param -n \
2939                          mdd.$(facet_svc mds1).lfsck_layout |
2940                          awk '/^repaired_orphan/ { print $2 }')
2941         [ $repaired -eq 1 ] ||
2942                 error "(5) Expect 1 fixed on mds{1}, but got: $repaired"
2943
2944         if [ $MDSCOUNT -ge 2 ]; then
2945                 repaired=$(do_facet mds2 $LCTL get_param -n \
2946                          mdd.$(facet_svc mds2).lfsck_layout |
2947                          awk '/^repaired_orphan/ { print $2 }')
2948                 [ $repaired -eq 1 ] ||
2949                 error "(6) Expect 1 fixed on mds{2}, but got: $repaired"
2950         fi
2951
2952         echo "Trigger layout LFSCK on all devices again to cleanup"
2953         $START_LAYOUT -r -o || error "(7) Fail to start LFSCK for layout!"
2954
2955         for k in $(seq $MDSCOUNT); do
2956                 # The LFSCK status query internal is 30 seconds. For the case
2957                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2958                 # time to guarantee the status sync up.
2959                 wait_update_facet mds${k} "$LCTL get_param -n \
2960                         mdd.$(facet_svc mds${k}).lfsck_layout |
2961                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2962                         error "(8) MDS${k} is not the expected 'completed'"
2963         done
2964
2965         for k in $(seq $OSTCOUNT); do
2966                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2967                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2968                              awk '/^status/ { print $2 }')
2969                 [ "$cur_status" == "completed" ] ||
2970                 error "(9) OST${k} Expect 'completed', but got '$cur_status'"
2971
2972         done
2973
2974         local repaired=$(do_facet mds1 $LCTL get_param -n \
2975                          mdd.$(facet_svc mds1).lfsck_layout |
2976                          awk '/^repaired_orphan/ { print $2 }')
2977         [ $repaired -eq 2 ] ||
2978                 error "(10) Expect 2 fixed on mds{1}, but got: $repaired"
2979
2980         if [ $MDSCOUNT -ge 2 ]; then
2981                 repaired=$(do_facet mds2 $LCTL get_param -n \
2982                          mdd.$(facet_svc mds2).lfsck_layout |
2983                          awk '/^repaired_orphan/ { print $2 }')
2984                 [ $repaired -eq 2 ] ||
2985                 error "(11) Expect 2 fixed on mds{2}, but got: $repaired"
2986         fi
2987 }
2988 run_test 18f "Skip the failed OST(s) when handle orphan OST-objects"
2989
2990 test_18g() {
2991         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2992
2993         echo "#####"
2994         echo "The target MDT-object is lost, but related OI mapping is there"
2995         echo "The LFSCK should recreate the lost MDT-object without affected"
2996         echo "by the stale OI mapping."
2997         echo "#####"
2998
2999         check_mount_and_prep
3000         $LFS mkdir -i 0 $DIR/$tdir/a1
3001         $LFS setstripe -c -1 -i 0 -S 1M $DIR/$tdir/a1
3002         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=$OSTCOUNT
3003         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
3004         echo ${fid1}
3005         $LFS getstripe $DIR/$tdir/a1/f1
3006         cancel_lru_locks osc
3007
3008         echo "Inject failure to simulate lost MDT-object but keep OI mapping"
3009         #define OBD_FAIL_LFSCK_LOST_MDTOBJ2     0x162e
3010         do_facet mds1 $LCTL set_param fail_loc=0x162e
3011         rm -f $DIR/$tdir/a1/f1
3012
3013         do_facet mds1 $LCTL set_param fail_loc=0
3014         cancel_lru_locks mdc
3015         cancel_lru_locks osc
3016
3017         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
3018         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
3019
3020         for k in $(seq $MDSCOUNT); do
3021                 # The LFSCK status query internal is 30 seconds. For the case
3022                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3023                 # time to guarantee the status sync up.
3024                 wait_update_facet mds${k} "$LCTL get_param -n \
3025                         mdd.$(facet_svc mds${k}).lfsck_layout |
3026                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
3027                         error "(2) MDS${k} is not the expected 'completed'"
3028         done
3029
3030         for k in $(seq $OSTCOUNT); do
3031                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
3032                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
3033                                 awk '/^status/ { print $2 }')
3034                 [ "$cur_status" == "completed" ] ||
3035                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
3036         done
3037
3038         local repaired=$(do_facet mds1 $LCTL get_param -n \
3039                          mdd.$(facet_svc mds1).lfsck_layout |
3040                          awk '/^repaired_orphan/ { print $2 }')
3041         [ $repaired -eq $OSTCOUNT ] ||
3042                 error "(4) Expect $OSTCOUNT fixed, but got: $repaired"
3043
3044         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
3045         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
3046         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
3047
3048         $LFS path2fid $DIR/$tdir/a1/f1
3049         $LFS getstripe $DIR/$tdir/a1/f1
3050 }
3051 run_test 18g "Find out orphan OST-object and repair it (7)"
3052
3053 test_18h() {
3054         echo "#####"
3055         echo "The PFL extent crashed. During the first cycle LFSCK scanning,"
3056         echo "the layout LFSCK will keep the bad PFL file(s) there without"
3057         echo "scanning its OST-object(s). Then in the second stage scanning,"
3058         echo "the OST will return related OST-object(s) to the MDT as orphan."
3059         echo "And then the LFSCK on the MDT can rebuild the PFL extent with"
3060         echo "the 'orphan(s)' stripe information."
3061         echo "#####"
3062
3063         check_mount_and_prep
3064
3065         $LFS setstripe -E 2M -S 1M -c 1 -E -1 $DIR/$tdir/f0 ||
3066                 error "(0) Fail to create PFL $DIR/$tdir/f0"
3067
3068         cat $LUSTRE/tests/test-framework.sh > $DIR/$tdir/f0 ||
3069                 error "(1.1) Fail to write $DIR/$tdir/f0"
3070
3071         dd if=$LUSTRE/tests/test-framework.sh of=$DIR/$tdir/f0 bs=1M seek=2 ||
3072                 error "(1.2) Fail to write $DIR/$tdir/f0"
3073
3074         cp $DIR/$tdir/f0 $DIR/$tdir/guard
3075
3076         echo "Inject failure stub to simulate bad PFL extent range"
3077         #define OBD_FAIL_LFSCK_BAD_PFL_RANGE    0x162f
3078         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162f
3079
3080         chown 1.1 $DIR/$tdir/f0
3081
3082         cancel_lru_locks mdc
3083         cancel_lru_locks osc
3084         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3085
3086         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 &&
3087                 error "(2) Write to bad PFL file should fail"
3088
3089         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
3090         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
3091
3092         for k in $(seq $MDSCOUNT); do
3093                 # The LFSCK status query internal is 30 seconds. For the case
3094                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3095                 # time to guarantee the status sync up.
3096                 wait_update_facet mds${k} "$LCTL get_param -n \
3097                         mdd.$(facet_svc mds${k}).lfsck_layout |
3098                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
3099                         error "(4.1) MDS${k} is not the expected 'completed'"
3100         done
3101
3102         for k in $(seq $OSTCOUNT); do
3103                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
3104                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
3105                              awk '/^status/ { print $2 }')
3106                 [ "$cur_status" == "completed" ] ||
3107                 error "(4.2) OST${k} Expect 'completed', but got '$cur_status'"
3108
3109         done
3110
3111         local repaired=$($SHOW_LAYOUT |
3112                          awk '/^repaired_orphan/ { print $2 }')
3113         [ $repaired -eq 2 ] ||
3114                 error "(5) Fail to repair crashed PFL range: $repaired"
3115
3116         echo "Data in $DIR/$tdir/f0 should not be broken"
3117         diff $DIR/$tdir/f0 $DIR/$tdir/guard ||
3118                 error "(6) Data in $DIR/$tdir/f0 is broken"
3119
3120         echo "Write should succeed after LFSCK repairing the bad PFL range"
3121         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 ||
3122                 error "(7) Write should succeed after LFSCK"
3123 }
3124 run_test 18h "LFSCK can repair crashed PFL extent range"
3125
3126 $LCTL set_param debug=-cache > /dev/null
3127
3128 test_19a() {
3129         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3130                 skip "MDS older than 2.5.55, LU-3951"
3131
3132         check_mount_and_prep
3133         $LFS setstripe -c 1 -i 0 $DIR/$tdir
3134
3135         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3136                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3137
3138         echo "foo1" > $DIR/$tdir/a0
3139         $LFS setstripe -E 512K -S 512K -o 0 -E -1 -S 1M $DIR/$tdir/a1 ||
3140                 error "(0) Fail to create PFL $DIR/$tdir/a1"
3141         echo "foo2" > $DIR/$tdir/a1
3142         echo "guard" > $DIR/$tdir/a2
3143         cancel_lru_locks osc
3144
3145         echo "Inject failure, then client will offer wrong parent FID when read"
3146         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3147                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
3148
3149         #define OBD_FAIL_LFSCK_INVALID_PFID     0x1619
3150         $LCTL set_param fail_loc=0x1619
3151
3152         echo "Read RPC with wrong parent FID should be denied"
3153         cat $DIR/$tdir/a0 && error "(3.1) Read a0 should be denied!"
3154         cat $DIR/$tdir/a1 && error "(3.2) Read a1 should be denied!"
3155         $LCTL set_param fail_loc=0
3156 }
3157 run_test 19a "OST-object inconsistency self detect"
3158
3159 test_19b() {
3160         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3161                 skip "MDS older than 2.5.55, LU-3951"
3162
3163         check_mount_and_prep
3164         $LFS setstripe -c 1 -i 0 $DIR/$tdir
3165
3166         echo "Inject failure stub to make the OST-object to back point to"
3167         echo "non-exist MDT-object"
3168
3169         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3170                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3171
3172         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
3173         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
3174         echo "foo1" > $DIR/$tdir/f0
3175         $LFS setstripe -E 1M -S 1M -o 0 -E 4M -S 256K $DIR/$tdir/f1 ||
3176                 error "(0) Fail to create PFL $DIR/$tdir/f1"
3177         echo "foo2" > $DIR/$tdir/f1
3178         cancel_lru_locks osc
3179         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
3180
3181         do_facet ost1 $LCTL set_param -n \
3182                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3183         echo "Nothing should be fixed since self detect and repair is disabled"
3184         local repaired=$(do_facet ost1 $LCTL get_param -n \
3185                         obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
3186                         awk '/^repaired/ { print $2 }')
3187         [ $repaired -eq 0 ] ||
3188                 error "(1) Expected 0 repaired, but got $repaired"
3189
3190         echo "Read RPC with right parent FID should be accepted,"
3191         echo "and cause parent FID on OST to be fixed"
3192
3193         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3194                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1