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