Whamcloud - gitweb
LU-12203 tests: skip sanity-lfsck 36[b,c] for FILESET
[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 #Bug number for excepting test
12 ALWAYS_EXCEPT="$SANITY_LFSCK_EXCEPT"
13
14 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
15 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
16
17 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
18 . $LUSTRE/tests/test-framework.sh
19 init_test_env $@
20 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
21 init_logging
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 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.60) ]] &&
33         skip "Need MDS version at least 2.3.60" && exit 0
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 [ $(facet_fstype $SINGLEMDS) == zfs ] && MDSSIZE=300000
44 OSTSIZE=100000
45 [ $(facet_fstype ost1) == 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 [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.4.90) ]] &&
55         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 2c"
56
57 [[ $(lustre_version_code ost1) -lt $(version_code 2.5.55) ]] &&
58         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 11 12 13 14 15 16 17 18 19 20 21"
59
60 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.50) ]] &&
61         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 2d 2e 3 22 23 24 25 26 27 28 29 30 31"
62
63 # DNE does not support striped directory on zfs-based backend yet.
64 [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 31"
66
67 build_test_filter
68
69 MDT_DEV="${FSNAME}-MDT0000"
70 OST_DEV="${FSNAME}-OST0000"
71 MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
72 START_NAMESPACE="do_facet $SINGLEMDS \
73                 $LCTL lfsck_start -M ${MDT_DEV} -t namespace"
74 START_LAYOUT="do_facet $SINGLEMDS \
75                 $LCTL lfsck_start -M ${MDT_DEV} -t layout"
76 START_LAYOUT_ON_OST="do_facet ost1 $LCTL lfsck_start -M ${OST_DEV} -t layout"
77 STOP_LFSCK="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
78 SHOW_NAMESPACE="do_facet $SINGLEMDS \
79                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace"
80 SHOW_LAYOUT="do_facet $SINGLEMDS \
81                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout"
82 SHOW_LAYOUT_ON_OST="do_facet ost1 \
83                 $LCTL get_param -n obdfilter.${OST_DEV}.lfsck_layout"
84 MOUNT_OPTS_SCRUB="-o user_xattr"
85 MOUNT_OPTS_NOSCRUB="-o user_xattr,noscrub"
86 MOUNT_OPTS_SKIP_LFSCK="-o user_xattr,skip_lfsck"
87
88 lfsck_prep() {
89         local ndirs=$1
90         local nfiles=$2
91         local igif=$3
92
93         check_mount_and_prep
94
95         echo "preparing... $nfiles * $ndirs files will be created $(date)."
96         if [ ! -z $igif ]; then
97                 #define OBD_FAIL_FID_IGIF       0x1504
98                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
99         fi
100
101         cp $LUSTRE/tests/*.sh $DIR/$tdir/
102         if [ $ndirs -gt 0 ]; then
103                 createmany -d $DIR/$tdir/d $ndirs
104                 createmany -m $DIR/$tdir/f $ndirs
105                 if [ $nfiles -gt 0 ]; then
106                         for ((i = 0; i < $ndirs; i++)); do
107                                 createmany -m $DIR/$tdir/d${i}/f $nfiles > \
108                                         /dev/null || error "createmany $nfiles"
109                         done
110                 fi
111                 createmany -d $DIR/$tdir/e $ndirs
112         fi
113
114         if [ ! -z $igif ]; then
115                 touch $DIR/$tdir/dummy
116                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0
117         fi
118
119         echo "prepared $(date)."
120 }
121
122 run_e2fsck_on_mdt0() {
123         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] && return
124
125         stop $SINGLEMDS > /dev/null || error "(0) Fail to the stop MDT0"
126         run_e2fsck $(facet_active_host $SINGLEMDS) $(mdsdevname 1) "-n" |
127                 grep "Fix? no" && {
128                 run_e2fsck $(facet_active_host $SINGLEMDS) $(mdsdevname 1) "-n"
129                 error "(2) Detected inconsistency on MDT0"
130         }
131         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
132                 error "(3) Fail to start MDT0"
133 }
134
135 wait_all_targets_blocked() {
136         local com=$1
137         local status=$2
138         local err=$3
139
140         local count=$(do_facet mds1 \
141                      "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000 -w |
142                       awk '/^${com}_mdts_${status}/ { print \\\$2 }'")
143         [[ $count -eq $MDSCOUNT ]] || {
144                 do_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000"
145                 error "($err) only $count of $MDSCOUNT MDTs are in ${status}"
146         }
147 }
148
149 wait_all_targets() {
150         local com=$1
151         local status=$2
152         local err=$3
153
154         wait_update_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000 |
155                 awk '/^${com}_mdts_${status}/ { print \\\$2 }'" \
156                 "$MDSCOUNT" $LTIME || {
157                 do_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000"
158                 error "($err) some MDTs are not in ${status}"
159         }
160 }
161
162 test_0() {
163         lfsck_prep 3 3
164
165         #define OBD_FAIL_LFSCK_DELAY1           0x1600
166         do_facet $SINGLEMDS $LCTL set_param fail_val=3 fail_loc=0x1600
167         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
168
169         $SHOW_NAMESPACE || error "Fail to monitor LFSCK (3)"
170
171         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
172         [ "$STATUS" == "scanning-phase1" ] ||
173                 error "(4) Expect 'scanning-phase1', but got '$STATUS'"
174
175         $STOP_LFSCK || error "(5) Fail to stop LFSCK!"
176
177         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
178         [ "$STATUS" == "stopped" ] ||
179                 error "(6) Expect 'stopped', but got '$STATUS'"
180
181         $START_NAMESPACE || error "(7) Fail to start LFSCK for namespace!"
182
183         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
184         [ "$STATUS" == "scanning-phase1" ] ||
185                 error "(8) Expect 'scanning-phase1', but got '$STATUS'"
186
187         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
188         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
189                 mdd.${MDT_DEV}.lfsck_namespace |
190                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
191                 $SHOW_NAMESPACE
192                 error "(9) unexpected status"
193         }
194
195         local repaired=$($SHOW_NAMESPACE |
196                          awk '/^updated_phase1/ { print $2 }')
197         [ $repaired -eq 0 ] ||
198                 error "(10) Expect nothing to be repaired, but got: $repaired"
199
200         local scanned1=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
201         $START_NAMESPACE -r || error "(11) Fail to reset LFSCK!"
202         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
203                 mdd.${MDT_DEV}.lfsck_namespace |
204                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
205                 $SHOW_NAMESPACE
206                 error "(12) unexpected status"
207         }
208
209         local scanned2=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
210         [ $((scanned1 + 1)) -eq $scanned2 ] ||
211                 error "(13) Expect success $((scanned1 + 1)), but got $scanned2"
212
213         echo "stopall, should NOT crash LU-3649"
214         stopall || error "(14) Fail to stopall"
215 }
216 run_test 0 "Control LFSCK manually"
217
218 test_1a() {
219         lfsck_prep 1 1
220
221         #define OBD_FAIL_FID_INDIR      0x1501
222         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1501
223         touch $DIR/$tdir/dummy
224
225         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
226         umount_client $MOUNT
227         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
228         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
229                 mdd.${MDT_DEV}.lfsck_namespace |
230                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
231                 $SHOW_NAMESPACE
232                 error "(4) unexpected status"
233         }
234
235         local repaired=$($SHOW_NAMESPACE |
236                          awk '/^dirent_repaired/ { print $2 }')
237         # for interop with old server
238         [ -z "$repaired" ] &&
239                 repaired=$($SHOW_NAMESPACE |
240                          awk '/^updated_phase1/ { print $2 }')
241
242         [ $repaired -eq 1 ] ||
243                 error "(5) Fail to repair crashed FID-in-dirent: $repaired"
244
245         run_e2fsck_on_mdt0
246
247         mount_client $MOUNT || error "(6) Fail to start client!"
248
249         #define OBD_FAIL_FID_LOOKUP     0x1505
250         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
251         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
252
253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
254 }
255 run_test 1a "LFSCK can find out and repair crashed FID-in-dirent"
256
257 test_1b()
258 {
259         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
260                 skip "OI Scrub not implemented for ZFS" && return
261
262         lfsck_prep 1 1
263
264         #define OBD_FAIL_FID_INLMA      0x1502
265         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1502
266         touch $DIR/$tdir/dummy
267
268         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
269         umount_client $MOUNT
270         #define OBD_FAIL_FID_NOLMA      0x1506
271         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1506
272         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
273         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
274                 mdd.${MDT_DEV}.lfsck_namespace |
275                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
276                 $SHOW_NAMESPACE
277                 error "(4) unexpected status"
278         }
279
280         local repaired=$($SHOW_NAMESPACE |
281                          awk '/^dirent_repaired/ { print $2 }')
282         # for interop with old server
283         [ -z "$repaired" ] &&
284                 repaired=$($SHOW_NAMESPACE |
285                          awk '/^updated_phase1/ { print $2 }')
286
287         [ $repaired -eq 1 ] ||
288                 error "(5) Fail to repair the missing FID-in-LMA: $repaired"
289
290         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
291         run_e2fsck_on_mdt0
292
293         mount_client $MOUNT || error "(6) Fail to start client!"
294
295         #define OBD_FAIL_FID_LOOKUP     0x1505
296         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
297         stat $DIR/$tdir/dummy > /dev/null || error "(7) no FID-in-LMA."
298
299         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
300 }
301 run_test 1b "LFSCK can find out and repair the missing FID-in-LMA"
302
303 test_1c() {
304         lfsck_prep 1 1
305
306         #define OBD_FAIL_FID_IGIF       0x1504
307         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
308         touch $DIR/$tdir/dummy
309
310         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
311         umount_client $MOUNT
312         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
313         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
314                 mdd.${MDT_DEV}.lfsck_namespace |
315                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
316                 $SHOW_NAMESPACE
317                 error "(4) unexpected status"
318         }
319
320         local repaired=$($SHOW_NAMESPACE |
321                          awk '/^dirent_repaired/ { print $2 }')
322         # for interop with old server
323         [ -z "$repaired" ] &&
324                 repaired=$($SHOW_NAMESPACE |
325                          awk '/^updated_phase1/ { print $2 }')
326
327         [ $repaired -eq 1 ] ||
328                 error "(5) Fail to repair lost FID-in-dirent: $repaired"
329
330         run_e2fsck_on_mdt0
331
332         mount_client $MOUNT || error "(6) Fail to start client!"
333
334         #define OBD_FAIL_FID_LOOKUP     0x1505
335         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
336         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
337
338         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
339 }
340 run_test 1c "LFSCK can find out and repair lost FID-in-dirent"
341
342 test_2a() {
343         lfsck_prep 1 1
344
345         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
346         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
347         touch $DIR/$tdir/dummy
348
349         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
350         umount_client $MOUNT
351         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
352         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
353                 mdd.${MDT_DEV}.lfsck_namespace |
354                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
355                 $SHOW_NAMESPACE
356                 error "(4) unexpected status"
357         }
358
359         local repaired=$($SHOW_NAMESPACE |
360                          awk '/^linkea_repaired/ { print $2 }')
361         # for interop with old server
362         [ -z "$repaired" ] &&
363                 repaired=$($SHOW_NAMESPACE |
364                          awk '/^updated_phase2/ { print $2 }')
365
366         [ $repaired -eq 1 ] ||
367                 error "(5) Fail to repair crashed linkEA: $repaired"
368
369         run_e2fsck_on_mdt0
370
371         mount_client $MOUNT || error "(6) Fail to start client!"
372
373         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
374                 error "(7) Fail to stat $DIR/$tdir/dummy"
375
376         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
377         local dummyname=$($LFS fid2path $DIR $dummyfid)
378         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
379                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
380 }
381 run_test 2a "LFSCK can find out and repair crashed linkEA entry"
382
383 test_2b()
384 {
385         lfsck_prep 1 1
386
387         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
388         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
389         touch $DIR/$tdir/dummy
390
391         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
392         umount_client $MOUNT
393         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
394         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
395                 mdd.${MDT_DEV}.lfsck_namespace |
396                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
397                 $SHOW_NAMESPACE
398                 error "(4) unexpected status"
399         }
400
401         local repaired=$($SHOW_NAMESPACE |
402                          awk '/^updated_phase2/ { print $2 }')
403         [ $repaired -eq 1 ] ||
404                 error "(5) Fail to repair crashed linkEA: $repaired"
405
406         run_e2fsck_on_mdt0
407
408         mount_client $MOUNT || error "(6) Fail to start client!"
409
410         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
411                 error "(7) Fail to stat $DIR/$tdir/dummy"
412
413         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
414         local dummyname=$($LFS fid2path $DIR $dummyfid)
415         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
416                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
417 }
418 run_test 2b "LFSCK can find out and remove invalid linkEA entry"
419
420 test_2c()
421 {
422         lfsck_prep 1 1
423
424         #define OBD_FAIL_LFSCK_LINKEA_MORE2     0x1605
425         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1605
426         touch $DIR/$tdir/dummy
427
428         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
429         umount_client $MOUNT
430         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
431         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
432                 mdd.${MDT_DEV}.lfsck_namespace |
433                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
434                 $SHOW_NAMESPACE
435                 error "(4) unexpected status"
436         }
437
438         local repaired=$($SHOW_NAMESPACE |
439                          awk '/^updated_phase2/ { print $2 }')
440         [ $repaired -eq 1 ] ||
441                 error "(5) Fail to repair crashed linkEA: $repaired"
442
443         run_e2fsck_on_mdt0
444
445         mount_client $MOUNT || error "(6) Fail to start client!"
446
447         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
448                 error "(7) Fail to stat $DIR/$tdir/dummy"
449
450         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
451         local dummyname=$($LFS fid2path $DIR $dummyfid)
452         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
453                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
454 }
455 run_test 2c "LFSCK can find out and remove repeated linkEA entry"
456
457 test_2d()
458 {
459         lfsck_prep 1 1
460
461         #define OBD_FAIL_LFSCK_NO_LINKEA        0x161d
462         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161d
463         touch $DIR/$tdir/dummy
464
465         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
466         umount_client $MOUNT
467         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
468         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
469                 mdd.${MDT_DEV}.lfsck_namespace |
470                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
471                 $SHOW_NAMESPACE
472                 error "(4) unexpected status"
473         }
474
475         local repaired=$($SHOW_NAMESPACE |
476                          awk '/^linkea_repaired/ { print $2 }')
477         [ $repaired -eq 1 ] ||
478                 error "(5) Fail to repair crashed linkEA: $repaired"
479
480         run_e2fsck_on_mdt0
481
482         mount_client $MOUNT || error "(6) Fail to start client!"
483
484         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
485                 error "(7) Fail to stat $DIR/$tdir/dummy"
486
487         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
488         local dummyname=$($LFS fid2path $DIR $dummyfid)
489         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
490                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
491 }
492 run_test 2d "LFSCK can recover the missing linkEA entry"
493
494 test_2e()
495 {
496         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
497
498         check_mount_and_prep
499
500         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT1"
501
502         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
503         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
504         $LFS mkdir -i 0 $DIR/$tdir/d0/d1 || error "(2) Fail to mkdir d1 on MDT0"
505         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
506
507         $START_NAMESPACE -r -A || error "(3) Fail to start LFSCK for namespace!"
508
509         wait_all_targets_blocked namespace completed 4
510
511         local repaired=$($SHOW_NAMESPACE |
512                          awk '/^linkea_repaired/ { print $2 }')
513         [ $repaired -eq 1 ] ||
514                 error "(5) Fail to repair crashed linkEA: $repaired"
515
516         local fid=$($LFS path2fid $DIR/$tdir/d0/d1)
517         local name=$($LFS fid2path $DIR $fid)
518         [ "$name" == "$DIR/$tdir/d0/d1" ] ||
519                 error "(6) Fail to repair linkEA: $fid $name"
520 }
521 run_test 2e "namespace LFSCK can verify remote object linkEA"
522
523 test_3()
524 {
525         lfsck_prep 4 4
526
527         mkdir $DIR/$tdir/dummy || error "(1) Fail to mkdir"
528         ln $DIR/$tdir/d0/f0 $DIR/$tdir/dummy/f0 || error "(2) Fail to hardlink"
529         ln $DIR/$tdir/d0/f1 $DIR/$tdir/dummy/f1 || error "(3) Fail to hardlink"
530
531         $LFS mkdir -i 0 $DIR/$tdir/edir || error "(4) Fail to mkdir"
532         touch $DIR/$tdir/edir/f0 || error "(5) Fail to touch"
533         touch $DIR/$tdir/edir/f1 || error "(6) Fail to touch"
534
535         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
536         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
537         ln $DIR/$tdir/edir/f0 $DIR/$tdir/edir/w0 || error "(7) Fail to hardlink"
538
539         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
540         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
541         ln $DIR/$tdir/edir/f1 $DIR/$tdir/edir/w1 || error "(8) Fail to hardlink"
542
543         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
544
545         $START_NAMESPACE -r || error "(9) Fail to start LFSCK for namespace!"
546         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
547                 mdd.${MDT_DEV}.lfsck_namespace |
548                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
549                 $SHOW_NAMESPACE
550                 error "(10) unexpected status"
551         }
552
553         local checked=$($SHOW_NAMESPACE |
554                         awk '/^checked_phase2/ { print $2 }')
555         [ $checked -ge 4 ] ||
556                 error "(11) Fail to check multiple-linked object: $checked"
557
558         local repaired=$($SHOW_NAMESPACE |
559                          awk '/^multiple_linked_repaired/ { print $2 }')
560         [ $repaired -ge 2 ] ||
561                 error "(12) Fail to repair multiple-linked object: $repaired"
562 }
563 run_test 3 "LFSCK can verify multiple-linked objects"
564
565 test_4()
566 {
567         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
568                 skip "OI Scrub not implemented for ZFS" && return
569
570         lfsck_prep 3 3
571         cleanup_mount $MOUNT || error "(0.1) Fail to stop client!"
572         stop $SINGLEMDS > /dev/null || error "(0.2) Fail to stop MDS!"
573
574         mds_backup_restore $SINGLEMDS || error "(1) Fail to backup/restore!"
575         echo "start $SINGLEMDS with disabling OI scrub"
576         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
577                 error "(2) Fail to start MDS!"
578
579         #define OBD_FAIL_LFSCK_DELAY2           0x1601
580         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
581         $START_NAMESPACE -r || error "(4) Fail to start LFSCK for namespace!"
582         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
583                 mdd.${MDT_DEV}.lfsck_namespace |
584                 awk '/^flags/ { print \\\$2 }'" "inconsistent" 32 || {
585                 $SHOW_NAMESPACE
586                 error "(5) unexpected status"
587         }
588
589         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
590         [ "$STATUS" == "scanning-phase1" ] ||
591                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
592
593         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
594         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
595                 mdd.${MDT_DEV}.lfsck_namespace |
596                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
597                 $SHOW_NAMESPACE
598                 error "(7) unexpected status"
599         }
600
601         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
602         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
603
604         local repaired=$($SHOW_NAMESPACE |
605                          awk '/^dirent_repaired/ { print $2 }')
606         # for interop with old server
607         [ -z "$repaired" ] &&
608                 repaired=$($SHOW_NAMESPACE |
609                          awk '/^updated_phase1/ { print $2 }')
610
611         [ $repaired -ge 9 ] ||
612                 error "(9) Fail to re-generate FID-in-dirent: $repaired"
613
614         run_e2fsck_on_mdt0
615
616         mount_client $MOUNT || error "(10) Fail to start client!"
617
618         #define OBD_FAIL_FID_LOOKUP     0x1505
619         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
620         ls $DIR/$tdir/ > /dev/null || error "(11) no FID-in-dirent."
621         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
622 }
623 run_test 4 "FID-in-dirent can be rebuilt after MDT file-level backup/restore"
624
625 test_5()
626 {
627         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
628                 skip "OI Scrub not implemented for ZFS" && return
629
630         lfsck_prep 1 1 1
631         cleanup_mount $MOUNT || error "(0.1) Fail to stop client!"
632         stop $SINGLEMDS > /dev/null || error "(0.2) Fail to stop MDS!"
633
634         mds_backup_restore $SINGLEMDS 1 || error "(1) Fail to backup/restore!"
635         echo "start $SINGLEMDS with disabling OI scrub"
636         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
637                 error "(2) Fail to start MDS!"
638
639         #define OBD_FAIL_LFSCK_DELAY2           0x1601
640         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
641         $START_NAMESPACE -r || error "(4) Fail to start LFSCK for namespace!"
642         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
643                 mdd.${MDT_DEV}.lfsck_namespace |
644                 awk '/^flags/ { print \\\$2 }'" "inconsistent,upgrade" 32 || {
645                 $SHOW_NAMESPACE
646                 error "(5) unexpected status"
647         }
648
649         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
650         [ "$STATUS" == "scanning-phase1" ] ||
651                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
652
653         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
654         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
655                 mdd.${MDT_DEV}.lfsck_namespace |
656                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
657                 $SHOW_NAMESPACE
658                 error "(7) unexpected status"
659         }
660
661         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
662         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
663
664         local repaired=$($SHOW_NAMESPACE |
665                          awk '/^dirent_repaired/ { print $2 }')
666         # for interop with old server
667         [ -z "$repaired" ] &&
668                 repaired=$($SHOW_NAMESPACE |
669                          awk '/^updated_phase1/ { print $2 }')
670
671         [ $repaired -ge 2 ] ||
672                 error "(9) Fail to generate FID-in-dirent for IGIF: $repaired"
673
674         run_e2fsck_on_mdt0
675
676         mount_client $MOUNT || error "(10) Fail to start client!"
677
678         #define OBD_FAIL_FID_LOOKUP     0x1505
679         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
680         stat $DIR/$tdir/dummy > /dev/null || error "(11) no FID-in-LMA."
681
682         ls $DIR/$tdir/ > /dev/null || error "(12) no FID-in-dirent."
683
684         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
685         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
686         local dummyname=$($LFS fid2path $DIR $dummyfid)
687         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
688                 error "(13) Fail to generate linkEA: $dummyfid $dummyname"
689 }
690 run_test 5 "LFSCK can handle IGIF object upgrading"
691
692 test_6a() {
693         lfsck_prep 5 5
694
695         #define OBD_FAIL_LFSCK_DELAY1           0x1600
696         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
697         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
698
699         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
700         [ "$STATUS" == "scanning-phase1" ] ||
701                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
702
703         # Sleep 3 sec to guarantee at least one object processed by LFSCK
704         sleep 3
705         # Fail the LFSCK to guarantee there is at least one checkpoint
706         #define OBD_FAIL_LFSCK_FATAL1           0x1608
707         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001608
708         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
709                 mdd.${MDT_DEV}.lfsck_namespace |
710                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
711                 $SHOW_NAMESPACE
712                 error "(4) unexpected status"
713         }
714
715         local POS0=$($SHOW_NAMESPACE |
716                      awk '/^last_checkpoint_position/ { print $2 }' |
717                      tr -d ',')
718
719         #define OBD_FAIL_LFSCK_DELAY1           0x1600
720         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
721         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
722
723         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
724         [ "$STATUS" == "scanning-phase1" ] ||
725                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
726
727         local POS1=$($SHOW_NAMESPACE |
728                      awk '/^latest_start_position/ { print $2 }' |
729                      tr -d ',')
730         [[ $POS0 -lt $POS1 ]] ||
731                 error "(7) Expect larger than: $POS0, but got $POS1"
732
733         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
734         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
735                 mdd.${MDT_DEV}.lfsck_namespace |
736                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
737                 $SHOW_NAMESPACE
738                 error "(8) unexpected status"
739         }
740 }
741 run_test 6a "LFSCK resumes from last checkpoint (1)"
742
743 test_6b() {
744         lfsck_prep 5 5
745
746         #define OBD_FAIL_LFSCK_DELAY2           0x1601
747         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
748         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
749
750         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
751         [ "$STATUS" == "scanning-phase1" ] ||
752                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
753
754         # Sleep 5 sec to guarantee that we are in the directory scanning
755         sleep 5
756         # Fail the LFSCK to guarantee there is at least one checkpoint
757         #define OBD_FAIL_LFSCK_FATAL2           0x1609
758         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
759         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
760                 mdd.${MDT_DEV}.lfsck_namespace |
761                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
762                 $SHOW_NAMESPACE
763                 error "(4) unexpected status"
764         }
765
766         local O_POS0=$($SHOW_NAMESPACE |
767                        awk '/^last_checkpoint_position/ { print $2 }' |
768                        tr -d ',')
769
770         local D_POS0=$($SHOW_NAMESPACE |
771                        awk '/^last_checkpoint_position/ { print $4 }')
772
773         #define OBD_FAIL_LFSCK_DELAY2           0x1601
774         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
775         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
776
777         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
778         [ "$STATUS" == "scanning-phase1" ] ||
779                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
780
781         local O_POS1=$($SHOW_NAMESPACE |
782                        awk '/^latest_start_position/ { print $2 }' |
783                        tr -d ',')
784         local D_POS1=$($SHOW_NAMESPACE |
785                        awk '/^latest_start_position/ { print $4 }')
786
787         echo "Additional debug for 6b"
788         $SHOW_NAMESPACE
789         if [ "$D_POS0" == "N/A" -o "$D_POS0" == "0x0" \
790              -o "$D_POS1" == "0x0" -o "$D_POS1" == "N/A" ]; then
791                 [[ $O_POS0 -lt $O_POS1 ]] ||
792                         error "(7.1) $O_POS1 is not larger than $O_POS0"
793         else
794                 [[ $D_POS0 -lt $D_POS1 ]] ||
795                         error "(7.2) $D_POS1 is not larger than $D_POS0"
796         fi
797
798         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
799         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
800                 mdd.${MDT_DEV}.lfsck_namespace |
801                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
802                 $SHOW_NAMESPACE
803                 error "(8) unexpected status"
804         }
805 }
806 run_test 6b "LFSCK resumes from last checkpoint (2)"
807
808 test_7a()
809 {
810         lfsck_prep 5 5
811         umount_client $MOUNT
812
813         #define OBD_FAIL_LFSCK_DELAY2           0x1601
814         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
815         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
816
817         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
818         [ "$STATUS" == "scanning-phase1" ] ||
819                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
820
821         # Sleep 3 sec to guarantee at least one object processed by LFSCK
822         sleep 3
823         echo "stop $SINGLEMDS"
824         stop $SINGLEMDS > /dev/null || error "(4) Fail to stop MDS!"
825
826         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
827         echo "start $SINGLEMDS"
828         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
829                 error "(5) Fail to start MDS!"
830
831         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
832                 mdd.${MDT_DEV}.lfsck_namespace |
833                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
834                 $SHOW_NAMESPACE
835                 error "(6) unexpected status"
836         }
837 }
838 run_test 7a "non-stopped LFSCK should auto restarts after MDS remount (1)"
839
840 test_7b()
841 {
842         lfsck_prep 2 2
843
844         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
845         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
846         for ((i = 0; i < 20; i++)); do
847                 touch $DIR/$tdir/dummy${i}
848         done
849
850         #define OBD_FAIL_LFSCK_DELAY3           0x1602
851         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1602
852         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
853         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
854                 mdd.${MDT_DEV}.lfsck_namespace |
855                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
856                 $SHOW_NAMESPACE
857                 error "(4) unexpected status"
858         }
859
860         umount_client $MOUNT
861         echo "stop $SINGLEMDS"
862         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop MDS!"
863
864         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
865         echo "start $SINGLEMDS"
866         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
867                 error "(6) Fail to start MDS!"
868
869         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
870                 mdd.${MDT_DEV}.lfsck_namespace |
871                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
872                 $SHOW_NAMESPACE
873                 error "(7) unexpected status"
874         }
875 }
876 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
877
878 test_8()
879 {
880         echo "formatall"
881         formatall > /dev/null
882         echo "setupall"
883         setupall > /dev/null
884
885         lfsck_prep 20 20
886
887         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
888         [ "$STATUS" == "init" ] ||
889                 error "(2) Expect 'init', but got '$STATUS'"
890
891         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
892         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
893         mkdir $DIR/$tdir/crashed
894
895         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
896         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
897         for ((i = 0; i < 5; i++)); do
898                 touch $DIR/$tdir/dummy${i}
899         done
900
901         umount_client $MOUNT || error "(3) Fail to stop client!"
902
903         #define OBD_FAIL_LFSCK_DELAY2           0x1601
904         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1601
905         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
906
907         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
908         [ "$STATUS" == "scanning-phase1" ] ||
909                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
910
911         $STOP_LFSCK || error "(6) Fail to stop LFSCK!"
912
913         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
914         [ "$STATUS" == "stopped" ] ||
915                 error "(7) Expect 'stopped', but got '$STATUS'"
916
917         $START_NAMESPACE || error "(8) Fail to start LFSCK for namespace!"
918
919         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
920         [ "$STATUS" == "scanning-phase1" ] ||
921                 error "(9) Expect 'scanning-phase1', but got '$STATUS'"
922
923         #define OBD_FAIL_LFSCK_FATAL2           0x1609
924         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
925         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
926                 mdd.${MDT_DEV}.lfsck_namespace |
927                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
928                 $SHOW_NAMESPACE
929                 error "(10) unexpected status"
930         }
931
932         #define OBD_FAIL_LFSCK_DELAY1           0x1600
933         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
934         $START_NAMESPACE || error "(11) Fail to start LFSCK for namespace!"
935
936         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
937         [ "$STATUS" == "scanning-phase1" ] ||
938                 error "(12) Expect 'scanning-phase1', but got '$STATUS'"
939
940         #define OBD_FAIL_LFSCK_CRASH            0x160a
941         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
942         sleep 5
943
944         echo "stop $SINGLEMDS"
945         stop $SINGLEMDS > /dev/null || error "(13) Fail to stop MDS!"
946
947         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
948         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
949
950         echo "start $SINGLEMDS"
951         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
952                 error "(14) Fail to start MDS!"
953
954         local timeout=$(max_recovery_time)
955         local timer=0
956
957         while [ $timer -lt $timeout ]; do
958                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
959                         mdt.${MDT_DEV}.recovery_status |
960                         awk '/^status/ { print \\\$2 }'")
961                 [ "$STATUS" != "RECOVERING" ] && break;
962                 sleep 1
963                 timer=$((timer + 1))
964         done
965
966         [ $timer != $timeout ] ||
967                 error "(14.1) recovery timeout"
968
969         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
970         [ "$STATUS" == "crashed" ] ||
971                 error "(15) Expect 'crashed', but got '$STATUS'"
972
973         #define OBD_FAIL_LFSCK_DELAY2           0x1601
974         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
975         $START_NAMESPACE || error "(16) Fail to start LFSCK for namespace!"
976
977         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
978         [ "$STATUS" == "scanning-phase1" ] ||
979                 error "(17) Expect 'scanning-phase1', but got '$STATUS'"
980
981         echo "stop $SINGLEMDS"
982         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop MDS!"
983
984         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
985         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
986
987         echo "start $SINGLEMDS"
988         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
989                 error "(19) Fail to start MDS!"
990
991         timer=0
992         while [ $timer -lt $timeout ]; do
993                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
994                         mdt.${MDT_DEV}.recovery_status |
995                         awk '/^status/ { print \\\$2 }'")
996                 [ "$STATUS" != "RECOVERING" ] && break;
997                 sleep 1
998                 timer=$((timer + 1))
999         done
1000
1001         [ $timer != $timeout ] ||
1002                 error "(19.1) recovery timeout"
1003
1004         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1005         [ "$STATUS" == "paused" ] ||
1006                 error "(20) Expect 'paused', but got '$STATUS'"
1007
1008         echo "stop $SINGLEMDS"
1009         stop $SINGLEMDS > /dev/null || error "(20.1) Fail to stop MDS!"
1010
1011         echo "start $SINGLEMDS without resume LFSCK"
1012         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SKIP_LFSCK > /dev/null ||
1013                 error "(20.2) Fail to start MDS!"
1014
1015         timer=0
1016         while [ $timer -lt $timeout ]; do
1017                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1018                         mdt.${MDT_DEV}.recovery_status |
1019                         awk '/^status/ { print \\\$2 }'")
1020                 [ "$STATUS" != "RECOVERING" ] && break;
1021                 sleep 1
1022                 timer=$((timer + 1))
1023         done
1024
1025         [ $timer != $timeout ] ||
1026                 error "(20.3) recovery timeout"
1027
1028         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1029         [ "$STATUS" == "paused" ] ||
1030                 error "(20.4) Expect 'paused', but got '$STATUS'"
1031
1032         #define OBD_FAIL_LFSCK_DELAY3           0x1602
1033         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1602
1034
1035         $START_NAMESPACE || error "(21) Fail to start LFSCK for namespace!"
1036         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1037                 mdd.${MDT_DEV}.lfsck_namespace |
1038                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
1039                 $SHOW_NAMESPACE
1040                 error "(22) unexpected status"
1041         }
1042
1043         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1044         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
1045                 error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
1046
1047         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1048         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1049                 mdd.${MDT_DEV}.lfsck_namespace |
1050                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1051                 $SHOW_NAMESPACE
1052                 error "(24) unexpected status"
1053         }
1054
1055         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1056         [ -z "$FLAGS" ] || error "(25) Expect empty flags, but got '$FLAGS'"
1057 }
1058 run_test 8 "LFSCK state machine"
1059
1060 test_9a() {
1061         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1062                 skip "Testing on UP system, the speed may be inaccurate."
1063                 return 0
1064         fi
1065
1066         check_mount_and_prep
1067         $LFS mkdir -i 0 $DIR/$tdir/lfsck || error "(1) Fail to mkdir lfsck"
1068         $LFS setstripe -c 1 -i -1 $DIR/$tdir/lfsck
1069         createmany -o $DIR/$tdir/lfsck/f 5000
1070
1071         local BASE_SPEED1=100
1072         local RUN_TIME1=10
1073         $START_LAYOUT -r -s $BASE_SPEED1 || error "(2) Fail to start LFSCK!"
1074
1075         sleep $RUN_TIME1
1076         STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
1077         [ "$STATUS" == "scanning-phase1" ] ||
1078                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
1079
1080         local SPEED=$($SHOW_LAYOUT |
1081                       awk '/^average_speed_phase1/ { print $2 }')
1082
1083         # There may be time error, normally it should be less than 2 seconds.
1084         # We allow another 20% schedule error.
1085         local TIME_DIFF=2
1086         # MAX_MARGIN = 1.3 = 13 / 10
1087         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
1088                            RUN_TIME1 * 13 / 10))
1089         [ $SPEED -lt $MAX_SPEED ] || {
1090                 $SHOW_LAYOUT
1091                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1092                 error "(4) Speed $SPEED, expected < $MAX_SPEED"
1093         }
1094
1095         # adjust speed limit
1096         local BASE_SPEED2=300
1097         local RUN_TIME2=10
1098         do_facet $SINGLEMDS \
1099                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1100         sleep $RUN_TIME2
1101
1102         SPEED=$($SHOW_LAYOUT | awk '/^average_speed_phase1/ { print $2 }')
1103         # MIN_MARGIN = 0.7 = 7 / 10
1104         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
1105                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
1106                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1107         [ $SPEED -gt $MIN_SPEED ] || {
1108                 if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
1109                         error_ignore LU-5624 \
1110                         "(5.1) Got speed $SPEED, expected more than $MIN_SPEED"
1111                 else
1112                         error \
1113                         "(5.2) Got speed $SPEED, expected more than $MIN_SPEED"
1114                 fi
1115         }
1116
1117         # MAX_MARGIN = 1.3 = 13 / 10
1118         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
1119                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
1120                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1121         [ $SPEED -lt $MAX_SPEED ] || {
1122                 $SHOW_LAYOUT
1123                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1124                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1125                 error "(6) Speed $SPEED, expected < $MAX_SPEED"
1126         }
1127
1128         do_nodes $(comma_list $(mdts_nodes)) \
1129                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1130         do_nodes $(comma_list $(osts_nodes)) \
1131                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1132
1133         wait_update_facet $SINGLEMDS \
1134                 "$LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout |
1135                 awk '/^status/ { print \\\$2 }'" "completed" 30 ||
1136                 error "(7) Failed to get expected 'completed'"
1137 }
1138 run_test 9a "LFSCK speed control (1)"
1139
1140 test_9b() {
1141         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1142                 skip "Testing on UP system, the speed may be inaccurate."
1143                 return 0
1144         fi
1145
1146         lfsck_prep 0 0
1147
1148         echo "Preparing another 50 * 50 files (with error) at $(date)."
1149         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1150         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1151         createmany -d $DIR/$tdir/d 50
1152         createmany -m $DIR/$tdir/f 50
1153         for ((i = 0; i < 50; i++)); do
1154                 createmany -m $DIR/$tdir/d${i}/f 50 > /dev/null
1155         done
1156
1157         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
1158         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
1159         $START_NAMESPACE -r || error "(4) Fail to start LFSCK!"
1160         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1161                 mdd.${MDT_DEV}.lfsck_namespace |
1162                 awk '/^status/ { print \\\$2 }'" "stopped" 10 || {
1163                 $SHOW_NAMESPACE
1164                 error "(5) unexpected status"
1165         }
1166
1167         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1168         echo "Prepared at $(date)."
1169
1170         local BASE_SPEED1=50
1171         local RUN_TIME1=10
1172         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
1173
1174         sleep $RUN_TIME1
1175         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1176         [ "$STATUS" == "scanning-phase2" ] ||
1177                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
1178
1179         local SPEED=$($SHOW_NAMESPACE |
1180                       awk '/^average_speed_phase2/ { print $2 }')
1181         # There may be time error, normally it should be less than 2 seconds.
1182         # We allow another 20% schedule error.
1183         local TIME_DIFF=2
1184         # MAX_MARGIN = 1.3 = 13 / 10
1185         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
1186                           RUN_TIME1 * 13 / 10))
1187         [ $SPEED -lt $MAX_SPEED ] || {
1188                 $SHOW_NAMESPACE
1189                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1190                 error "(8) Speed $SPEED, expected < $MAX_SPEED"
1191         }
1192
1193         # adjust speed limit
1194         local BASE_SPEED2=150
1195         local RUN_TIME2=10
1196         do_facet $SINGLEMDS \
1197                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1198         sleep $RUN_TIME2
1199
1200         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
1201         # MIN_MARGIN = 0.7 = 7 / 10
1202         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
1203                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
1204                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1205         [ $SPEED -gt $MIN_SPEED ] || {
1206                 if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
1207                         error_ignore LU-5624 \
1208                         "(9.1) Got speed $SPEED, expected more than $MIN_SPEED"
1209                 else
1210                         error \
1211                         "(9.2) Got speed $SPEED, expected more than $MIN_SPEED"
1212                 fi
1213         }
1214
1215         # MAX_MARGIN = 1.3 = 13 / 10
1216         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
1217                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
1218                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1219         [ $SPEED -lt $MAX_SPEED ] || {
1220                 $SHOW_NAMESPACE
1221                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1222                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1223                 error "(10) Speed $SPEED, expected < $MAX_SPEED"
1224         }
1225
1226         do_nodes $(comma_list $(mdts_nodes)) \
1227                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1228         do_nodes $(comma_list $(osts_nodes)) \
1229                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1230         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1231                 mdd.${MDT_DEV}.lfsck_namespace |
1232                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1233                 $SHOW_NAMESPACE
1234                 error "(11) unexpected status"
1235         }
1236 }
1237 run_test 9b "LFSCK speed control (2)"
1238
1239 test_10()
1240 {
1241         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
1242                 skip "lookup(..)/linkea on ZFS issue" && return
1243
1244         lfsck_prep 1 1
1245
1246         echo "Preparing more files with error at $(date)."
1247         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
1248         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
1249
1250         for ((i = 0; i < 1000; i = $((i+2)))); do
1251                 mkdir -p $DIR/$tdir/d${i}
1252                 touch $DIR/$tdir/f${i}
1253                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1254         done
1255
1256         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1257         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1258
1259         for ((i = 1; i < 1000; i = $((i+2)))); do
1260                 mkdir -p $DIR/$tdir/d${i}
1261                 touch $DIR/$tdir/f${i}
1262                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1263         done
1264
1265         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1266         echo "Prepared at $(date)."
1267
1268         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
1269
1270         umount_client $MOUNT
1271         mount_client $MOUNT || error "(3) Fail to start client!"
1272
1273         $START_NAMESPACE -r -s 100 || error "(5) Fail to start LFSCK!"
1274
1275         sleep 10
1276         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1277         [ "$STATUS" == "scanning-phase1" ] ||
1278                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
1279
1280         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
1281
1282         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
1283
1284         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
1285
1286         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
1287
1288         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
1289
1290         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
1291
1292         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
1293
1294         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
1295                 error "(14) Fail to softlink!"
1296
1297         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1298         [ "$STATUS" == "scanning-phase1" ] ||
1299                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
1300
1301         do_nodes $(comma_list $(mdts_nodes)) \
1302                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1303         do_nodes $(comma_list $(osts_nodes)) \
1304                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1305         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1306                 mdd.${MDT_DEV}.lfsck_namespace |
1307                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1308                 $SHOW_NAMESPACE
1309                 error "(16) unexpected status"
1310         }
1311 }
1312 run_test 10 "System is available during LFSCK scanning"
1313
1314 # remove LAST_ID
1315 ost_remove_lastid() {
1316         local ost=$1
1317         local idx=$2
1318         local rcmd="do_facet ost${ost}"
1319
1320         echo "remove LAST_ID on ost${ost}: idx=${idx}"
1321
1322         # step 1: local mount
1323         mount_fstype ost${ost} || return 1
1324         # step 2: remove the specified LAST_ID
1325         ${rcmd} rm -fv $(facet_mntpt ost${ost})/O/${idx}/{LAST_ID,d0/0}
1326         # step 3: umount
1327         unmount_fstype ost${ost} || return 2
1328 }
1329
1330 test_11a() {
1331         check_mount_and_prep
1332         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1333         createmany -o $DIR/$tdir/f 64 || error "(0) Fail to create 64 files."
1334
1335         echo "stopall"
1336         stopall > /dev/null
1337
1338         ost_remove_lastid 1 0 || error "(1) Fail to remove LAST_ID"
1339
1340         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
1341                 error "(2) Fail to start ost1"
1342
1343         #define OBD_FAIL_LFSCK_DELAY4           0x160e
1344         do_facet ost1 $LCTL set_param fail_val=3 fail_loc=0x160e
1345
1346         echo "trigger LFSCK for layout on ost1 to rebuild the LAST_ID(s)"
1347         $START_LAYOUT_ON_OST -r || error "(4) Fail to start LFSCK on OST!"
1348
1349         wait_update_facet ost1 "$LCTL get_param -n \
1350                 obdfilter.${OST_DEV}.lfsck_layout |
1351                 awk '/^flags/ { print \\\$2 }'" "crashed_lastid" 60 || {
1352                 $SHOW_LAYOUT_ON_OST
1353                 error "(5) unexpected status"
1354         }
1355
1356         do_facet ost1 $LCTL set_param fail_val=0 fail_loc=0
1357
1358         wait_update_facet ost1 "$LCTL get_param -n \
1359                 obdfilter.${OST_DEV}.lfsck_layout |
1360                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1361                 $SHOW_LAYOUT_ON_OST
1362                 error "(6) unexpected status"
1363         }
1364
1365         echo "the LAST_ID(s) should have been rebuilt"
1366         FLAGS=$($SHOW_LAYOUT_ON_OST | awk '/^flags/ { print $2 }')
1367         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
1368 }
1369 run_test 11a "LFSCK can rebuild lost last_id"
1370
1371 test_11b() {
1372         check_mount_and_prep
1373         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1374
1375         echo "set fail_loc=0x160d to skip the updating LAST_ID on-disk"
1376         #define OBD_FAIL_LFSCK_SKIP_LASTID      0x160d
1377         do_facet ost1 $LCTL set_param fail_loc=0x160d
1378
1379         local count=$(precreated_ost_obj_count 0 0)
1380
1381         createmany -o $DIR/$tdir/f $((count + 32))
1382
1383         local proc_path="${FSNAME}-OST0000-osc-MDT0000"
1384         local seq=$(do_facet mds1 $LCTL get_param -n \
1385                     osp.${proc_path}.prealloc_last_seq)
1386         local lastid1=$(do_facet ost1 "lctl get_param -n \
1387                 obdfilter.${ost1_svc}.last_id" | grep $seq |
1388                 awk -F: '{ print $2 }')
1389
1390         umount_client $MOUNT
1391         stop ost1 || error "(1) Fail to stop ost1"
1392
1393         #define OBD_FAIL_OST_ENOSPC              0x215
1394         do_facet ost1 $LCTL set_param fail_loc=0x215
1395
1396         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1397                 error "(2) Fail to start ost1"
1398
1399         for ((i = 0; i < 60; i++)); do
1400                 lastid2=$(do_facet ost1 "lctl get_param -n \
1401                         obdfilter.${ost1_svc}.last_id" | grep $seq |
1402                         awk -F: '{ print $2 }')
1403                 [ ! -z $lastid2 ] && break;
1404                 sleep 1
1405         done
1406
1407         echo "the on-disk LAST_ID should be smaller than the expected one"
1408         [ $lastid1 -gt $lastid2 ] ||
1409                 error "(4) expect lastid1 [ $lastid1 ] > lastid2 [ $lastid2 ]"
1410
1411         echo "trigger LFSCK for layout on ost1 to rebuild the on-disk LAST_ID"
1412         $START_LAYOUT_ON_OST -r || error "(5) Fail to start LFSCK on OST!"
1413
1414         wait_update_facet ost1 "$LCTL get_param -n \
1415                 obdfilter.${OST_DEV}.lfsck_layout |
1416                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1417                 $SHOW_LAYOUT_ON_OST
1418                 error "(6) unexpected status"
1419         }
1420
1421         stop ost1 || error "(7) Fail to stop ost1"
1422
1423         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1424                 error "(8) Fail to start ost1"
1425
1426         echo "the on-disk LAST_ID should have been rebuilt"
1427         wait_update_facet ost1 "$LCTL get_param -n \
1428                 obdfilter.${ost1_svc}.last_id | grep $seq |
1429                 awk -F: '{ print \\\$2 }'" "$lastid1" 60 || {
1430                 do_facet ost1 $LCTL get_param -n \
1431                 obdfilter.${ost1_svc}.last_id
1432                 error "(9) expect lastid1 $seq:$lastid1"
1433         }
1434
1435         do_facet ost1 $LCTL set_param fail_loc=0
1436         stopall || error "(10) Fail to stopall"
1437 }
1438 run_test 11b "LFSCK can rebuild crashed last_id"
1439
1440 test_12a() {
1441         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1442
1443         check_mount_and_prep
1444         for k in $(seq $MDSCOUNT); do
1445                 $LFS mkdir -i $((k - 1)) $DIR/$tdir/${k}
1446                 createmany -o $DIR/$tdir/${k}/f 100 ||
1447                         error "(0) Fail to create 100 files."
1448         done
1449
1450         echo "Start namespace LFSCK on all targets by single command (-s 1)."
1451         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1452                 -s 1 -r || error "(2) Fail to start LFSCK on all devices!"
1453
1454         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1455         wait_all_targets namespace scanning-phase1 3
1456
1457         echo "Stop namespace LFSCK on all targets by single lctl command."
1458         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1459                 error "(4) Fail to stop LFSCK on all devices!"
1460
1461         echo "All the LFSCK targets should be in 'stopped' status."
1462         wait_all_targets_blocked namespace stopped 5
1463
1464         echo "Re-start namespace LFSCK on all targets by single command (-s 0)."
1465         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1466                 -s 0 -r || error "(6) Fail to start LFSCK on all devices!"
1467
1468         echo "All the LFSCK targets should be in 'completed' status."
1469         wait_all_targets_blocked namespace completed 7
1470
1471         start_full_debug_logging
1472
1473         echo "Start layout LFSCK on all targets by single command (-s 1)."
1474         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1475                 -s 1 -r || error "(8) Fail to start LFSCK on all devices!"
1476
1477         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1478         wait_all_targets layout scanning-phase1 9
1479
1480         echo "Stop layout LFSCK on all targets by single lctl command."
1481         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1482                 error "(10) Fail to stop LFSCK on all devices!"
1483
1484         echo "All the LFSCK targets should be in 'stopped' status."
1485         wait_all_targets_blocked layout stopped 11
1486
1487         for k in $(seq $OSTCOUNT); do
1488                 local STATUS=$(do_facet ost${k} $LCTL get_param -n \
1489                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1490                                 awk '/^status/ { print $2 }')
1491                 [ "$STATUS" == "stopped" ] ||
1492                         error "(12) OST${k} Expect 'stopped', but got '$STATUS'"
1493         done
1494
1495         echo "Re-start layout LFSCK on all targets by single command (-s 0)."
1496         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1497                 -s 0 -r || error "(13) Fail to start LFSCK on all devices!"
1498
1499         echo "All the LFSCK targets should be in 'completed' status."
1500         wait_all_targets_blocked layout completed 14
1501
1502         stop_full_debug_logging
1503 }
1504 run_test 12a "single command to trigger LFSCK on all devices"
1505
1506 test_12b() {
1507         check_mount_and_prep
1508
1509         echo "Start LFSCK without '-M' specified."
1510         do_facet mds1 $LCTL lfsck_start -A -r ||
1511                 error "(0) Fail to start LFSCK without '-M'"
1512
1513         wait_all_targets_blocked namespace completed 1
1514         wait_all_targets_blocked layout completed 2
1515
1516         local count=$(do_facet mds1 $LCTL dl |
1517                       awk '{ print $3 }' | grep mdt | wc -l)
1518         if [ $count -gt 1 ]; then
1519                 echo
1520                 echo "Start layout LFSCK on the node with multipe targets,"
1521                 echo "but not specify '-M'/'-A' option. Should get failure."
1522                 echo
1523                 do_facet mds1 $LCTL lfsck_start -t layout -r &&
1524                         error "(3) Start layout LFSCK should fail" || true
1525         fi
1526 }
1527 run_test 12b "auto detect Lustre device"
1528
1529 test_13() {
1530         echo "#####"
1531         echo "The lmm_oi in layout EA should be consistent with the MDT-object"
1532         echo "FID; otherwise, the LFSCK should re-generate the lmm_oi from the"
1533         echo "MDT-object FID."
1534         echo "#####"
1535
1536         check_mount_and_prep
1537
1538         echo "Inject failure stub to simulate bad lmm_oi"
1539         #define OBD_FAIL_LFSCK_BAD_LMMOI        0x160f
1540         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160f
1541         createmany -o $DIR/$tdir/f 1
1542         $LFS setstripe -E 1M -S 1M -E -1 $DIR/$tdir/f1 ||
1543                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1544         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1545
1546         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
1547         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1548
1549         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1550                 mdd.${MDT_DEV}.lfsck_layout |
1551                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1552                 $SHOW_LAYOUT
1553                 error "(2) unexpected status"
1554         }
1555
1556         local repaired=$($SHOW_LAYOUT |
1557                          awk '/^repaired_others/ { print $2 }')
1558         [ $repaired -eq 2 ] ||
1559                 error "(3) Fail to repair crashed lmm_oi: $repaired"
1560 }
1561 run_test 13 "LFSCK can repair crashed lmm_oi"
1562
1563 test_14a() {
1564         echo "#####"
1565         echo "The OST-object referenced by the MDT-object should be there;"
1566         echo "otherwise, the LFSCK should re-create the missing OST-object."
1567         echo "without '--delay-create-ostobj' option."
1568         echo "#####"
1569
1570         check_mount_and_prep
1571         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1572
1573         echo "Inject failure stub to simulate dangling referenced MDT-object"
1574         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1575         do_facet ost1 $LCTL set_param fail_loc=0x1610
1576         local count=$(precreated_ost_obj_count 0 0)
1577
1578         createmany -o $DIR/$tdir/f $((count + 16)) ||
1579                 error "(0.1) Fail to create $DIR/$tdir/fx"
1580         touch $DIR/$tdir/guard0
1581
1582         for ((i = 0; i < 16; i++)); do
1583                 $LFS setstripe -E 512K -S 256K -o 0 -E 2M \
1584                         $DIR/$tdir/f_comp${i} ||
1585                         error "(0.2) Fail to create $DIR/$tdir/f_comp${i}"
1586         done
1587         touch $DIR/$tdir/guard1
1588
1589         do_facet ost1 $LCTL set_param fail_loc=0
1590
1591         start_full_debug_logging
1592
1593         # exhaust other pre-created dangling cases
1594         count=$(precreated_ost_obj_count 0 0)
1595         createmany -o $DIR/$tdir/a $count ||
1596                 error "(0.5) Fail to create $count files."
1597
1598         echo "'ls' should fail because of dangling referenced MDT-object"
1599         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1600
1601         echo "Trigger layout LFSCK to find out dangling reference"
1602         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1603
1604         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1605                 mdd.${MDT_DEV}.lfsck_layout |
1606                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1607                 $SHOW_LAYOUT
1608                 error "(3) unexpected status"
1609         }
1610
1611         local repaired=$($SHOW_LAYOUT |
1612                          awk '/^repaired_dangling/ { print $2 }')
1613         [ $repaired -ge 32 ] ||
1614                 error "(4) Fail to repair dangling reference: $repaired"
1615
1616         echo "'stat' should fail because of not repair dangling by default"
1617         stat $DIR/$tdir/guard0 > /dev/null 2>&1 &&
1618                 error "(5.1) stat should fail"
1619         stat $DIR/$tdir/guard1 > /dev/null 2>&1 &&
1620                 error "(5.2) stat should fail"
1621
1622         echo "Trigger layout LFSCK to repair dangling reference"
1623         $START_LAYOUT -r -c || error "(6) Fail to start LFSCK for layout!"
1624
1625         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1626                 mdd.${MDT_DEV}.lfsck_layout |
1627                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1628                 $SHOW_LAYOUT
1629                 error "(7) unexpected status"
1630         }
1631
1632         # There may be some async LFSCK updates in processing, wait for
1633         # a while until the target reparation has been done. LU-4970.
1634
1635         echo "'stat' should success after layout LFSCK repairing"
1636         wait_update_facet client "stat $DIR/$tdir/guard0 |
1637                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1638                 stat $DIR/$tdir/guard0
1639                 $SHOW_LAYOUT
1640                 error "(8.1) unexpected size"
1641         }
1642
1643         wait_update_facet client "stat $DIR/$tdir/guard1 |
1644                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1645                 stat $DIR/$tdir/guard1
1646                 $SHOW_LAYOUT
1647                 error "(8.2) unexpected size"
1648         }
1649
1650         repaired=$($SHOW_LAYOUT |
1651                          awk '/^repaired_dangling/ { print $2 }')
1652         [ $repaired -ge 32 ] ||
1653                 error "(9) Fail to repair dangling reference: $repaired"
1654
1655         stop_full_debug_logging
1656
1657         echo "stopall to cleanup object cache"
1658         stopall > /dev/null
1659         echo "setupall"
1660         setupall > /dev/null
1661 }
1662 run_test 14a "LFSCK can repair MDT-object with dangling LOV EA reference (1)"
1663
1664 test_14b() {
1665         echo "#####"
1666         echo "The OST-object referenced by the MDT-object should be there;"
1667         echo "otherwise, the LFSCK should re-create the missing OST-object."
1668         echo "with '--delay-create-ostobj' option."
1669         echo "#####"
1670
1671         check_mount_and_prep
1672         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1673
1674         echo "Inject failure stub to simulate dangling referenced MDT-object"
1675         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1676         do_facet ost1 $LCTL set_param fail_loc=0x1610
1677         local count=$(precreated_ost_obj_count 0 0)
1678
1679         createmany -o $DIR/$tdir/f $((count + 31))
1680         touch $DIR/$tdir/guard
1681         do_facet ost1 $LCTL set_param fail_loc=0
1682
1683         start_full_debug_logging
1684
1685         # exhaust other pre-created dangling cases
1686         count=$(precreated_ost_obj_count 0 0)
1687         createmany -o $DIR/$tdir/a $count ||
1688                 error "(0) Fail to create $count files."
1689
1690         echo "'ls' should fail because of dangling referenced MDT-object"
1691         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1692
1693         echo "Trigger layout LFSCK to find out dangling reference"
1694         $START_LAYOUT -r -o -d || error "(2) Fail to start LFSCK for layout!"
1695
1696         wait_all_targets_blocked layout completed 3
1697
1698         local repaired=$($SHOW_LAYOUT |
1699                          awk '/^repaired_dangling/ { print $2 }')
1700         [ $repaired -ge 32 ] ||
1701                 error "(4) Fail to repair dangling reference: $repaired"
1702
1703         echo "'stat' should fail because of not repair dangling by default"
1704         stat $DIR/$tdir/guard > /dev/null 2>&1 && error "(5) stat should fail"
1705
1706         echo "Trigger layout LFSCK to repair dangling reference"
1707         $START_LAYOUT -r -o -c -d || error "(6) Fail to start LFSCK for layout!"
1708
1709         wait_all_targets_blocked layout completed 7
1710
1711         # There may be some async LFSCK updates in processing, wait for
1712         # a while until the target reparation has been done. LU-4970.
1713
1714         echo "'stat' should success after layout LFSCK repairing"
1715         wait_update_facet client "stat $DIR/$tdir/guard |
1716                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1717                 stat $DIR/$tdir/guard
1718                 $SHOW_LAYOUT
1719                 error "(8) unexpected size"
1720         }
1721
1722         repaired=$($SHOW_LAYOUT |
1723                          awk '/^repaired_dangling/ { print $2 }')
1724         [ $repaired -ge 32 ] ||
1725                 error "(9) Fail to repair dangling reference: $repaired"
1726
1727         stop_full_debug_logging
1728
1729         echo "stopall to cleanup object cache"
1730         stopall > /dev/null
1731         echo "setupall"
1732         setupall > /dev/null
1733 }
1734 run_test 14b "LFSCK can repair MDT-object with dangling LOV EA reference (2)"
1735
1736 test_15a() {
1737         echo "#####"
1738         echo "If the OST-object referenced by the MDT-object back points"
1739         echo "to some non-exist MDT-object, then the LFSCK should repair"
1740         echo "the OST-object to back point to the right MDT-object."
1741         echo "#####"
1742
1743         check_mount_and_prep
1744         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1745
1746         echo "Inject failure stub to make the OST-object to back point to"
1747         echo "non-exist MDT-object."
1748         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
1749
1750         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
1751         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1752         $LFS setstripe -E 1M -S 256K -c 1 -E -1 -S 512K -c $OSTCOUNT \
1753                 $DIR/$tdir/f1 ||
1754                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1755         # 'dd' will trigger punch RPC firstly on every OST-objects.
1756         # So even though some OST-object will not be write by 'dd',
1757         # as long as it is allocated (may be NOT allocated in pfl_3b)
1758         # its layout information will be set also.
1759         dd if=/dev/zero of=$DIR/$tdir/f1 bs=4K count=257
1760         cancel_lru_locks osc
1761         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1762
1763         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1764         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1765
1766         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1767                 mdd.${MDT_DEV}.lfsck_layout |
1768                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1769                 $SHOW_LAYOUT
1770                 error "(2) unexpected status"
1771         }
1772
1773         local repaired=$($SHOW_LAYOUT |
1774                          awk '/^repaired_unmatched_pair/ { print $2 }')
1775         [ $repaired -ge 3 ] ||
1776                 error "(3) Fail to repair unmatched pair: $repaired"
1777 }
1778 run_test 15a "LFSCK can repair unmatched MDT-object/OST-object pairs (1)"
1779
1780 test_15b() {
1781         echo "#####"
1782         echo "If the OST-object referenced by the MDT-object back points"
1783         echo "to other MDT-object that doesn't recognize the OST-object,"
1784         echo "then the LFSCK should repair it to back point to the right"
1785         echo "MDT-object (the first one)."
1786         echo "#####"
1787
1788         check_mount_and_prep
1789         mkdir -p $DIR/$tdir/0
1790         $LFS setstripe -c 1 -i 0 $DIR/$tdir/0
1791         dd if=/dev/zero of=$DIR/$tdir/0/guard bs=1M count=1
1792         cancel_lru_locks osc
1793
1794         echo "Inject failure stub to make the OST-object to back point to"
1795         echo "other MDT-object"
1796
1797         local stripes=1
1798         [ $OSTCOUNT -ge 2 ] && stripes=2
1799
1800         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR2  0x1612
1801         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1612
1802         dd if=/dev/zero of=$DIR/$tdir/0/f0 bs=1M count=1
1803         $LFS setstripe -E 1M -S 256K -c $stripes -E 2M -S 512K -c 1 \
1804                 $DIR/$tdir/f1 ||
1805                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1806         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2
1807         cancel_lru_locks osc
1808         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1809
1810         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1811         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1812
1813         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1814                 mdd.${MDT_DEV}.lfsck_layout |
1815                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1816                 $SHOW_LAYOUT
1817                 error "(2) unexpected status"
1818         }
1819
1820         local repaired=$($SHOW_LAYOUT |
1821                          awk '/^repaired_unmatched_pair/ { print $2 }')
1822         [ $repaired -eq 4 ] ||
1823                 error "(3) Fail to repair unmatched pair: $repaired"
1824 }
1825 run_test 15b "LFSCK can repair unmatched MDT-object/OST-object pairs (2)"
1826
1827 test_15c() {
1828         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1829
1830         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.7.55) ] &&
1831                 skip "Skip the test after 2.7.55 see LU-6437" && return
1832
1833         echo "#####"
1834         echo "According to current metadata migration implementation,"
1835         echo "before the old MDT-object is removed, both the new MDT-object"
1836         echo "and old MDT-object will reference the same LOV layout. Then if"
1837         echo "the layout LFSCK finds the new MDT-object by race, it will"
1838         echo "regard related OST-object(s) as multiple referenced case, and"
1839         echo "will try to create new OST-object(s) for the new MDT-object."
1840         echo "To avoid such trouble, the layout LFSCK needs to lock the old"
1841         echo "MDT-object before confirm the multiple referenced case."
1842         echo "#####"
1843
1844         check_mount_and_prep
1845         $LFS mkdir -i 1 $DIR/$tdir/a1
1846         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
1847         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=1
1848         cancel_lru_locks osc
1849
1850         echo "Inject failure stub on MDT1 to delay the migration"
1851
1852         #define OBD_FAIL_MIGRATE_DELAY                  0x1803
1853         do_facet mds2 $LCTL set_param fail_val=5 fail_loc=0x1803
1854         echo "Migrate $DIR/$tdir/a1 from MDT1 to MDT0 with delay"
1855         $LFS migrate -m 0 $DIR/$tdir/a1 &
1856
1857         sleep 1
1858         echo "Trigger layout LFSCK to race with the migration"
1859         $START_LAYOUT -A -r || error "(1) Fail to start layout LFSCK!"
1860
1861         wait_all_targets_blocked layout completed 2
1862
1863         do_facet mds2 $LCTL set_param fail_loc=0 fail_val=0
1864         local repaired=$($SHOW_LAYOUT |
1865                          awk '/^repaired_unmatched_pair/ { print $2 }')
1866         [ $repaired -eq 1 ] ||
1867                 error "(3) Fail to repair unmatched pair: $repaired"
1868
1869         repaired=$($SHOW_LAYOUT |
1870                    awk '/^repaired_multiple_referenced/ { print $2 }')
1871         [ $repaired -eq 0 ] ||
1872                 error "(4) Unexpectedly repaird multiple references: $repaired"
1873 }
1874 run_test 15c "LFSCK can repair unmatched MDT-object/OST-object pairs (3)"
1875
1876 test_16() {
1877         echo "#####"
1878         echo "If the OST-object's owner information does not match the owner"
1879         echo "information stored in the MDT-object, then the LFSCK trust the"
1880         echo "MDT-object and update the OST-object's owner information."
1881         echo "#####"
1882
1883         check_mount_and_prep
1884         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1885         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1886         cancel_lru_locks osc
1887
1888         # created but no setattr or write to the file.
1889         mkdir $DIR/$tdir/d1
1890         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/d1
1891         $RUNAS createmany -o $DIR/$tdir/d1/o 100 || error "create failed"
1892
1893         echo "Inject failure stub to skip OST-object owner changing"
1894         #define OBD_FAIL_LFSCK_BAD_OWNER        0x1613
1895         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1613
1896         chown 1.1 $DIR/$tdir/f0
1897         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1898
1899         echo "Trigger layout LFSCK to find out inconsistent OST-object owner"
1900         echo "and fix them"
1901
1902         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1903
1904         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1905                 mdd.${MDT_DEV}.lfsck_layout |
1906                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1907                 $SHOW_LAYOUT
1908                 error "(2) unexpected status"
1909         }
1910
1911         local repaired=$($SHOW_LAYOUT |
1912                          awk '/^repaired_inconsistent_owner/ { print $2 }')
1913         [ $repaired -eq 1 ] ||
1914                 error "(3) Fail to repair inconsistent owner: $repaired"
1915 }
1916 run_test 16 "LFSCK can repair inconsistent MDT-object/OST-object owner"
1917
1918 test_17() {
1919         echo "#####"
1920         echo "If more than one MDT-objects reference the same OST-object,"
1921         echo "and the OST-object only recognizes one MDT-object, then the"
1922         echo "LFSCK should create new OST-objects for such non-recognized"
1923         echo "MDT-objects."
1924         echo "#####"
1925
1926         check_mount_and_prep
1927         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1928
1929         echo "Inject failure stub to make two MDT-objects to refernce"
1930         echo "the OST-object"
1931
1932         #define OBD_FAIL_LFSCK_MULTIPLE_REF     0x1614
1933         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0x1614
1934         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
1935         cancel_lru_locks mdc
1936         cancel_lru_locks osc
1937
1938         createmany -o $DIR/$tdir/f 1
1939         cancel_lru_locks mdc
1940         cancel_lru_locks osc
1941
1942         $LFS setstripe -E 2M -S 256K -o 0 -E 4M -S 512K -o 0 \
1943                 $DIR/$tdir/f1 ||
1944                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1945         cancel_lru_locks mdc
1946         cancel_lru_locks osc
1947         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1948
1949         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard use the same OST-objects"
1950         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard use the same OST-objects"
1951         local size=$(ls -l $DIR/$tdir/f0 | awk '{ print $5 }')
1952         [ $size -eq 1048576 ] ||
1953                 error "(1.1) f0 (wrong) size should be 1048576, but got $size"
1954
1955         size=$(ls -l $DIR/$tdir/f1 | awk '{ print $5 }')
1956         [ $size -eq 1048576 ] ||
1957                 error "(1.2) f1 (wrong) size should be 1048576, but got $size"
1958
1959         echo "Trigger layout LFSCK to find out multiple refenced MDT-objects"
1960         echo "and fix them"
1961
1962         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1963
1964         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1965                 mdd.${MDT_DEV}.lfsck_layout |
1966                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1967                 $SHOW_LAYOUT
1968                 error "(3) unexpected status"
1969         }
1970
1971         local repaired=$($SHOW_LAYOUT |
1972                          awk '/^repaired_multiple_referenced/ { print $2 }')
1973         [ $repaired -eq 2 ] ||
1974                 error "(4) Fail to repair multiple references: $repaired"
1975
1976         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard should use diff OST-objects"
1977         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=2 ||
1978                 error "(5) Fail to write f0."
1979         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
1980         [ $size -eq 1048576 ] ||
1981                 error "(6) guard size should be 1048576, but got $size"
1982
1983         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard should use diff OST-objects"
1984         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2 ||
1985                 error "(7) Fail to write f1."
1986         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
1987         [ $size -eq 1048576 ] ||
1988                 error "(8) guard size should be 1048576, but got $size"
1989 }
1990 run_test 17 "LFSCK can repair multiple references"
1991
1992 $LCTL set_param debug=+cache > /dev/null
1993
1994 test_18a() {
1995         echo "#####"
1996         echo "The target MDT-object is there, but related stripe information"
1997         echo "is lost or partly lost. The LFSCK should regenerate the missing"
1998         echo "layout EA entries."
1999         echo "#####"
2000
2001         check_mount_and_prep
2002         $LFS mkdir -i 0 $DIR/$tdir/a1
2003         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2004         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2005
2006         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2007
2008         $LFS path2fid $DIR/$tdir/a1/f1
2009         $LFS getstripe $DIR/$tdir/a1/f1
2010
2011         if [ $MDSCOUNT -ge 2 ]; then
2012                 $LFS mkdir -i 1 $DIR/$tdir/a2
2013                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2014                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2015                 $LFS path2fid $DIR/$tdir/a2/f2
2016                 $LFS getstripe $DIR/$tdir/a2/f2
2017         fi
2018
2019         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2020                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2021
2022         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2023
2024         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2025
2026         $LFS path2fid $DIR/$tdir/f3
2027         $LFS getstripe $DIR/$tdir/f3
2028
2029         cancel_lru_locks osc
2030
2031         echo "Inject failure, to make the MDT-object lost its layout EA"
2032         #define OBD_FAIL_LFSCK_LOST_STRIPE 0x1615
2033         do_facet mds1 $LCTL set_param fail_loc=0x1615
2034         chown 1.1 $DIR/$tdir/a1/f1
2035
2036         if [ $MDSCOUNT -ge 2 ]; then
2037                 do_facet mds2 $LCTL set_param fail_loc=0x1615
2038                 chown 1.1 $DIR/$tdir/a2/f2
2039         fi
2040
2041         chown 1.1 $DIR/$tdir/f3
2042
2043         sync
2044         sleep 2
2045
2046         do_facet mds1 $LCTL set_param fail_loc=0
2047         if [ $MDSCOUNT -ge 2 ]; then
2048                 do_facet mds2 $LCTL set_param fail_loc=0
2049         fi
2050
2051         cancel_lru_locks mdc
2052         cancel_lru_locks osc
2053
2054         echo "The file size should be incorrect since layout EA is lost"
2055         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2056         [ "$cur_size" != "$saved_size1" ] ||
2057                 error "(1) Expect incorrect file1 size"
2058
2059         if [ $MDSCOUNT -ge 2 ]; then
2060                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2061                 [ "$cur_size" != "$saved_size1" ] ||
2062                         error "(2) Expect incorrect file2 size"
2063         fi
2064
2065         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2066         [ "$cur_size" != "$saved_size2" ] ||
2067                 error "(1.2) Expect incorrect file3 size"
2068
2069         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2070         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
2071
2072         for k in $(seq $MDSCOUNT); do
2073                 # The LFSCK status query internal is 30 seconds. For the case
2074                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2075                 # time to guarantee the status sync up.
2076                 wait_update_facet mds${k} "$LCTL get_param -n \
2077                         mdd.$(facet_svc mds${k}).lfsck_layout |
2078                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2079                         error "(4) MDS${k} is not the expected 'completed'"
2080         done
2081
2082         for k in $(seq $OSTCOUNT); do
2083                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2084                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2085                                 awk '/^status/ { print $2 }')
2086                 [ "$cur_status" == "completed" ] ||
2087                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2088         done
2089
2090         local repaired=$(do_facet mds1 $LCTL get_param -n \
2091                          mdd.$(facet_svc mds1).lfsck_layout |
2092                          awk '/^repaired_orphan/ { print $2 }')
2093         [ $repaired -eq 3 ] ||
2094         error "(6.1) Expect 3 fixed on mds1, but got: $repaired"
2095
2096         if [ $MDSCOUNT -ge 2 ]; then
2097                 repaired=$(do_facet mds2 $LCTL get_param -n \
2098                          mdd.$(facet_svc mds2).lfsck_layout |
2099                                  awk '/^repaired_orphan/ { print $2 }')
2100                 [ $repaired -eq 2 ] ||
2101                 error "(6.2) Expect 2 fixed on mds2, but got: $repaired"
2102         fi
2103
2104         $LFS path2fid $DIR/$tdir/a1/f1
2105         $LFS getstripe $DIR/$tdir/a1/f1
2106
2107         if [ $MDSCOUNT -ge 2 ]; then
2108                 $LFS path2fid $DIR/$tdir/a2/f2
2109                 $LFS getstripe $DIR/$tdir/a2/f2
2110         fi
2111
2112         $LFS path2fid $DIR/$tdir/f3
2113         $LFS getstripe $DIR/$tdir/f3
2114
2115         echo "The file size should be correct after layout LFSCK scanning"
2116         cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2117         [ "$cur_size" == "$saved_size1" ] ||
2118                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2119
2120         if [ $MDSCOUNT -ge 2 ]; then
2121                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2122                 [ "$cur_size" == "$saved_size1" ] ||
2123                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2124         fi
2125
2126         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2127         [ "$cur_size" == "$saved_size2" ] ||
2128                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2129 }
2130 run_test 18a "Find out orphan OST-object and repair it (1)"
2131
2132 test_18b() {
2133         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2134
2135         echo "#####"
2136         echo "The target MDT-object is lost. The LFSCK should re-create the"
2137         echo "MDT-object under .lustre/lost+found/MDTxxxx. The admin should"
2138         echo "can move it back to normal namespace manually."
2139         echo "#####"
2140
2141         check_mount_and_prep
2142         $LFS mkdir -i 0 $DIR/$tdir/a1
2143         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2144         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2145         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2146         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2147         echo ${fid1}
2148         $LFS getstripe $DIR/$tdir/a1/f1
2149
2150         if [ $MDSCOUNT -ge 2 ]; then
2151                 $LFS mkdir -i 1 $DIR/$tdir/a2
2152                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2153                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2154                 fid2=$($LFS path2fid $DIR/$tdir/a2/f2)
2155                 echo ${fid2}
2156                 $LFS getstripe $DIR/$tdir/a2/f2
2157         fi
2158
2159         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2160                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2161
2162         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2163
2164         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2165         local fid3=$($LFS path2fid $DIR/$tdir/f3)
2166         echo ${fid3}
2167         $LFS getstripe $DIR/$tdir/f3
2168
2169         cancel_lru_locks osc
2170
2171         echo "Inject failure, to simulate the case of missing the MDT-object"
2172         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2173         do_facet mds1 $LCTL set_param fail_loc=0x1616
2174         rm -f $DIR/$tdir/a1/f1
2175
2176         if [ $MDSCOUNT -ge 2 ]; then
2177                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2178                 rm -f $DIR/$tdir/a2/f2
2179         fi
2180
2181         rm -f $DIR/$tdir/f3
2182
2183         sync
2184         sleep 2
2185
2186         do_facet mds1 $LCTL set_param fail_loc=0
2187         if [ $MDSCOUNT -ge 2 ]; then
2188                 do_facet mds2 $LCTL set_param fail_loc=0
2189         fi
2190
2191         cancel_lru_locks mdc
2192         cancel_lru_locks osc
2193
2194         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2195         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2196
2197         for k in $(seq $MDSCOUNT); do
2198                 # The LFSCK status query internal is 30 seconds. For the case
2199                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2200                 # time to guarantee the status sync up.
2201                 wait_update_facet mds${k} "$LCTL get_param -n \
2202                         mdd.$(facet_svc mds${k}).lfsck_layout |
2203                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2204                         error "(2) MDS${k} is not the expected 'completed'"
2205         done
2206
2207         for k in $(seq $OSTCOUNT); do
2208                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2209                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2210                                 awk '/^status/ { print $2 }')
2211                 [ "$cur_status" == "completed" ] ||
2212                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2213         done
2214
2215         local repaired=$(do_facet mds1 $LCTL get_param -n \
2216                          mdd.$(facet_svc mds1).lfsck_layout |
2217                          awk '/^repaired_orphan/ { print $2 }')
2218         [ $repaired -eq 3 ] ||
2219         error "(4.1) Expect 3 fixed on mds1, but got: $repaired"
2220
2221         if [ $MDSCOUNT -ge 2 ]; then
2222                 repaired=$(do_facet mds2 $LCTL get_param -n \
2223                          mdd.$(facet_svc mds2).lfsck_layout |
2224                          awk '/^repaired_orphan/ { print $2 }')
2225                 [ $repaired -eq 2 ] ||
2226                 error "(4.2) Expect 2 fixed on mds2, but got: $repaired"
2227         fi
2228
2229         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2230         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2231         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2232
2233         if [ $MDSCOUNT -ge 2 ]; then
2234                 local name=$MOUNT/.lustre/lost+found/MDT0001/${fid2}-R-0
2235                 mv $name $DIR/$tdir/a2/f2 || error "(6) Fail to move $name"
2236         fi
2237
2238         mv $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0 $DIR/$tdir/f3 ||
2239         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
2240
2241         $LFS path2fid $DIR/$tdir/a1/f1
2242         $LFS getstripe $DIR/$tdir/a1/f1
2243
2244         if [ $MDSCOUNT -ge 2 ]; then
2245                 $LFS path2fid $DIR/$tdir/a2/f2
2246                 $LFS getstripe $DIR/$tdir/a2/f2
2247         fi
2248
2249         $LFS path2fid $DIR/$tdir/f3
2250         $LFS getstripe $DIR/$tdir/f3
2251
2252         echo "The file size should be correct after layout LFSCK scanning"
2253         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2254         [ "$cur_size" == "$saved_size1" ] ||
2255                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2256
2257         if [ $MDSCOUNT -ge 2 ]; then
2258                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2259                 [ "$cur_size" == "$saved_size1" ] ||
2260                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2261         fi
2262
2263         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2264         [ "$cur_size" == "$saved_size2" ] ||
2265                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2266 }
2267 run_test 18b "Find out orphan OST-object and repair it (2)"
2268
2269 test_18c() {
2270         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2271
2272         echo "#####"
2273         echo "The target MDT-object is lost, and the OST-object FID is missing."
2274         echo "The LFSCK should re-create the MDT-object with new FID under the "
2275         echo "directory .lustre/lost+found/MDTxxxx."
2276         echo "#####"
2277
2278         check_mount_and_prep
2279         $LFS mkdir -i 0 $DIR/$tdir/a1
2280         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2281
2282         echo "Inject failure, to simulate the case of missing parent FID"
2283         #define OBD_FAIL_LFSCK_NOPFID           0x1617
2284         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1617
2285
2286         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2287         $LFS getstripe $DIR/$tdir/a1/f1
2288
2289         if [ $MDSCOUNT -ge 2 ]; then
2290                 $LFS mkdir -i 1 $DIR/$tdir/a2
2291                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a2
2292                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2293                 $LFS getstripe $DIR/$tdir/a2/f2
2294         fi
2295
2296         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2297                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2298
2299         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2300         $LFS getstripe $DIR/$tdir/f3
2301
2302         cancel_lru_locks osc
2303         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
2304
2305         echo "Inject failure, to simulate the case of missing the MDT-object"
2306         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2307         do_facet mds1 $LCTL set_param fail_loc=0x1616
2308         rm -f $DIR/$tdir/a1/f1
2309
2310         if [ $MDSCOUNT -ge 2 ]; then
2311                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2312                 rm -f $DIR/$tdir/a2/f2
2313         fi
2314
2315         rm -f $DIR/$tdir/f3
2316
2317         sync
2318         sleep 2
2319
2320         do_facet mds1 $LCTL set_param fail_loc=0
2321         if [ $MDSCOUNT -ge 2 ]; then
2322                 do_facet mds2 $LCTL set_param fail_loc=0
2323         fi
2324
2325         cancel_lru_locks mdc
2326         cancel_lru_locks osc
2327
2328         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2329         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2330
2331         for k in $(seq $MDSCOUNT); do
2332                 # The LFSCK status query internal is 30 seconds. For the case
2333                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2334                 # time to guarantee the status sync up.
2335                 wait_update_facet mds${k} "$LCTL get_param -n \
2336                         mdd.$(facet_svc mds${k}).lfsck_layout |
2337                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2338                         error "(2) MDS${k} is not the expected 'completed'"
2339         done
2340
2341         for k in $(seq $OSTCOUNT); do
2342                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2343                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2344                                 awk '/^status/ { print $2 }')
2345                 [ "$cur_status" == "completed" ] ||
2346                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2347         done
2348
2349         if [ $MDSCOUNT -ge 2 ]; then
2350                 expected=4
2351         else
2352                 expected=3
2353         fi
2354
2355         local repaired=$(do_facet mds1 $LCTL get_param -n \
2356                          mdd.$(facet_svc mds1).lfsck_layout |
2357                          awk '/^repaired_orphan/ { print $2 }')
2358         [ $repaired -eq $expected ] ||
2359                 error "(4) Expect $expected fixed on mds1, but got: $repaired"
2360
2361         if [ $MDSCOUNT -ge 2 ]; then
2362                 repaired=$(do_facet mds2 $LCTL get_param -n \
2363                            mdd.$(facet_svc mds2).lfsck_layout |
2364                            awk '/^repaired_orphan/ { print $2 }')
2365                 [ $repaired -eq 0 ] ||
2366                         error "(5) Expect 0 fixed on mds2, but got: $repaired"
2367         fi
2368
2369         ls -ail $MOUNT/.lustre/lost+found/
2370
2371         echo "There should NOT be some stub under .lustre/lost+found/MDT0001/"
2372         if [ -d $MOUNT/.lustre/lost+found/MDT0001 ]; then
2373                 cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-N-*)
2374                 [ -z "$cname" ] ||
2375                         error "(6) .lustre/lost+found/MDT0001/ should be empty"
2376         fi
2377
2378         echo "There should be some stub under .lustre/lost+found/MDT0000/"
2379         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2380                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2381
2382         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-N-*)
2383         [ ! -z "$cname" ] ||
2384                 error "(8) .lustre/lost+found/MDT0000/ should not be empty"
2385 }
2386 run_test 18c "Find out orphan OST-object and repair it (3)"
2387
2388 test_18d() {
2389         echo "#####"
2390         echo "The target MDT-object layout EA is corrupted, but the right"
2391         echo "OST-object is still alive as orphan. The layout LFSCK will"
2392         echo "not create new OST-object to occupy such slot."
2393         echo "#####"
2394
2395         check_mount_and_prep
2396         mkdir $DIR/$tdir/a1
2397         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2398         echo "guard" > $DIR/$tdir/a1/f1
2399         echo "foo" > $DIR/$tdir/a1/f2
2400
2401         echo "guard" > $DIR/$tdir/a1/f3
2402         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2403                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2404         echo "foo" > $DIR/$tdir/a1/f4
2405
2406         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2407         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2408         $LFS path2fid $DIR/$tdir/a1/f1
2409         $LFS getstripe $DIR/$tdir/a1/f1
2410         $LFS path2fid $DIR/$tdir/a1/f2
2411         $LFS getstripe $DIR/$tdir/a1/f2
2412         $LFS path2fid $DIR/$tdir/a1/f3
2413         $LFS getstripe $DIR/$tdir/a1/f3
2414         $LFS path2fid $DIR/$tdir/a1/f4
2415         $LFS getstripe $DIR/$tdir/a1/f4
2416         cancel_lru_locks osc
2417
2418         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2419         echo "to reference the same OST-object (which is f1's OST-obejct)."
2420         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2421         echo "dangling reference case, but f2's old OST-object is there."
2422
2423         echo "The failure also makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2424         echo "to reference the same OST-object (which is f3's OST-obejct)."
2425         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2426         echo "dangling reference case, but f4's old OST-object is there."
2427         echo
2428
2429         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2430         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2431         chown 1.1 $DIR/$tdir/a1/f2
2432         chown 1.1 $DIR/$tdir/a1/f4
2433         rm -f $DIR/$tdir/a1/f1
2434         rm -f $DIR/$tdir/a1/f3
2435         sync
2436         sleep 2
2437         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2438
2439         echo "stopall to cleanup object cache"
2440         stopall > /dev/null
2441         echo "setupall"
2442         setupall > /dev/null
2443
2444         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2445         $START_LAYOUT -r -o -c -d || error "(2) Fail to start LFSCK for layout!"
2446
2447         for k in $(seq $MDSCOUNT); do
2448                 # The LFSCK status query internal is 30 seconds. For the case
2449                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2450                 # time to guarantee the status sync up.
2451                 wait_update_facet mds${k} "$LCTL get_param -n \
2452                         mdd.$(facet_svc mds${k}).lfsck_layout |
2453                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2454                         error "(3) MDS${k} is not the expected 'completed'"
2455         done
2456
2457         for k in $(seq $OSTCOUNT); do
2458                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2459                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2460                                 awk '/^status/ { print $2 }')
2461                 [ "$cur_status" == "completed" ] ||
2462                 error "(4) OST${k} Expect 'completed', but got '$cur_status'"
2463         done
2464
2465         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2466                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2467                          awk '/^repaired_orphan/ { print $2 }')
2468         [ $repaired -eq 2 ] ||
2469                 error "(5) Expect 2 orphans have been fixed, but got: $repaired"
2470
2471         repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2472                    mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2473                    awk '/^repaired_dangling/ { print $2 }')
2474         [ $repaired -eq 0 ] ||
2475                 error "(6) Expect 0 dangling has been fixed, but got: $repaired"
2476
2477         echo "The file size should be correct after layout LFSCK scanning"
2478         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2479         [ "$cur_size" == "$saved_size1" ] ||
2480                 error "(7) Expect file2 size $saved_size1, but got $cur_size"
2481
2482         cur_size=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2483         [ "$cur_size" == "$saved_size2" ] ||
2484                 error "(8) Expect file4 size $saved_size2, but got $cur_size"
2485
2486         echo "The LFSCK should find back the original data."
2487         cat $DIR/$tdir/a1/f2
2488         $LFS path2fid $DIR/$tdir/a1/f2
2489         $LFS getstripe $DIR/$tdir/a1/f2
2490         cat $DIR/$tdir/a1/f4
2491         $LFS path2fid $DIR/$tdir/a1/f4
2492         $LFS getstripe $DIR/$tdir/a1/f4
2493 }
2494 run_test 18d "Find out orphan OST-object and repair it (4)"
2495
2496 test_18e() {
2497         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2498
2499         echo "#####"
2500         echo "The target MDT-object layout EA slot is occpuied by some new"
2501         echo "created OST-object when repair dangling reference case. Such"
2502         echo "conflict OST-object has been modified by others. To keep the"
2503         echo "new data, the LFSCK will create a new file to refernece this"
2504         echo "old orphan OST-object."
2505         echo "#####"
2506
2507         check_mount_and_prep
2508         mkdir $DIR/$tdir/a1
2509         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2510         echo "guard" > $DIR/$tdir/a1/f1
2511         echo "foo" > $DIR/$tdir/a1/f2
2512
2513         echo "guard" > $DIR/$tdir/a1/f3
2514         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2515                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2516         echo "foo" > $DIR/$tdir/a1/f4
2517
2518         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2519         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2520
2521         $LFS path2fid $DIR/$tdir/a1/f1
2522         $LFS getstripe $DIR/$tdir/a1/f1
2523         $LFS path2fid $DIR/$tdir/a1/f2
2524         $LFS getstripe $DIR/$tdir/a1/f2
2525         $LFS path2fid $DIR/$tdir/a1/f3
2526         $LFS getstripe $DIR/$tdir/a1/f3
2527         $LFS path2fid $DIR/$tdir/a1/f4
2528         $LFS getstripe $DIR/$tdir/a1/f4
2529         cancel_lru_locks osc
2530
2531         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2532         echo "to reference the same OST-object (which is f1's OST-obejct)."
2533         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2534         echo "dangling reference case, but f2's old OST-object is there."
2535
2536         echo "Also the failure makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2537         echo "to reference the same OST-object (which is f3's OST-obejct)."
2538         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2539         echo "dangling reference case, but f4's old OST-object is there."
2540         echo
2541
2542         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2543         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2544         chown 1.1 $DIR/$tdir/a1/f2
2545         chown 1.1 $DIR/$tdir/a1/f4
2546         rm -f $DIR/$tdir/a1/f1
2547         rm -f $DIR/$tdir/a1/f3
2548         sync
2549         sleep 2
2550         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2551
2552         echo "stopall to cleanup object cache"
2553         stopall > /dev/null
2554         echo "setupall"
2555         setupall > /dev/null
2556
2557         #define OBD_FAIL_LFSCK_DELAY3           0x1602
2558         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
2559
2560         start_full_debug_logging
2561
2562         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2563         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
2564
2565         wait_update_facet mds1 "$LCTL get_param -n \
2566                 mdd.$(facet_svc mds1).lfsck_layout |
2567                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" $LTIME ||
2568                 error "(3) MDS1 is not the expected 'scanning-phase2'"
2569
2570         # to guarantee all updates are synced.
2571         sync
2572         sleep 2
2573
2574         echo "Write new data to f2/f4 to modify the new created OST-object."
2575         echo "dummy" >> $DIR/$tdir/a1/f2 || error "write a1/f2 failed"
2576         echo "dummy" >> $DIR/$tdir/a1/f4 || error "write a1/f4 failed"
2577
2578         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2579
2580         for k in $(seq $MDSCOUNT); do
2581                 # The LFSCK status query internal is 30 seconds. For the case
2582                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2583                 # time to guarantee the status sync up.
2584                 wait_update_facet mds${k} "$LCTL get_param -n \
2585                         mdd.$(facet_svc mds${k}).lfsck_layout |
2586                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2587                         error "(4) MDS${k} is not the expected 'completed'"
2588         done
2589
2590         for k in $(seq $OSTCOUNT); do
2591                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2592                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2593                                 awk '/^status/ { print $2 }')
2594                 [ "$cur_status" == "completed" ] ||
2595                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2596         done
2597
2598         stop_full_debug_logging
2599
2600         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2601                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2602                          awk '/^repaired_orphan/ { print $2 }')
2603         [ $repaired -eq 2 ] ||
2604                 error "(6) Expect 2 orphans have been fixed, but got: $repaired"
2605
2606         echo "There should be stub file under .lustre/lost+found/MDT0000/"
2607         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2608                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2609
2610         local count=$(ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-* | wc -l)
2611         if [ $count -ne 2 ]; then
2612                 ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-*
2613                 error "(8) Expect 2 stubs under lost+found, but got $count"
2614         fi
2615
2616         echo "The stub file should keep the original f2 or f4 data"
2617         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | head -n 1)
2618         local cur_size=$(ls -il $cname | awk '{ print $6 }')
2619         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2620                 error "(9) Got unexpected $cur_size"
2621
2622         cat $cname
2623         $LFS path2fid $cname
2624         $LFS getstripe $cname
2625
2626         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | tail -n 1)
2627         cur_size=$(ls -il $cname | awk '{ print $6 }')
2628         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2629                 error "(10) Got unexpected $cur_size"
2630
2631         cat $cname
2632         $LFS path2fid $cname
2633         $LFS getstripe $cname
2634
2635         echo "The f2/f4 should contains new data."
2636         cat $DIR/$tdir/a1/f2
2637         $LFS path2fid $DIR/$tdir/a1/f2
2638         $LFS getstripe $DIR/$tdir/a1/f2
2639         cat $DIR/$tdir/a1/f4
2640         $LFS path2fid $DIR/$tdir/a1/f4
2641         $LFS getstripe $DIR/$tdir/a1/f4
2642 }
2643 run_test 18e "Find out orphan OST-object and repair it (5)"
2644
2645 test_18f() {
2646         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2647
2648         echo "#####"
2649         echo "The target MDT-object is lost. The LFSCK should re-create the"
2650         echo "MDT-object under .lustre/lost+found/MDTxxxx. If some OST fail"
2651         echo "to verify some OST-object(s) during the first stage-scanning,"
2652         echo "the LFSCK should skip orphan OST-objects for such OST. Others"
2653         echo "should not be affected."
2654         echo "#####"
2655
2656         check_mount_and_prep
2657         $LFS mkdir -i 0 $DIR/$tdir/a1
2658         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2659         dd if=/dev/zero of=$DIR/$tdir/a1/guard bs=1M count=2
2660         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2661         $LFS mkdir -i 0 $DIR/$tdir/a2
2662         $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a2
2663         dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2664         $LFS getstripe $DIR/$tdir/a1/f1
2665         $LFS getstripe $DIR/$tdir/a2/f2
2666
2667         if [ $MDSCOUNT -ge 2 ]; then
2668                 $LFS mkdir -i 1 $DIR/$tdir/a3
2669                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a3
2670                 dd if=/dev/zero of=$DIR/$tdir/a3/guard bs=1M count=2
2671                 dd if=/dev/zero of=$DIR/$tdir/a3/f3 bs=1M count=2
2672                 $LFS mkdir -i 1 $DIR/$tdir/a4
2673                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a4
2674                 dd if=/dev/zero of=$DIR/$tdir/a4/f4 bs=1M count=2
2675                 $LFS getstripe $DIR/$tdir/a3/f3
2676                 $LFS getstripe $DIR/$tdir/a4/f4
2677         fi
2678
2679         cancel_lru_locks osc
2680
2681         echo "Inject failure, to simulate the case of missing the MDT-object"
2682         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2683         do_facet mds1 $LCTL set_param fail_loc=0x1616
2684         rm -f $DIR/$tdir/a1/f1
2685         rm -f $DIR/$tdir/a2/f2
2686
2687         if [ $MDSCOUNT -ge 2 ]; then
2688                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2689                 rm -f $DIR/$tdir/a3/f3
2690                 rm -f $DIR/$tdir/a4/f4
2691         fi
2692
2693         sync
2694         sleep 2
2695
2696         do_facet mds1 $LCTL set_param fail_loc=0
2697         if [ $MDSCOUNT -ge 2 ]; then
2698                 do_facet mds2 $LCTL set_param fail_loc=0
2699         fi
2700
2701         cancel_lru_locks mdc
2702         cancel_lru_locks osc
2703
2704         echo "Inject failure, to simulate the OST0 fail to handle"
2705         echo "MDT0 LFSCK request during the first-stage scanning."
2706         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
2707         do_facet mds1 $LCTL set_param fail_loc=0x161c fail_val=0
2708
2709         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2710         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2711
2712         for k in $(seq $MDSCOUNT); do
2713                 # The LFSCK status query internal is 30 seconds. For the case
2714                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2715                 # time to guarantee the status sync up.
2716                 wait_update_facet mds${k} "$LCTL get_param -n \
2717                         mdd.$(facet_svc mds${k}).lfsck_layout |
2718                         awk '/^status/ { print \\\$2 }'" "partial" $LTIME ||
2719                         error "(2) MDS${k} is not the expected 'partial'"
2720         done
2721
2722         wait_update_facet ost1 "$LCTL get_param -n \
2723                 obdfilter.$(facet_svc ost1).lfsck_layout |
2724                 awk '/^status/ { print \\\$2 }'" "partial" $LTIME || {
2725                 error "(3) OST1 is not the expected 'partial'"
2726         }
2727
2728         wait_update_facet ost2 "$LCTL get_param -n \
2729                 obdfilter.$(facet_svc ost2).lfsck_layout |
2730                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME || {
2731                 error "(4) OST2 is not the expected 'completed'"
2732         }
2733
2734         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2735
2736         local repaired=$(do_facet mds1 $LCTL get_param -n \
2737                          mdd.$(facet_svc mds1).lfsck_layout |
2738                          awk '/^repaired_orphan/ { print $2 }')
2739         [ $repaired -eq 1 ] ||
2740                 error "(5) Expect 1 fixed on mds{1}, but got: $repaired"
2741
2742         if [ $MDSCOUNT -ge 2 ]; then
2743                 repaired=$(do_facet mds2 $LCTL get_param -n \
2744                          mdd.$(facet_svc mds2).lfsck_layout |
2745                          awk '/^repaired_orphan/ { print $2 }')
2746                 [ $repaired -eq 1 ] ||
2747                 error "(6) Expect 1 fixed on mds{2}, but got: $repaired"
2748         fi
2749
2750         echo "Trigger layout LFSCK on all devices again to cleanup"
2751         $START_LAYOUT -r -o || error "(7) Fail to start LFSCK for layout!"
2752
2753         for k in $(seq $MDSCOUNT); do
2754                 # The LFSCK status query internal is 30 seconds. For the case
2755                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2756                 # time to guarantee the status sync up.
2757                 wait_update_facet mds${k} "$LCTL get_param -n \
2758                         mdd.$(facet_svc mds${k}).lfsck_layout |
2759                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2760                         error "(8) MDS${k} is not the expected 'completed'"
2761         done
2762
2763         for k in $(seq $OSTCOUNT); do
2764                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2765                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2766                              awk '/^status/ { print $2 }')
2767                 [ "$cur_status" == "completed" ] ||
2768                 error "(9) OST${k} Expect 'completed', but got '$cur_status'"
2769
2770         done
2771
2772         local repaired=$(do_facet mds1 $LCTL get_param -n \
2773                          mdd.$(facet_svc mds1).lfsck_layout |
2774                          awk '/^repaired_orphan/ { print $2 }')
2775         [ $repaired -eq 2 ] ||
2776                 error "(10) Expect 2 fixed on mds{1}, but got: $repaired"
2777
2778         if [ $MDSCOUNT -ge 2 ]; then
2779                 repaired=$(do_facet mds2 $LCTL get_param -n \
2780                          mdd.$(facet_svc mds2).lfsck_layout |
2781                          awk '/^repaired_orphan/ { print $2 }')
2782                 [ $repaired -eq 2 ] ||
2783                 error "(11) Expect 2 fixed on mds{2}, but got: $repaired"
2784         fi
2785 }
2786 run_test 18f "Skip the failed OST(s) when handle orphan OST-objects"
2787
2788 test_18g() {
2789         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2790
2791         echo "#####"
2792         echo "The target MDT-object is lost, but related OI mapping is there"
2793         echo "The LFSCK should recreate the lost MDT-object without affected"
2794         echo "by the stale OI mapping."
2795         echo "#####"
2796
2797         check_mount_and_prep
2798         $LFS mkdir -i 0 $DIR/$tdir/a1
2799         $LFS setstripe -c -1 -i 0 -S 1M $DIR/$tdir/a1
2800         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=$OSTCOUNT
2801         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2802         echo ${fid1}
2803         $LFS getstripe $DIR/$tdir/a1/f1
2804         cancel_lru_locks osc
2805
2806         echo "Inject failure to simulate lost MDT-object but keep OI mapping"
2807         #define OBD_FAIL_LFSCK_LOST_MDTOBJ2     0x162e
2808         do_facet mds1 $LCTL set_param fail_loc=0x162e
2809         rm -f $DIR/$tdir/a1/f1
2810
2811         do_facet mds1 $LCTL set_param fail_loc=0
2812         cancel_lru_locks mdc
2813         cancel_lru_locks osc
2814
2815         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2816         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2817
2818         for k in $(seq $MDSCOUNT); do
2819                 # The LFSCK status query internal is 30 seconds. For the case
2820                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2821                 # time to guarantee the status sync up.
2822                 wait_update_facet mds${k} "$LCTL get_param -n \
2823                         mdd.$(facet_svc mds${k}).lfsck_layout |
2824                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2825                         error "(2) MDS${k} is not the expected 'completed'"
2826         done
2827
2828         for k in $(seq $OSTCOUNT); do
2829                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2830                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2831                                 awk '/^status/ { print $2 }')
2832                 [ "$cur_status" == "completed" ] ||
2833                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2834         done
2835
2836         local repaired=$(do_facet mds1 $LCTL get_param -n \
2837                          mdd.$(facet_svc mds1).lfsck_layout |
2838                          awk '/^repaired_orphan/ { print $2 }')
2839         [ $repaired -eq $OSTCOUNT ] ||
2840                 error "(4) Expect $OSTCOUNT fixed, but got: $repaired"
2841
2842         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2843         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2844         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2845
2846         $LFS path2fid $DIR/$tdir/a1/f1
2847         $LFS getstripe $DIR/$tdir/a1/f1
2848 }
2849 run_test 18g "Find out orphan OST-object and repair it (7)"
2850
2851 test_18h() {
2852         echo "#####"
2853         echo "The PFL extent crashed. During the first cycle LFSCK scanning,"
2854         echo "the layout LFSCK will keep the bad PFL file(s) there without"
2855         echo "scanning its OST-object(s). Then in the second stage scanning,"
2856         echo "the OST will return related OST-object(s) to the MDT as orphan."
2857         echo "And then the LFSCK on the MDT can rebuild the PFL extent with"
2858         echo "the 'orphan(s)' stripe information."
2859         echo "#####"
2860
2861         check_mount_and_prep
2862
2863         $LFS setstripe -E 2M -S 1M -c 1 -E -1 $DIR/$tdir/f0 ||
2864                 error "(0) Fail to create PFL $DIR/$tdir/f0"
2865
2866         cat $LUSTRE/tests/test-framework.sh > $DIR/$tdir/f0 ||
2867                 error "(1.1) Fail to write $DIR/$tdir/f0"
2868
2869         dd if=$LUSTRE/tests/test-framework.sh of=$DIR/$tdir/f0 bs=1M seek=2 ||
2870                 error "(1.2) Fail to write $DIR/$tdir/f0"
2871
2872         cp $DIR/$tdir/f0 $DIR/$tdir/guard
2873
2874         echo "Inject failure stub to simulate bad PFL extent range"
2875         #define OBD_FAIL_LFSCK_BAD_PFL_RANGE    0x162f
2876         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162f
2877
2878         chown 1.1 $DIR/$tdir/f0
2879
2880         cancel_lru_locks mdc
2881         cancel_lru_locks osc
2882         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2883
2884         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 &&
2885                 error "(2) Write to bad PFL file should fail"
2886
2887         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
2888         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
2889
2890         for k in $(seq $MDSCOUNT); do
2891                 # The LFSCK status query internal is 30 seconds. For the case
2892                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2893                 # time to guarantee the status sync up.
2894                 wait_update_facet mds${k} "$LCTL get_param -n \
2895                         mdd.$(facet_svc mds${k}).lfsck_layout |
2896                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2897                         error "(4.1) MDS${k} is not the expected 'completed'"
2898         done
2899
2900         for k in $(seq $OSTCOUNT); do
2901                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2902                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2903                              awk '/^status/ { print $2 }')
2904                 [ "$cur_status" == "completed" ] ||
2905                 error "(4.2) OST${k} Expect 'completed', but got '$cur_status'"
2906
2907         done
2908
2909         local repaired=$($SHOW_LAYOUT |
2910                          awk '/^repaired_orphan/ { print $2 }')
2911         [ $repaired -eq 2 ] ||
2912                 error "(5) Fail to repair crashed PFL range: $repaired"
2913
2914         echo "Data in $DIR/$tdir/f0 should not be broken"
2915         diff $DIR/$tdir/f0 $DIR/$tdir/guard ||
2916                 error "(6) Data in $DIR/$tdir/f0 is broken"
2917
2918         echo "Write should succeed after LFSCK repairing the bad PFL range"
2919         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 ||
2920                 error "(7) Write should succeed after LFSCK"
2921 }
2922 run_test 18h "LFSCK can repair crashed PFL extent range"
2923
2924 $LCTL set_param debug=-cache > /dev/null
2925
2926 test_19a() {
2927         check_mount_and_prep
2928         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2929
2930         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2931                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
2932
2933         echo "foo1" > $DIR/$tdir/a0
2934         $LFS setstripe -E 512K -S 512K -o 0 -E -1 -S 1M $DIR/$tdir/a1 ||
2935                 error "(0) Fail to create PFL $DIR/$tdir/a1"
2936         echo "foo2" > $DIR/$tdir/a1
2937         echo "guard" > $DIR/$tdir/a2
2938         cancel_lru_locks osc
2939
2940         echo "Inject failure, then client will offer wrong parent FID when read"
2941         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2942                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2943
2944         #define OBD_FAIL_LFSCK_INVALID_PFID     0x1619
2945         $LCTL set_param fail_loc=0x1619
2946
2947         echo "Read RPC with wrong parent FID should be denied"
2948         cat $DIR/$tdir/a0 && error "(3.1) Read a0 should be denied!"
2949         cat $DIR/$tdir/a1 && error "(3.2) Read a1 should be denied!"
2950         $LCTL set_param fail_loc=0
2951 }
2952 run_test 19a "OST-object inconsistency self detect"
2953
2954 test_19b() {
2955         check_mount_and_prep
2956         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2957
2958         echo "Inject failure stub to make the OST-object to back point to"
2959         echo "non-exist MDT-object"
2960
2961         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2962                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
2963
2964         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
2965         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
2966         echo "foo1" > $DIR/$tdir/f0
2967         $LFS setstripe -E 1M -S 1M -o 0 -E 4M -S 256K $DIR/$tdir/f1 ||
2968                 error "(0) Fail to create PFL $DIR/$tdir/f1"
2969         echo "foo2" > $DIR/$tdir/f1
2970         cancel_lru_locks osc
2971         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
2972
2973         do_facet ost1 $LCTL set_param -n \
2974                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
2975         echo "Nothing should be fixed since self detect and repair is disabled"
2976         local repaired=$(do_facet ost1 $LCTL get_param -n \
2977                         obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2978                         awk '/^repaired/ { print $2 }')
2979         [ $repaired -eq 0 ] ||
2980                 error "(1) Expected 0 repaired, but got $repaired"
2981
2982         echo "Read RPC with right parent FID should be accepted,"
2983         echo "and cause parent FID on OST to be fixed"
2984
2985         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2986                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2987
2988         cat $DIR/$tdir/f0 || error "(2.1) Read f0 should not be denied!"
2989         cat $DIR/$tdir/f1 || error "(2.2) Read f1 should not be denied!"
2990
2991         repaired=$(do_facet ost1 $LCTL get_param -n \
2992                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2993                 awk '/^repaired/ { print $2 }')
2994         [ $repaired -eq 2 ] ||
2995                 error "(3) Expected 1 repaired, but got $repaired"
2996 }
2997 run_test 19b "OST-object inconsistency self repair"
2998
2999 PATTERN_WITH_HOLE="40000001"
3000 PATTERN_WITHOUT_HOLE="raid0"
3001
3002 test_20a() {
3003         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
3004         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
3005
3006         echo "#####"
3007         echo "The target MDT-object and some of its OST-object are lost."
3008         echo "The LFSCK should find out the left OST-objects and re-create"
3009         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
3010         echo "with the partial OST-objects (LOV EA hole)."
3011
3012         echo "New client can access the file with LOV EA hole via normal"
3013         echo "system tools or commands without crash the system."
3014
3015         echo "For old client, even though it cannot access the file with"
3016         echo "LOV EA hole, it should not cause the system crash."
3017         echo "#####"
3018
3019         check_mount_and_prep
3020         $LFS mkdir -i 0 $DIR/$tdir/a1
3021         if [ $OSTCOUNT -gt 2 ]; then
3022                 $LFS setstripe -c 3 -i 0 -S 1M $DIR/$tdir/a1
3023                 bcount=513
3024         else
3025                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a1
3026                 bcount=257
3027         fi
3028
3029         # 256 blocks on the stripe0.
3030         # 1 block on the stripe1 for 2 OSTs case.
3031         # 256 blocks on the stripe1 for other cases.
3032         # 1 block on the stripe2 if OSTs > 2
3033         dd if=/dev/zero of=$DIR/$tdir/a1/f0 bs=4096 count=$bcount
3034         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=4096 count=$bcount
3035         dd if=/dev/zero of=$DIR/$tdir/a1/f2 bs=4096 count=$bcount
3036
3037         local fid0=$($LFS path2fid $DIR/$tdir/a1/f0)
3038         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
3039         local fid2=$($LFS path2fid $DIR/$tdir/a1/f2)
3040
3041         echo ${fid0}
3042         $LFS getstripe $DIR/$tdir/a1/f0
3043         echo ${fid1}
3044         $LFS getstripe $DIR/$tdir/a1/f1
3045         echo ${fid2}
3046         $LFS getstripe $DIR/$tdir/a1/f2
3047
3048         if [ $OSTCOUNT -gt 2 ]; then
3049                 dd if=/dev/zero of=$DIR/$tdir/a1/f3 bs=4096 count=$bcount
3050                 fid3=$($LFS path2fid $DIR/$tdir/a1/f3)
3051                 echo ${fid3}
3052                 $LFS getstripe $DIR/$tdir/a1/f3
3053         fi
3054
3055         cancel_lru_locks osc
3056
3057         echo "Inject failure..."
3058         echo "To simulate f0 lost MDT-object"
3059         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
3060         do_facet mds1 $LCTL set_param fail_loc=0x1616
3061         rm -f $DIR/$tdir/a1/f0
3062
3063         echo "To simulate f1 lost MDT-object and OST-object0"
3064         #define OBD_FAIL_LFSCK_LOST_SPEOBJ      0x161a
3065         do_facet mds1 $LCTL set_param fail_loc=0x161a
3066         rm -f $DIR/$tdir/a1/f1
3067
3068         echo "To simulate f2 lost MDT-object and OST-object1"
3069         do_facet mds1 $LCTL set_param fail_val=1
3070         rm -f $DIR/$tdir/a1/f2
3071
3072         if [ $OSTCOUNT -gt 2 ]; then
3073                 echo "To simulate f3 lost MDT-object and OST-object2"
3074                 do_facet mds1 $LCTL set_param fail_val=2
3075                 rm -f $DIR/$tdir/a1/f3
3076         fi
3077
3078         umount_client $MOUNT
3079         sync
3080         sleep 2
3081         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
3082
3083         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
3084         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
3085
3086         for k in $(seq $MDSCOUNT); do
3087                 # The LFSCK status query internal is 30 seconds. For the case
3088                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3089                 # time to guarantee the status sync up.
3090                 wait_update_facet mds${k} "$LCTL get_param -n \
3091                         mdd.$(facet_svc mds${k}).lfsck_layout |
3092                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
3093                         error "(2) MDS${k} is not the expected 'completed'"
3094         done
3095
3096         for k in $(seq $OSTCOUNT); do
3097                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
3098                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
3099                                 awk '/^status/ { print $2 }')
3100                 [ "$cur_status" == "completed" ] ||
3101                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
3102         done
3103
3104         local repaired=$(do_facet mds1 $LCTL get_param -n \
3105                          mdd.$(facet_svc mds1).lfsck_layout |
3106                          awk '/^repaired_orphan/ { print $2 }')
3107         if [ $OSTCOUNT -gt 2 ]; then
3108                 [ $repaired -eq 9 ] ||
3109                         error "(4.1) Expect 9 fixed on mds1, but got: $repaired"
3110         else
3111                 [ $repaired -eq 4 ] ||
3112                         error "(4.2) Expect 4 fixed on mds1, but got: $repaired"
3113         fi
3114
3115         mount_client $MOUNT || error "(5.0) Fail to start client!"
3116
3117         LOV_PATTERN_F_HOLE=0x40000000
3118
3119         #
3120         # ${fid0}-R-0 is the old f0
3121         #
3122         local name="$MOUNT/.lustre/lost+found/MDT0000/${fid0}-R-0"
3123         echo "Check $name, which is the old f0"
3124
3125         $LFS getstripe -v $name || error "(5.1) cannot getstripe on $name"
3126
3127         local pattern=$($LFS getstripe -L $name)
3128         [[ "$pattern" = "$PATTERN_WITHOUT_HOLE" ]] ||
3129                 error "(5.2) NOT expect pattern flag hole, but got $pattern"
3130
3131         local stripes=$($LFS getstripe -c $name)
3132         if [ $OSTCOUNT -gt 2 ]; then
3133                 [ $stripes -eq 3 ] ||
3134                 error "(5.3.1) expect the stripe count is 3, but got $stripes"
3135         else
3136                 [ $stripes -eq 2 ] ||
3137                 error "(5.3.2) expect the stripe count is 2, but got $stripes"
3138         fi
3139
3140         local size=$(stat $name | awk '/Size:/ { print $2 }')
3141         [ $size -eq $((4096 * $bcount)) ] ||
3142                 error "(5.4) expect the size $((4096 * $bcount)), but got $size"
3143
3144         cat $name > /dev/null || error "(5.5) cannot read $name"
3145
3146         echo "dummy" >> $name || error "(5.6) cannot write $name"
3147
3148         chown $RUNAS_ID:$RUNAS_GID $name || error "(5.7) cannot chown on $name"
3149
3150         touch $name || error "(5.8) cannot touch $name"
3151
3152         rm -f $name || error "(5.9) cannot unlink $name"
3153
3154         #
3155         # ${fid1}-R-0 contains the old f1's stripe1 (and stripe2 if OSTs > 2)
3156         #
3157         name="$MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
3158         if [ $OSTCOUNT -gt 2 ]; then
3159                 echo "Check $name, it contains the old f1's stripe1 and stripe2"
3160         else
3161                 echo "Check $name, it contains the old f1's stripe1"
3162         fi
3163
3164         $LFS getstripe -v $name || error "(6.1) cannot getstripe on $name"
3165
3166         pattern=$($LFS getstripe -L $name)
3167         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3168                 error "(6.2) expect pattern flag hole, but got $pattern"
3169
3170         stripes=$($LFS getstripe -c $name)
3171         if [ $OSTCOUNT -gt 2 ]; then
3172                 [ $stripes -eq 3 ] ||
3173                 error "(6.3.1) expect the stripe count is 3, but got $stripes"
3174         else
3175                 [ $stripes -eq 2 ] ||
3176                 error "(6.3.2) expect the stripe count is 2, but got $stripes"
3177         fi
3178
3179         size=$(stat $name | awk '/Size:/ { print $2 }')
3180         [ $size -eq $((4096 * $bcount)) ] ||
3181                 error "(6.4) expect the size $((4096 * $bcount)), but got $size"
3182
3183         cat $name > /dev/null && error "(6.5) normal read $name should fail"
3184
3185         local failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3186                          bs=4096 2>&1 | grep "Input/output error" | wc -l)
3187
3188         # stripe0 is dummy
3189         [ $failures -eq 256 ] ||
3190                 error "(6.6) expect 256 IO failures, but get $failures"
3191
3192         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3193         [ $size -eq $((4096 * $bcount)) ] ||
3194                 error "(6.7) expect the size $((4096 * $bcount)), but got $size"
3195
3196         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 &&
3197                 error "(6.8) write to the LOV EA hole should fail"
3198
3199         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 seek=300 ||
3200                 error "(6.9) write to normal stripe should NOT fail"
3201
3202         echo "foo" >> $name && error "(6.10) append write $name should fail"
3203
3204         chown $RUNAS_ID:$RUNAS_GID $name || error "(6.11) cannot chown on $name"
3205
3206         touch $name || error "(6.12) cannot touch $name"
3207
3208         rm -f $name || error "(6.13) cannot unlink $name"
3209
3210         #
3211         # ${fid2}-R-0 it contains the old f2's stripe0 (and stripe2 if OSTs > 2)
3212         #
3213         name="$MOUNT/.lustre/lost+found/MDT0000/${fid2}-R-0"
3214         if [ $OSTCOUNT -gt 2 ]; then
3215                 echo "Check $name, it contains the old f2's stripe0 and stripe2"
3216         else
3217                 echo "Check $name, it contains the old f2's stripe0"
3218         fi
3219
3220         $LFS getstripe -v $name || error "(7.1) cannot getstripe on $name"
3221
3222         pattern=$($LFS getstripe -L $name)
3223         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3224                 error "(7.2) expect pattern flag hole, but got $pattern"
3225
3226         stripes=$($LFS getstripe -c $name)
3227         size=$(stat $name | awk '/Size:/ { print $2 }')
3228         if [ $OSTCOUNT -gt 2 ]; then
3229                 [ $stripes -eq 3 ] ||
3230                 error "(7.3.1) expect the stripe count is 3, but got $stripes"
3231
3232                 [ $size -eq $((4096 * $bcount)) ] ||
3233                 error "(7.4.1) expect size $((4096 * $bcount)), but got $size"
3234
3235                 cat $name > /dev/null &&
3236                         error "(7.5.1) normal read $name should fail"
3237
3238                 failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3239                            bs=4096 2>&1 | grep "Input/output error" | wc -l)
3240                 # stripe1 is dummy
3241                 [ $failures -eq 256 ] ||
3242                         error "(7.6) expect 256 IO failures, but get $failures"
3243
3244                 size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3245                 [ $size -eq $((4096 * $bcount)) ] ||
3246                 error "(7.7) expect the size $((4096 * $bcount)), but got $size"
3247
3248                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
3249                 seek=300 && error "(7.8.0) write to the LOV EA hole should fail"
3250
3251                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 ||
3252                 error "(7.8.1) write to normal stripe should NOT fail"
3253
3254                 echo "foo" >> $name &&
3255                         error "(7.8.3) append write $name should fail"
3256
3257                 chown $RUNAS_ID:$RUNAS_GID $name ||
3258                         error "(7.9.1) cannot chown on $name"
3259
3260                 touch $name || error "(7.10.1) cannot touch $name"
3261         else
3262                 [ $stripes -eq 2 ] ||
3263                 error "(7.3.2) expect the stripe count is 2, but got $stripes"
3264
3265                 # stripe1 is dummy
3266                 [ $size -eq $((4096 * (256 + 0))) ] ||
3267                 error "(7.4.2) expect the size $((4096 * 256)), but got $size"
3268
3269                 cat $name > /dev/null &&
3270                         error "(7.5.2) normal read $name should fail"
3271
3272                 failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3273                            bs=4096 2>&1 | grep "Input/output error" | wc -l)
3274                 [ $failures -eq 256 ] ||
3275                 error "(7.6.2) expect 256 IO failures, but get $failures"
3276
3277                 bcount=$((256 * 2))
3278                 size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3279                 [ $size -eq $((4096 * $bcount)) ] ||
3280                 error "(7.7.2) expect the size $((4096 * $bcount)), got $size"
3281
3282                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
3283                 seek=256 && error "(7.8.2) write to the LOV EA hole should fail"
3284
3285                 chown $RUNAS_ID:$RUNAS_GID $name ||
3286                         error "(7.9.2) cannot chown on $name"
3287
3288                 touch $name || error "(7.10.2) cannot touch $name"
3289         fi
3290
3291         rm -f $name || error "(7.11) cannot unlink $name"
3292
3293         [ $OSTCOUNT -le 2 ] && return
3294
3295         #
3296         # ${fid3}-R-0 should contains the old f3's stripe0 and stripe1
3297         #
3298         name="$MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
3299         echo "Check $name, which contains the old f3's stripe0 and stripe1"
3300
3301         $LFS getstripe -v $name || error "(8.1) cannot getstripe on $name"
3302
3303         pattern=$($LFS getstripe -L $name)
3304         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3305                 error "(8.2) expect pattern flag hole, but got $pattern"
3306
3307         stripes=$($LFS getstripe -c $name)
3308         [ $stripes -eq 3 ] ||
3309                 error "(8.3) expect the stripe count is 3, but got $stripes"
3310
3311         size=$(stat $name | awk '/Size:/ { print $2 }')
3312         # stripe2 is lost
3313         [ $size -eq $((4096 * (256 + 256 + 0))) ] ||
3314                 error "(8.4) expect the size $((4096 * 512)), but got $size"
3315
3316         cat $name > /dev/null &&
3317                 error "(8.5) normal read $name should fail"
3318
3319         failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3320                    bs=4096 2>&1 | grep "Input/output error" | wc -l)
3321         # stripe2 is dummy
3322         [ $failures -eq 256 ] ||
3323                 error "(8.6) expect 256 IO failures, but get $failures"
3324
3325         bcount=$((256 * 3))
3326         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3327         [ $size -eq $((4096 * $bcount)) ] ||
3328                 error "(8.7) expect the size $((4096 * $bcount)), but got $size"
3329
3330         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
3331                 seek=512 && error "(8.8) write to the LOV EA hole should fail"
3332
3333         chown $RUNAS_ID:$RUNAS_GID $name ||
3334                 error "(8.9) cannot chown on $name"
3335
3336         touch $name || error "(8.10) cannot touch $name"
3337
3338         rm -f $name || error "(8.11) cannot unlink $name"
3339 }
3340 run_test 20a "Handle the orphan with dummy LOV EA slot properly"
3341
3342 test_20b() {
3343         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
3344         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
3345
3346         echo "#####"
3347         echo "The target MDT-object and some of its OST-object are lost."
3348         echo "The LFSCK should find out the left OST-objects and re-create"
3349         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
3350         echo "with the partial OST-objects (LOV EA hole)."
3351
3352         echo "New client can access the file with LOV EA hole via normal"
3353         echo "system tools or commands without crash the system - PFL case."
3354         echo "#####"
3355
3356         check_mount_and_prep
3357
3358         $LFS setstripe -E 2M -S 1M -c 2 -E -1 -S 1M -c 2 $DIR/$tdir/f0 ||
3359                 error "(0) Fail to create PFL file $DIR/$tdir/f0"
3360         $LFS setstripe -E 2M -S 1M -c 2 -E -1 -S 1M -c 2 $DIR/$tdir/f1 ||
3361                 error "(1) Fail to create PFL file $DIR/$tdir/f1"
3362         $LFS setstripe -E 2M -S 1M -c 2 -E -1 -S 1M -c 2 $DIR/$tdir/f2 ||
3363                 error "(2) Fail to create PFL file $DIR/$tdir/f2"
3364
3365         local bcount=$((256 * 3 + 1))
3366
3367         dd if=/dev/zero of=$DIR/$tdir/f0 bs=4096 count=$bcount
3368         dd if=/dev/zero of=$DIR/$tdir/f1 bs=4096 count=$bcount
3369         dd if=/dev/zero of=$DIR/$tdir/f2 bs=4096 count=$bcount
3370
3371         local fid0=$($LFS path2fid $DIR/$tdir/f0)
3372         local fid1=$($LFS path2fid $DIR/$tdir/f1)
3373         local fid2=$($LFS path2fid $DIR/$tdir/f2)
3374
3375         echo ${fid0}
3376         $LFS getstripe $DIR/$tdir/f0
3377         echo ${fid1}
3378         $LFS getstripe $DIR/$tdir/f1
3379         echo ${fid2}
3380         $LFS getstripe $DIR/$tdir/f2
3381
3382         cancel_lru_locks mdc
3383         cancel_lru_locks osc
3384
3385         echo "Inject failure..."
3386         echo "To simulate f0 lost MDT-object"
3387         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
3388         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1616
3389         rm -f $DIR/$tdir/f0
3390
3391         echo "To simulate the case of f1 lost MDT-object and "
3392         echo "the first OST-object in each PFL component"
3393         #define OBD_FAIL_LFSCK_LOST_SPEOBJ      0x161a
3394         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161a
3395         rm -f $DIR/$tdir/f1
3396
3397         echo "To simulate the case of f2 lost MDT-object and "
3398         echo "the second OST-object in each PFL component"
3399         do_facet $SINGLEMDS $LCTL set_param fail_val=1
3400         rm -f $DIR/$tdir/f2
3401
3402         sync
3403         sleep 2
3404         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
3405
3406         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
3407         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
3408
3409         for k in $(seq $MDSCOUNT); do
3410                 # The LFSCK status query internal is 30 seconds. For the case
3411                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3412                 # time to guarantee the status sync up.
3413                 wait_update_facet mds${k} "$LCTL get_param -n \
3414                         mdd.$(facet_svc mds${k}).lfsck_layout |
3415                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
3416                         error "(4) MDS${k} is not the expected 'completed'"
3417         done
3418
3419         for k in $(seq $OSTCOUNT); do
3420                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
3421                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
3422                                 awk '/^status/ { print $2 }')
3423                 [ "$cur_status" == "completed" ] ||
3424                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
3425         done
3426
3427         local repaired=$(do_facet mds1 $LCTL get_param -n \
3428                          mdd.$(facet_svc mds1).lfsck_layout |
3429                          awk '/^repaired_orphan/ { print $2 }')
3430         [ $repaired -eq 8 ] ||
3431                 error "(6) Expect 8 fixed on mds1, but got: $repaired"
3432
3433         #
3434         # ${fid0}-R-0 is the old f0
3435         #
3436         local name="$MOUNT/.lustre/lost+found/MDT0000/${fid0}-R-0"
3437         echo "Check $name, which is the old f0"
3438
3439         $LFS getstripe -v $name || error "(7.1) cannot getstripe on $name"
3440
3441         local pattern=$($LFS getstripe -L -I1 $name)
3442         [[ "$pattern" = "$PATTERN_WITHOUT_HOLE" ]] ||
3443                 error "(7.2.1) NOT expect pattern flag hole, but got $pattern"
3444
3445         pattern=$($LFS getstripe -L -I2 $name)
3446         [[ "$pattern" = "$PATTERN_WITHOUT_HOLE" ]] ||
3447                 error "(7.2.2) NOT expect pattern flag hole, but got $pattern"
3448
3449         local stripes=$($LFS getstripe -c -I1 $name)
3450         [ $stripes -eq 2 ] ||
3451                 error "(7.3.1) expect 2 stripes, but got $stripes"
3452
3453         stripes=$($LFS getstripe -c -I2 $name)
3454         [ $stripes -eq 2 ] ||
3455                 error "(7.3.2) expect 2 stripes, but got $stripes"
3456
3457         local e_start=$($LFS getstripe -I1 $name |
3458                         awk '/lcme_extent.e_start:/ { print $2 }')
3459         [ $e_start -eq 0 ] ||
3460                 error "(7.4.1) expect the COMP1 start at 0, got $e_start"
3461
3462         local e_end=$($LFS getstripe -I1 $name |
3463                       awk '/lcme_extent.e_end:/ { print $2 }')
3464         [ $e_end -eq 2097152 ] ||
3465                 error "(7.4.2) expect the COMP1 end at 2097152, got $e_end"
3466
3467         e_start=$($LFS getstripe -I2 $name |
3468                   awk '/lcme_extent.e_start:/ { print $2 }')
3469         [ $e_start -eq 2097152 ] ||
3470                 error "(7.5.1) expect the COMP2 start at 2097152, got $e_start"
3471
3472         e_end=$($LFS getstripe -I2 $name |
3473                 awk '/lcme_extent.e_end:/ { print $2 }')
3474         [ "$e_end" = "EOF" ] ||
3475                 error "(7.5.2) expect the COMP2 end at (EOF), got $e_end"
3476
3477         local size=$(stat $name | awk '/Size:/ { print $2 }')
3478         [ $size -eq $((4096 * $bcount)) ] ||
3479                 error "(7.6) expect the size $((4096 * $bcount)), but got $size"
3480
3481         cat $name > /dev/null || error "(7.7) cannot read $name"
3482
3483         echo "dummy" >> $name || error "(7.8) cannot write $name"
3484
3485         chown $RUNAS_ID:$RUNAS_GID $name || error "(7.9) cannot chown on $name"
3486
3487         touch $name || error "(7.10) cannot touch $name"
3488
3489         rm -f $name || error "(7.11) cannot unlink $name"
3490
3491         #
3492         # ${fid1}-R-0 contains the old f1's second stripe in each COMP
3493         #
3494         name="$MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
3495         echo "Check $name, it contains f1's second OST-object in each COMP"
3496
3497         $LFS getstripe -v $name || error "(8.1) cannot getstripe on $name"
3498
3499         pattern=$($LFS getstripe -L -I1 $name)
3500         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3501                 error "(8.2.1) expect pattern flag hole, but got $pattern"
3502
3503         pattern=$($LFS getstripe -L -I2 $name)
3504         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3505                 error "(8.2.2) expect pattern flag hole, but got $pattern"
3506
3507         stripes=$($LFS getstripe -c -I1 $name)
3508         [ $stripes -eq 2 ] ||
3509                 error "(8.3.2) expect 2 stripes, but got $stripes"
3510
3511         stripes=$($LFS getstripe -c -I2 $name)
3512         [ $stripes -eq 2 ] ||
3513                 error "(8.3.2) expect 2 stripes, but got $stripes"
3514
3515         e_start=$($LFS getstripe -I1 $name |
3516                   awk '/lcme_extent.e_start:/ { print $2 }')
3517         [ $e_start -eq 0 ] ||
3518                 error "(8.4.1) expect the COMP1 start at 0, got $e_start"
3519
3520         e_end=$($LFS getstripe -I1 $name |
3521                 awk '/lcme_extent.e_end:/ { print $2 }')
3522         [ $e_end -eq 2097152 ] ||
3523                 error "(8.4.2) expect the COMP1 end at 2097152, got $e_end"
3524
3525         e_start=$($LFS getstripe -I2 $name |
3526                   awk '/lcme_extent.e_start:/ { print $2 }')
3527         [ $e_start -eq 2097152 ] ||
3528                 error "(8.5.1) expect the COMP2 start at 2097152, got $e_start"
3529
3530         e_end=$($LFS getstripe -I2 $name |
3531                 awk '/lcme_extent.e_end:/ { print $2 }')
3532         [ "$e_end" = "EOF" ] ||
3533                 error "(8.5.2) expect the COMP2 end at (EOF), got $e_end"
3534
3535         size=$(stat $name | awk '/Size:/ { print $2 }')
3536         [ $size -eq $((4096 * $bcount)) ] ||
3537                 error "(8.6) expect the size $((4096 * $bcount)), but got $size"
3538
3539         cat $name > /dev/null && error "(8.7) normal read $name should fail"
3540
3541         local failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3542                          bs=4096 2>&1 | grep "Input/output error" | wc -l)
3543
3544         # The first stripe in each COMP was lost
3545         [ $failures -eq 512 ] ||
3546                 error "(8.8) expect 512 IO failures, but get $failures"
3547
3548         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3549         [ $size -eq $((4096 * $bcount)) ] ||
3550                 error "(8.9) expect the size $((4096 * $bcount)), but got $size"
3551
3552         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 &&
3553                 error "(8.10) write to the LOV EA hole should fail"
3554
3555         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 seek=300 ||
3556                 error "(8.11) write to normal stripe should NOT fail"
3557
3558         echo "foo" >> $name && error "(8.12) append write $name should fail"
3559
3560         chown $RUNAS_ID:$RUNAS_GID $name || error "(8.13) cannot chown on $name"
3561
3562         touch $name || error "(8.14) cannot touch $name"
3563
3564         rm -f $name || error "(8.15) cannot unlink $name"
3565
3566         #
3567         # ${fid2}-R-0 contains the old f2's first stripe in each COMP
3568         #
3569         name="$MOUNT/.lustre/lost+found/MDT0000/${fid2}-R-0"
3570         echo "Check $name, it contains f2's first stripe in each COMP"
3571
3572         $LFS getstripe -v $name || error "(9.1) cannot getstripe on $name"
3573
3574         pattern=$($LFS getstripe -L -I1 $name)
3575         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3576                 error "(9.2.1) expect pattern flag hole, but got $pattern"
3577
3578         pattern=$($LFS getstripe -L -I2 $name)
3579         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3580                 error "(9.2.2) expect pattern flag hole, but got $pattern"
3581
3582         stripes=$($LFS getstripe -c -I1 $name)
3583         [ $stripes -eq 2 ] ||
3584                 error "(9.3.2) expect 2 stripes, but got $stripes"
3585
3586         stripes=$($LFS getstripe -c -I2 $name)
3587         [ $stripes -eq 2 ] ||
3588                 error "(9.3.2) expect 2 stripes, but got $stripes"
3589
3590         e_start=$($LFS getstripe -I1 $name |
3591                   awk '/lcme_extent.e_start:/ { print $2 }')
3592         [ $e_start -eq 0 ] ||
3593                 error "(9.4.1) expect the COMP1 start at 0, got $e_start"
3594
3595         e_end=$($LFS getstripe -I1 $name |
3596                 awk '/lcme_extent.e_end:/ { print $2 }')
3597         [ $e_end -eq 2097152 ] ||
3598                 error "(9.4.2) expect the COMP1 end at 2097152, got $e_end"
3599
3600         e_start=$($LFS getstripe -I2 $name |
3601                   awk '/lcme_extent.e_start:/ { print $2 }')
3602         [ $e_start -eq 2097152 ] ||
3603                 error "(9.5.1) expect the COMP2 start at 2097152, got $e_start"
3604
3605         e_end=$($LFS getstripe -I2 $name |
3606                 awk '/lcme_extent.e_end:/ { print $2 }')
3607         [ "$e_end" = "EOF" ] ||
3608                 error "(9.5.2) expect the COMP2 end at (EOF), got $e_end"
3609
3610         size=$(stat $name | awk '/Size:/ { print $2 }')
3611         # The second stripe in COMP was lost, so we do not know there
3612         # have ever been some data before. 'stat' will regard it as
3613         # no data on the lost stripe.
3614         bcount=$((256 * 3))
3615         [ $size -eq $((4096 * $bcount)) ] ||
3616                 error "(9.6) expect size $((4096 * $bcount)), but got $size"
3617
3618         cat $name > /dev/null &&
3619                 error "(9.7) normal read $name should fail"
3620
3621         failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3622                    bs=4096 2>&1 | grep "Input/output error" | wc -l)
3623         [ $failures -eq 512 ] ||
3624                 error "(9.8) expect 256 IO failures, but get $failures"
3625
3626         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
3627         # The second stripe in COMP was lost, so we do not know there
3628         # have ever been some data before. Since 'dd' skip failure,
3629         # it will regard the lost stripe contains data.
3630         bcount=$((256 * 4))
3631         [ $size -eq $((4096 * $bcount)) ] ||
3632                 error "(9.9) expect the size $((4096 * $bcount)), but got $size"
3633
3634         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
3635                 seek=300 && error "(9.10) write to the LOV EA hole should fail"
3636
3637         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 ||
3638                 error "(9.11) write to normal stripe should NOT fail"
3639
3640         echo "foo" >> $name &&
3641                 error "(9.12) append write $name should fail"
3642
3643         chown $RUNAS_ID:$RUNAS_GID $name ||
3644                 error "(9.13) cannot chown on $name"
3645
3646         touch $name || error "(9.14) cannot touch $name"
3647
3648         rm -f $name || error "(7.15) cannot unlink $name"
3649 }
3650 run_test 20b "Handle the orphan with dummy LOV EA slot properly - PFL case"
3651
3652 test_21() {
3653         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.5.59) ]] &&
3654                 skip "ignore the test if MDS is older than 2.5.59" && return
3655
3656         check_mount_and_prep
3657         createmany -o $DIR/$tdir/f 100 || error "(0) Fail to create 100 files"
3658
3659         echo "Start all LFSCK components by default (-s 1)"
3660         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -s 1 -r ||
3661                 error "Fail to start LFSCK"
3662
3663         echo "namespace LFSCK should be in 'scanning-phase1' status"
3664         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
3665         [ "$STATUS" == "scanning-phase1" ] ||
3666                 error "Expect namespace 'scanning-phase1', but got '$STATUS'"
3667
3668         echo "layout LFSCK should be in 'scanning-phase1' status"
3669         STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
3670         [ "$STATUS" == "scanning-phase1" ] ||
3671                 error "Expect layout 'scanning-phase1', but got '$STATUS'"
3672
3673         echo "Stop all LFSCK components by default"
3674         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 ||
3675                 error "Fail to stop LFSCK"
3676 }
3677 run_test 21 "run all LFSCK components by default"
3678
3679 test_22a() {
3680         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
3681
3682         echo "#####"
3683         echo "The parent_A references the child directory via some name entry,"
3684         echo "but the child directory back references another parent_B via its"
3685         echo "".." name entry. The parent_B does not exist. Then the namespace"
3686         echo "LFSCK will repair the child directory's ".." name entry."
3687         echo "#####"
3688
3689         check_mount_and_prep
3690
3691         $LFS mkdir -i 1 $DIR/$tdir/guard || error "(1) Fail to mkdir on MDT1"
3692         $LFS mkdir -i 1 $DIR/$tdir/foo || error "(2) Fail to mkdir on MDT1"
3693
3694         echo "Inject failure stub on MDT0 to simulate bad dotdot name entry"
3695         echo "The dummy's dotdot name entry references the guard."
3696         #define OBD_FAIL_LFSCK_BAD_PARENT       0x161e
3697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161e
3698         $LFS mkdir -i 0 $DIR/$tdir/foo/dummy ||
3699                 error "(3) Fail to mkdir on MDT0"
3700         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3701
3702         rmdir $DIR/$tdir/guard || error "(4) Fail to rmdir $DIR/$tdir/guard"
3703
3704         echo "Trigger namespace LFSCK to repair unmatched pairs"
3705         $START_NAMESPACE -A -r ||
3706                 error "(5) Fail to start LFSCK for namespace"
3707
3708         wait_all_targets_blocked namespace completed 6
3709
3710         local repaired=$($SHOW_NAMESPACE |
3711                          awk '/^unmatched_pairs_repaired/ { print $2 }')
3712         [ $repaired -eq 1 ] ||
3713                 error "(7) Fail to repair unmatched pairs: $repaired"
3714
3715         echo "'ls' should success after namespace LFSCK repairing"
3716         ls -ail $DIR/$tdir/foo/dummy > /dev/null ||
3717                 error "(8) ls should success."
3718 }
3719 run_test 22a "LFSCK can repair unmatched pairs (1)"
3720
3721 test_22b() {
3722         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
3723
3724         echo "#####"
3725         echo "The parent_A references the child directory via the name entry_B,"
3726         echo "but the child directory back references another parent_C via its"
3727         echo "".." name entry. The parent_C exists, but there is no the name"
3728         echo "entry_B under the parent_C. Then the namespace LFSCK will repair"
3729         echo "the child directory's ".." name entry and its linkEA."
3730         echo "#####"
3731
3732         check_mount_and_prep
3733
3734         $LFS mkdir -i 1 $DIR/$tdir/guard || error "(1) Fail to mkdir on MDT1"
3735         $LFS mkdir -i 1 $DIR/$tdir/foo || error "(2) Fail to mkdir on MDT1"
3736
3737         echo "Inject failure stub on MDT0 to simulate bad dotdot name entry"
3738         echo "and bad linkEA. The dummy's dotdot name entry references the"
3739         echo "guard. The dummy's linkEA references n non-exist name entry."
3740         #define OBD_FAIL_LFSCK_BAD_PARENT       0x161e
3741         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161e
3742         $LFS mkdir -i 0 $DIR/$tdir/foo/dummy ||
3743                 error "(3) Fail to mkdir on MDT0"
3744         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3745
3746         local dummyfid=$($LFS path2fid $DIR/$tdir/foo/dummy)
3747         echo "fid2path should NOT work on the dummy's FID $dummyfid"
3748         local dummyname=$($LFS fid2path $DIR $dummyfid)
3749         [ "$dummyname" != "$DIR/$tdir/foo/dummy" ] ||
3750                 error "(4) fid2path works unexpectedly."
3751
3752         echo "Trigger namespace LFSCK to repair unmatched pairs"
3753         $START_NAMESPACE -A -r ||
3754                 error "(5) Fail to start LFSCK for namespace"
3755
3756         wait_all_targets_blocked namespace completed 6
3757
3758         local repaired=$($SHOW_NAMESPACE |
3759                          awk '/^unmatched_pairs_repaired/ { print $2 }')
3760         [ $repaired -eq 1 ] ||
3761                 error "(7) Fail to repair unmatched pairs: $repaired"
3762
3763         echo "fid2path should work on the dummy's FID $dummyfid after LFSCK"
3764         local dummyname=$($LFS fid2path $DIR $dummyfid)
3765         [ "$dummyname" == "$DIR/$tdir/foo/dummy" ] ||
3766                 error "(8) fid2path does not work"
3767 }
3768 run_test 22b "LFSCK can repair unmatched pairs (2)"
3769
3770 test_23a() {
3771         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
3772
3773         echo "#####"
3774         echo "The name entry is there, but the MDT-object for such name "
3775         echo "entry does not exist. The namespace LFSCK should find out "
3776         echo "and repair the inconsistency as required."
3777         echo "#####"
3778
3779         check_mount_and_prep
3780
3781         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT0"
3782         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 || error "(2) Fail to mkdir d1 on MDT1"
3783
3784         echo "Inject failure stub on MDT1 to simulate dangling name entry"
3785         #define OBD_FAIL_LFSCK_DANGLING2        0x1620
3786         do_facet mds2 $LCTL set_param fail_loc=0x1620
3787         rmdir $DIR/$tdir/d0/d1 || error "(3) Fail to rmdir d1"
3788         do_facet mds2 $LCTL set_param fail_loc=0
3789
3790         echo "'ls' should fail because of dangling name entry"
3791         ls -ail $DIR/$tdir/d0/d1 > /dev/null 2>&1 && error "(4) ls should fail."
3792
3793         echo "Trigger namespace LFSCK to find out dangling name entry"
3794         $START_NAMESPACE -A -r ||
3795                 error "(5) Fail to start LFSCK for namespace"
3796
3797         wait_all_targets_blocked namespace completed 6
3798
3799         local repaired=$($SHOW_NAMESPACE |
3800                          awk '/^dangling_repaired/ { print $2 }')
3801         [ $repaired -eq 1 ] ||
3802                 error "(7) Fail to repair dangling name entry: $repaired"
3803
3804         echo "'ls' should fail because not re-create MDT-object by default"
3805         ls -ail $DIR/$tdir/d0/d1 > /dev/null 2>&1 && error "(8) ls should fail."
3806
3807         echo "Trigger namespace LFSCK again to repair dangling name entry"
3808         $START_NAMESPACE -A -r -C ||
3809                 error "(9) Fail to start LFSCK for namespace"
3810
3811         wait_all_targets_blocked namespace completed 10
3812
3813         repaired=$($SHOW_NAMESPACE |
3814                    awk '/^dangling_repaired/ { print $2 }')
3815         [ $repaired -eq 1 ] ||
3816                 error "(11) Fail to repair dangling name entry: $repaired"
3817
3818         echo "'ls' should success after namespace LFSCK repairing"
3819         ls -ail $DIR/$tdir/d0/d1 > /dev/null || error "(12) ls should success."
3820 }
3821 run_test 23a "LFSCK can repair dangling name entry (1)"
3822
3823 test_23b() {
3824         echo "#####"
3825         echo "The objectA has multiple hard links, one of them corresponding"
3826         echo "to the name entry_B. But there is something wrong for the name"
3827         echo "entry_B and cause entry_B to references non-exist object_C."
3828         echo "In the first-stage scanning, the LFSCK will think the entry_B"
3829         echo "as dangling, and re-create the lost object_C. When the LFSCK"
3830         echo "comes to the second-stage scanning, it will find that the"
3831         echo "former re-creating object_C is not proper, and will try to"
3832         echo "replace the object_C with the real object_A."
3833         echo "#####"
3834
3835         check_mount_and_prep
3836
3837         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT0"
3838         $LFS path2fid $DIR/$tdir/d0
3839
3840         createmany -o $DIR/$tdir/d0/t 10 || error "(1.5) Fail to creatmany"
3841
3842         echo "dummy" > $DIR/$tdir/d0/f0 || error "(2) Fail to touch on MDT0"
3843         $LFS path2fid $DIR/$tdir/d0/f0
3844
3845         echo "dead" > $DIR/$tdir/d0/f1 || error "(3) Fail to touch on MDT0"
3846         $LFS path2fid $DIR/$tdir/d0/f1
3847
3848         local SEQ0=$($LFS path2fid $DIR/$tdir/d0/f0 | awk -F':' '{print $1}')
3849         local SEQ1=$($LFS path2fid $DIR/$tdir/d0/f1 | awk -F':' '{print $1}')
3850
3851         if [ "$SEQ0" != "$SEQ1" ]; then
3852                 # To guarantee that the f0 and f1 are in the same FID seq
3853                 rm -f $DIR/$tdir/d0/f0 ||
3854                         error "(3.1) Fail to unlink $DIR/$tdir/d0/f0"
3855                 echo "dummy" > $DIR/$tdir/d0/f0 ||
3856                         error "(3.2) Fail to touch on MDT0"
3857                 $LFS path2fid $DIR/$tdir/d0/f0
3858         fi
3859
3860         local OID=$($LFS path2fid $DIR/$tdir/d0/f1 | awk -F':' '{print $2}')
3861         OID=$(printf %d $OID)
3862
3863         echo "Inject failure stub on MDT0 to simulate dangling name entry"
3864         #define OBD_FAIL_LFSCK_DANGLING3        0x1621
3865         do_facet $SINGLEMDS $LCTL set_param fail_val=$OID fail_loc=0x1621
3866         ln $DIR/$tdir/d0/f0 $DIR/$tdir/d0/foo || error "(4) Fail to hard link"
3867         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
3868
3869         # If there is creation after the dangling injection, it may re-use
3870         # the just released local object (inode) that is referenced by the
3871         # dangling name entry. It will fail the dangling injection.
3872         # So before deleting the target object for the dangling name entry,
3873         # remove some other objects to avoid the target object being reused
3874         # by some potential creations. LU-7429
3875         unlinkmany $DIR/$tdir/d0/t 10 || error "(5.0) Fail to unlinkmany"
3876
3877         rm -f $DIR/$tdir/d0/f1 || error "(5) Fail to unlink $DIR/$tdir/d0/f1"
3878
3879         echo "'ls' should fail because of dangling name entry"
3880         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 &&
3881                 error "(6) ls should fail."
3882
3883         echo "Trigger namespace LFSCK to find out dangling name entry"
3884         $START_NAMESPACE -r -C ||
3885                 error "(7) Fail to start LFSCK for namespace"
3886
3887         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3888                 mdd.${MDT_DEV}.lfsck_namespace |
3889                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3890                 $SHOW_NAMESPACE
3891                 error "(8) unexpected status"
3892         }
3893
3894         local repaired=$($SHOW_NAMESPACE |
3895                          awk '/^dangling_repaired/ { print $2 }')
3896         [ $repaired -eq 1 ] ||
3897                 error "(9) Fail to repair dangling name entry: $repaired"
3898
3899         repaired=$($SHOW_NAMESPACE |
3900                    awk '/^multiple_linked_repaired/ { print $2 }')
3901         [ $repaired -eq 1 ] ||
3902                 error "(10) Fail to drop the former created object: $repaired"
3903
3904         local data=$(cat $DIR/$tdir/d0/foo)
3905         [ "$data" == "dummy" ] ||
3906                 error "(11) The $DIR/$tdir/d0/foo is not recovered: $data"
3907 }
3908 run_test 23b "LFSCK can repair dangling name entry (2)"
3909
3910 cleanup_23c() {
3911         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
3912         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3913                 mdd.${MDT_DEV}.lfsck_namespace |
3914                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3915                 $SHOW_NAMESPACE
3916                 error "(10) unexpected status"
3917         }
3918
3919         stop_full_debug_logging
3920 }
3921
3922 test_23c() {
3923         echo "#####"
3924         echo "The objectA has multiple hard links, one of them corresponding"
3925         echo "to the name entry_B. But there is something wrong for the name"
3926         echo "entry_B and cause entry_B to references non-exist object_C."
3927         echo "In the first-stage scanning, the LFSCK will think the entry_B"
3928         echo "as dangling, and re-create the lost object_C. And then others"
3929         echo "modified the re-created object_C. When the LFSCK comes to the"
3930         echo "second-stage scanning, it will find that the former re-creating"
3931         echo "object_C maybe wrong and try to replace the object_C with the"
3932         echo "real object_A. But because object_C has been modified, so the"
3933         echo "LFSCK cannot replace it."
3934         echo "#####"
3935
3936         start_full_debug_logging
3937
3938         check_mount_and_prep
3939
3940         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT0"
3941         parent_fid="$($LFS path2fid $DIR/$tdir/d0)"
3942         echo "parent_fid=$parent_fid"
3943
3944         createmany -o $DIR/$tdir/d0/t 10 || error "(1.5) Fail to creatmany"
3945
3946         echo "dummy" > $DIR/$tdir/d0/f0 || error "(2) Fail to touch on MDT0"
3947         f0_fid="$($LFS path2fid $DIR/$tdir/d0/f0)"
3948         echo "f0_fid=$f0_fid"
3949
3950         echo "dead" > $DIR/$tdir/d0/f1 || error "(3) Fail to touch on MDT0"
3951         f1_fid="$($LFS path2fid $DIR/$tdir/d0/f1)"
3952         echo "f1_fid=$f1_fid"
3953
3954         if [ "${fid_f0/:.*/}" != "${fid_f1/:.*/}" ]; then
3955                 # To guarantee that the f0 and f1 are in the same FID seq
3956                 rm -f $DIR/$tdir/d0/f0 ||
3957                         error "(3.1) Fail to unlink $DIR/$tdir/d0/f0"
3958                 echo "dummy" > $DIR/$tdir/d0/f0 ||
3959                         error "(3.2) Fail to touch on MDT0"
3960                 f0_fid="$($LFS path2fid $DIR/$tdir/d0/f0)"
3961                 echo "f0_fid=$f0_fid (replaced)"
3962         fi
3963
3964         local oid=$(awk -F':' '{ printf $2 }' <<< $f1_fid)
3965
3966         echo "Inject failure stub on MDT0 to simulate dangling name entry"
3967         #define OBD_FAIL_LFSCK_DANGLING3        0x1621
3968         do_facet $SINGLEMDS $LCTL set_param fail_val=$oid fail_loc=0x1621
3969         ln $DIR/$tdir/d0/f0 $DIR/$tdir/d0/foo || error "(4) Fail to hard link"
3970         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
3971
3972         # If there is creation after the dangling injection, it may re-use
3973         # the just released local object (inode) that is referenced by the
3974         # dangling name entry. It will fail the dangling injection.
3975         # So before deleting the target object for the dangling name entry,
3976         # remove some other objects to avoid the target object being reused
3977         # by some potential creations. LU-7429
3978         unlinkmany $DIR/$tdir/d0/t 10 || error "(5.0) Fail to unlinkmany"
3979
3980         rm -f $DIR/$tdir/d0/f1 || error "(5) Fail to unlink $DIR/$tdir/d0/f1"
3981
3982         echo "'ls' should fail because of dangling name entry"
3983         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 &&
3984                 error "(6) ls should fail."
3985
3986         #define OBD_FAIL_LFSCK_DELAY3           0x1602
3987         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
3988
3989         echo "Trigger namespace LFSCK to find out dangling name entry"
3990         $START_NAMESPACE -r -C ||
3991                 error "(7) Fail to start LFSCK for namespace"
3992
3993         wait_update_facet client "stat -c%s $DIR/$tdir/d0/foo" "0" $LTIME || {
3994                 # While unexpected by the test, it is valid for LFSCK to repair
3995                 # the link to the original object before any data is written.
3996                 local size=$(stat -c %s $DIR/$tdir/d0/foo)
3997
3998                 if [ "$size" = "6" -a "$(<$DIR/$tdir/d0/foo)" = "dummy" ]; then
3999                         log "LFSCK repaired file prematurely"
4000                         cleanup_23c
4001                         return 0
4002                 fi
4003
4004                 stat $DIR/$tdir/d0/foo
4005                 $SHOW_NAMESPACE
4006                 error "(8) unexpected size"
4007         }
4008
4009         echo "data" >> $DIR/$tdir/d0/foo || error "(9) Fail to write"
4010         cancel_lru_locks osc
4011
4012         cleanup_23c
4013
4014         local repaired=$($SHOW_NAMESPACE |
4015                          awk '/^dangling_repaired/ { print $2 }')
4016         [ $repaired -eq 1 ] ||
4017                 error "(11) Fail to repair dangling name entry: $repaired"
4018
4019         local data=$(cat $DIR/$tdir/d0/foo)
4020         [ "$data" != "dummy" ] ||
4021                 error "(12) The $DIR/$tdir/d0/foo should not be recovered"
4022 }
4023 run_test 23c "LFSCK can repair dangling name entry (3)"
4024
4025 test_24() {
4026         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4027         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
4028
4029         echo "#####"
4030         echo "Two MDT-objects back reference the same name entry via their"
4031         echo "each own linkEA entry, but the name entry only references one"
4032         echo "MDT-object. The namespace LFSCK will remove the linkEA entry"
4033         echo "for the MDT-object that is not recognized. If such MDT-object"
4034         echo "has no other linkEA entry after the removing, then the LFSCK"
4035         echo "will add it as orphan under the .lustre/lost+found/MDTxxxx/."
4036         echo "#####"
4037
4038         check_mount_and_prep
4039
4040         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4041
4042         mkdir $DIR/$tdir/d0/guard || error "(1) Fail to mkdir guard"
4043         $LFS path2fid $DIR/$tdir/d0/guard
4044
4045         mkdir $DIR/$tdir/d0/dummy || error "(2) Fail to mkdir dummy"
4046         $LFS path2fid $DIR/$tdir/d0/dummy
4047
4048         local pfid
4049         if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
4050                 pfid=$($LFS path2fid $DIR/$tdir/d0/guard)
4051         else
4052                 pfid=$($LFS path2fid $DIR/$tdir/d0/dummy)
4053         fi
4054
4055         touch $DIR/$tdir/d0/guard/foo ||
4056                 error "(3) Fail to touch $DIR/$tdir/d0/guard/foo"
4057
4058         echo "Inject failure stub on MDT0 to simulate the case that"
4059         echo "the $DIR/$tdir/d0/dummy/foo has the 'bad' linkEA entry"
4060         echo "that references $DIR/$tdir/d0/guard/foo."
4061         echo "Then remove the name entry $DIR/$tdir/d0/dummy/foo."
4062         echo "So the MDT-object $DIR/$tdir/d0/dummy/foo will be left"
4063         echo "there with the same linkEA entry as another MDT-object"
4064         echo "$DIR/$tdir/d0/guard/foo has"
4065
4066         #define OBD_FAIL_LFSCK_MUL_REF          0x1622
4067         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1622
4068         $LFS mkdir -i 0 $DIR/$tdir/d0/dummy/foo ||
4069                 error "(4) Fail to mkdir $DIR/$tdir/d0/dummy/foo"
4070         $LFS path2fid $DIR/$tdir/d0/dummy/foo
4071         local cfid=$($LFS path2fid $DIR/$tdir/d0/dummy/foo)
4072         rmdir $DIR/$tdir/d0/dummy/foo ||
4073                 error "(5) Fail to remove $DIR/$tdir/d0/dummy/foo name entry"
4074         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4075
4076         echo "stat $DIR/$tdir/d0/dummy/foo should fail"
4077         stat $DIR/$tdir/d0/dummy/foo > /dev/null 2>&1 &&
4078                 error "(6) stat successfully unexpectedly"
4079
4080         echo "Trigger namespace LFSCK to repair multiple-referenced name entry"
4081         $START_NAMESPACE -A -r ||
4082                 error "(7) Fail to start LFSCK for namespace"
4083
4084         wait_all_targets_blocked namespace completed 8
4085
4086         local repaired=$($SHOW_NAMESPACE |
4087                          awk '/^multiple_referenced_repaired/ { print $2 }')
4088         [ $repaired -eq 1 ] ||
4089         error "(9) Fail to repair multiple referenced name entry: $repaired"
4090
4091         echo "There should be an orphan under .lustre/lost+found/MDT0000/"
4092         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
4093                 error "(10) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
4094
4095         local cname="$cfid-$pfid-D-0"
4096         ls -ail $MOUNT/.lustre/lost+found/MDT0000/$cname ||
4097                 error "(11) .lustre/lost+found/MDT0000/ should not be empty"
4098 }
4099 run_test 24 "LFSCK can repair multiple-referenced name entry"
4100
4101 test_25() {
4102         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
4103                 skip "ldiskfs only test" && return
4104
4105         echo "#####"
4106         echo "The file type in the name entry does not match the file type"
4107         echo "claimed by the referenced object. Then the LFSCK will update"
4108         echo "the file type in the name entry."
4109         echo "#####"
4110
4111         check_mount_and_prep
4112
4113         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4114
4115         echo "Inject failure stub on MDT0 to simulate the case that"
4116         echo "the file type stored in the name entry is wrong."
4117
4118         #define OBD_FAIL_LFSCK_BAD_TYPE         0x1623
4119         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1623
4120         touch $DIR/$tdir/d0/foo || error "(2) Fail to touch $DIR/$tdir/d0/foo"
4121         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4122
4123         echo "Trigger namespace LFSCK to repair bad file type in the name entry"
4124         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace"
4125
4126         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
4127                 mdd.${MDT_DEV}.lfsck_namespace |
4128                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
4129                 $SHOW_NAMESPACE
4130                 error "(4) unexpected status"
4131         }
4132
4133         local repaired=$($SHOW_NAMESPACE |
4134                          awk '/^bad_file_type_repaired/ { print $2 }')
4135         [ $repaired -eq 1 ] ||
4136         error "(5) Fail to repair bad file type in name entry: $repaired"
4137
4138         ls -ail $DIR/$tdir/d0 || error "(6) Fail to 'ls' the $DIR/$tdir/d0"
4139 }
4140 run_test 25 "LFSCK can repair bad file type in the name entry"
4141
4142 test_26a() {
4143         echo "#####"
4144         echo "The local name entry back referenced by the MDT-object is lost."
4145         echo "The namespace LFSCK will add the missing local name entry back"
4146         echo "to the normal namespace."
4147         echo "#####"
4148
4149         check_mount_and_prep
4150
4151         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4152         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
4153         local foofid=$($LFS path2fid $DIR/$tdir/d0/foo)
4154
4155         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/dummy ||
4156                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
4157
4158         echo "Inject failure stub on MDT0 to simulate the case that"
4159         echo "foo's name entry will be removed, but the foo's object"
4160         echo "and its linkEA are kept in the system."
4161
4162         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
4163         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
4164         rm -f $DIR/$tdir/d0/foo || error "(4) Fail to unlink $DIR/$tdir/d0/foo"
4165         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4166
4167         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 &&
4168                 error "(5) 'ls' should fail"
4169
4170         echo "Trigger namespace LFSCK to repair the missing remote name entry"
4171         $START_NAMESPACE -r -A ||
4172                 error "(6) Fail to start LFSCK for namespace"
4173
4174         wait_all_targets_blocked namespace completed 7
4175
4176         local repaired=$($SHOW_NAMESPACE |
4177                          awk '/^lost_dirent_repaired/ { print $2 }')
4178         [ $repaired -eq 1 ] ||
4179                 error "(8) Fail to repair lost dirent: $repaired"
4180
4181         ls -ail $DIR/$tdir/d0/foo ||
4182                 error "(9) Fail to 'ls' $DIR/$tdir/d0/foo"
4183
4184         local foofid2=$($LFS path2fid $DIR/$tdir/d0/foo)
4185         [ "$foofid" == "$foofid2" ] ||
4186                 error "(10) foo's FID changed: $foofid, $foofid2"
4187 }
4188 run_test 26a "LFSCK can add the missing local name entry back to the namespace"
4189
4190 test_26b() {
4191         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4192
4193         echo "#####"
4194         echo "The remote name entry back referenced by the MDT-object is lost."
4195         echo "The namespace LFSCK will add the missing remote name entry back"
4196         echo "to the normal namespace."
4197         echo "#####"
4198
4199         check_mount_and_prep
4200
4201         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4202         $LFS mkdir -i 0 $DIR/$tdir/d0/foo || error "(2) Fail to mkdir foo"
4203         local foofid=$($LFS path2fid $DIR/$tdir/d0/foo)
4204
4205         echo "Inject failure stub on MDT0 to simulate the case that"
4206         echo "foo's name entry will be removed, but the foo's object"
4207         echo "and its linkEA are kept in the system."
4208
4209         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
4210         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
4211         rmdir $DIR/$tdir/d0/foo || error "(3) Fail to rmdir $DIR/$tdir/d0/foo"
4212         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4213
4214         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 &&
4215                 error "(4) 'ls' should fail"
4216
4217         echo "Trigger namespace LFSCK to repair the missing remote name entry"
4218         $START_NAMESPACE -r -A ||
4219                 error "(5) Fail to start LFSCK for namespace"
4220
4221         wait_all_targets_blocked namespace completed 6
4222
4223         local repaired=$($SHOW_NAMESPACE |
4224                          awk '/^lost_dirent_repaired/ { print $2 }')
4225         [ $repaired -eq 1 ] ||
4226                 error "(7) Fail to repair lost dirent: $repaired"
4227
4228         ls -ail $DIR/$tdir/d0/foo ||
4229                 error "(8) Fail to 'ls' $DIR/$tdir/d0/foo"
4230
4231         local foofid2=$($LFS path2fid $DIR/$tdir/d0/foo)
4232         [ "$foofid" == "$foofid2" ] ||
4233                 error "(9) foo's FID changed: $foofid, $foofid2"
4234 }
4235 run_test 26b "LFSCK can add the missing remote name entry back to the namespace"
4236
4237 test_27a() {
4238         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
4239
4240         echo "#####"
4241         echo "The local parent referenced by the MDT-object linkEA is lost."
4242         echo "The namespace LFSCK will re-create the lost parent as orphan."
4243         echo "#####"
4244
4245         check_mount_and_prep
4246
4247         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4248         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
4249         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/dummy ||
4250                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
4251
4252         echo "Inject failure stub on MDT0 to simulate the case that"
4253         echo "foo's name entry will be removed, but the foo's object"
4254         echo "and its linkEA are kept in the system. And then remove"
4255         echo "another hard link and the parent directory."
4256
4257         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
4258         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
4259         rm -f $DIR/$tdir/d0/foo ||
4260                 error "(4) Fail to unlink $DIR/$tdir/d0/foo"
4261         rm -f $DIR/$tdir/d0/dummy ||
4262                 error "(5) Fail to unlink $DIR/$tdir/d0/dummy"
4263         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4264
4265         rm -rf $DIR/$tdir/d0 || error "(5) Fail to unlink the dir d0"
4266         ls -ail $DIR/$tdir/d0 > /dev/null 2>&1 && error "(6) 'ls' should fail"
4267
4268         echo "Trigger namespace LFSCK to repair the lost parent"
4269         $START_NAMESPACE -r -A ||
4270                 error "(6) Fail to start LFSCK for namespace"
4271
4272         wait_all_targets_blocked namespace completed 7
4273
4274         local repaired=$($SHOW_NAMESPACE |
4275                          awk '/^lost_dirent_repaired/ { print $2 }')
4276         [ $repaired -eq 1 ] ||
4277                 error "(8) Fail to repair lost dirent: $repaired"
4278
4279         echo "There should be an orphan under .lustre/lost+found/MDT0000/"
4280         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
4281                 error "(9) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
4282
4283         ls -ail $MOUNT/.lustre/lost+found/MDT0000/
4284
4285         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-P-*)
4286         [ ! -z "$cname" ] ||
4287                 error "(10) .lustre/lost+found/MDT0000/ should not be empty"
4288 }
4289 run_test 27a "LFSCK can recreate the lost local parent directory as orphan"
4290
4291 test_27b() {
4292         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4293         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
4294
4295         echo "#####"
4296         echo "The remote parent referenced by the MDT-object linkEA is lost."
4297         echo "The namespace LFSCK will re-create the lost parent as orphan."
4298         echo "#####"
4299
4300         check_mount_and_prep
4301
4302         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4303         $LFS mkdir -i 0 $DIR/$tdir/d0/foo || error "(2) Fail to mkdir foo"
4304
4305         $LFS path2fid $DIR/$tdir/d0
4306
4307         echo "Inject failure stub on MDT0 to simulate the case that"
4308         echo "foo's name entry will be removed, but the foo's object"
4309         echo "and its linkEA are kept in the system. And then remove"
4310         echo "the parent directory."
4311
4312         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
4313         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
4314         rmdir $DIR/$tdir/d0/foo || error "(3) Fail to rmdir $DIR/$tdir/d0/foo"
4315         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4316
4317         rmdir $DIR/$tdir/d0 || error "(4) Fail to unlink the dir d0"
4318         ls -ail $DIR/$tdir/d0 > /dev/null 2>&1 && error "(5) 'ls' should fail"
4319
4320         echo "Trigger namespace LFSCK to repair the missing remote name entry"
4321         $START_NAMESPACE -r -A ||
4322                 error "(6) Fail to start LFSCK for namespace"
4323
4324         wait_all_targets_blocked namespace completed 7
4325
4326         local repaired=$($SHOW_NAMESPACE |
4327                          awk '/^lost_dirent_repaired/ { print $2 }')
4328         [ $repaired -eq 1 ] ||
4329                 error "(8) Fail to repair lost dirent: $repaired"
4330
4331         ls -ail $MOUNT/.lustre/lost+found/
4332
4333         echo "There should be an orphan under .lustre/lost+found/MDT0001/"
4334         [ -d $MOUNT/.lustre/lost+found/MDT0001 ] ||
4335                 error "(9) $MOUNT/.lustre/lost+found/MDT0001/ should be there"
4336
4337         ls -ail $MOUNT/.lustre/lost+found/MDT0001/
4338
4339         cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-P-*)
4340         [ ! -z "$cname" ] ||
4341                 error "(10) .lustre/lost+found/MDT0001/ should not be empty"
4342 }
4343 run_test 27b "LFSCK can recreate the lost remote parent directory as orphan"
4344
4345 test_28() {
4346         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4347
4348         echo "#####"
4349         echo "The target name entry is lost. The LFSCK should insert the"
4350         echo "orphan MDT-object under .lustre/lost+found/MDTxxxx. But if"
4351         echo "the MDT (on which the orphan MDT-object resides) has ever"
4352         echo "failed to respond some name entry verification during the"
4353         echo "first stage-scanning, then the LFSCK should skip to handle"
4354         echo "orphan MDT-object on this MDT. But other MDTs should not"
4355         echo "be affected."
4356         echo "#####"
4357
4358         check_mount_and_prep
4359         $LFS mkdir -i 0 $DIR/$tdir/d1
4360         $LFS mkdir -i 1 $DIR/$tdir/d1/a1
4361         $LFS mkdir -i 1 $DIR/$tdir/d1/a2
4362
4363         $LFS mkdir -i 1 $DIR/$tdir/d2
4364         $LFS mkdir -i 0 $DIR/$tdir/d2/a1
4365         $LFS mkdir -i 0 $DIR/$tdir/d2/a2
4366
4367         echo "Inject failure stub on MDT0 to simulate the case that"
4368         echo "d1/a1's name entry will be removed, but the d1/a1's object"
4369         echo "and its linkEA are kept in the system. And the case that"
4370         echo "d2/a2's name entry will be removed, but the d2/a2's object"
4371         echo "and its linkEA are kept in the system."
4372
4373         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
4374         do_facet mds1 $LCTL set_param fail_loc=0x1624
4375         do_facet mds2 $LCTL set_param fail_loc=0x1624
4376         rmdir $DIR/$tdir/d1/a1 || error "(1) Fail to rmdir $DIR/$tdir/d1/a1"
4377         rmdir $DIR/$tdir/d2/a2 || error "(2) Fail to rmdir $DIR/$tdir/d2/a2"
4378         do_facet mds1 $LCTL set_param fail_loc=0
4379         do_facet mds2 $LCTL set_param fail_loc=0
4380
4381         cancel_lru_locks mdc
4382         cancel_lru_locks osc
4383
4384         echo "Inject failure, to simulate the MDT0 fail to handle"
4385         echo "MDT1 LFSCK request during the first-stage scanning."
4386         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
4387         do_facet mds2 $LCTL set_param fail_loc=0x161c fail_val=0
4388
4389         echo "Trigger namespace LFSCK on all devices to find out orphan object"
4390         $START_NAMESPACE -r -A ||
4391                 error "(3) Fail to start LFSCK for namespace"
4392
4393         wait_update_facet mds1 "$LCTL get_param -n \
4394                 mdd.$(facet_svc mds1).lfsck_namespace |
4395                 awk '/^status/ { print \\\$2 }'" "partial" 32 || {
4396                 error "(4) mds1 is not the expected 'partial'"
4397         }
4398
4399         wait_update_facet mds2 "$LCTL get_param -n \
4400                 mdd.$(facet_svc mds2).lfsck_namespace |
4401                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
4402                 error "(5) mds2 is not the expected 'completed'"
4403         }
4404
4405         do_facet mds2 $LCTL set_param fail_loc=0 fail_val=0
4406
4407         local repaired=$(do_facet mds1 $LCTL get_param -n \
4408                          mdd.$(facet_svc mds1).lfsck_namespace |
4409                          awk '/^lost_dirent_repaired/ { print $2 }')
4410         [ $repaired -eq 0 ] ||
4411                 error "(6) Expect 0 fixed on mds1, but got: $repaired"
4412
4413         repaired=$(do_facet mds2 $LCTL get_param -n \
4414                    mdd.$(facet_svc mds2).lfsck_namespace |
4415                    awk '/^lost_dirent_repaired/ { print $2 }')
4416         [ $repaired -eq 1 ] ||
4417                 error "(7) Expect 1 fixed on mds2, but got: $repaired"
4418
4419         echo "Trigger namespace LFSCK on all devices again to cleanup"
4420         $START_NAMESPACE -r -A ||
4421                 error "(8) Fail to start LFSCK for namespace"
4422
4423         wait_all_targets_blocked namespace completed 9
4424
4425         local repaired=$(do_facet mds1 $LCTL get_param -n \
4426                          mdd.$(facet_svc mds1).lfsck_namespace |
4427                          awk '/^lost_dirent_repaired/ { print $2 }')
4428         [ $repaired -eq 1 ] ||
4429                 error "(10) Expect 1 fixed on mds1, but got: $repaired"
4430
4431         repaired=$(do_facet mds2 $LCTL get_param -n \
4432                    mdd.$(facet_svc mds2).lfsck_namespace |
4433                    awk '/^lost_dirent_repaired/ { print $2 }')
4434         [ $repaired -eq 0 ] ||
4435                 error "(11) Expect 0 fixed on mds2, but got: $repaired"
4436 }
4437 run_test 28 "Skip the failed MDT(s) when handle orphan MDT-objects"
4438
4439 test_29a() {
4440         echo "#####"
4441         echo "The object's nlink attribute is larger than the object's known"
4442         echo "name entries count. The LFSCK will repair the object's nlink"
4443         echo "attribute to match the known name entries count"
4444         echo "#####"
4445
4446         check_mount_and_prep
4447
4448         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4449         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
4450
4451         echo "Inject failure stub on MDT0 to simulate the case that foo's"
4452         echo "nlink attribute is larger than its name entries count."
4453
4454         #define OBD_FAIL_LFSCK_MORE_NLINK       0x1625
4455         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1625
4456         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/h1 ||
4457                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
4458         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4459
4460         cancel_lru_locks mdc
4461         local count=$(stat --format=%h $DIR/$tdir/d0/foo)
4462         [ $count -eq 3 ] || error "(4) Cannot inject error: $count"
4463
4464         echo "Trigger namespace LFSCK to repair the nlink count"
4465         $START_NAMESPACE -r -A ||
4466                 error "(5) Fail to start LFSCK for namespace"
4467
4468         wait_all_targets_blocked namespace completed 6
4469
4470         local repaired=$($SHOW_NAMESPACE |
4471                          awk '/^nlinks_repaired/ { print $2 }')
4472         [ $repaired -eq 1 ] ||
4473                 error "(7) Fail to repair nlink count: $repaired"
4474
4475         cancel_lru_locks mdc
4476         count=$(stat --format=%h $DIR/$tdir/d0/foo)
4477         [ $count -eq 2 ] || error "(8) Fail to repair nlink count: $count"
4478 }
4479 # Disable 29a, we only allow nlink to be updated if the known linkEA
4480 # entries is larger than nlink count.
4481 #
4482 #run_test 29a "LFSCK can repair bad nlink count (1)"
4483
4484 test_29b() {
4485         echo "#####"
4486         echo "The object's nlink attribute is smaller than the object's known"
4487         echo "name entries count. The LFSCK will repair the object's nlink"
4488         echo "attribute to match the known name entries count"
4489         echo "#####"
4490
4491         check_mount_and_prep
4492
4493         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
4494         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
4495
4496         echo "Inject failure stub on MDT0 to simulate the case that foo's"
4497         echo "nlink attribute is smaller than its name entries count."
4498
4499         #define OBD_FAIL_LFSCK_LESS_NLINK       0x1626
4500         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1626
4501         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/h1 ||
4502                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
4503         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4504
4505         cancel_lru_locks mdc
4506         local count=$(stat --format=%h $DIR/$tdir/d0/foo)
4507         [ $count -eq 1 ] || error "(4) Cannot inject error: $count"
4508
4509         echo "Trigger namespace LFSCK to repair the nlink count"
4510         $START_NAMESPACE -r -A ||
4511                 error "(5) Fail to start LFSCK for namespace"
4512
4513         wait_all_targets_blocked namespace completed 6
4514
4515         local repaired=$($SHOW_NAMESPACE |
4516                          awk '/^nlinks_repaired/ { print $2 }')
4517         [ $repaired -eq 1 ] ||
4518                 error "(7) Fail to repair nlink count: $repaired"
4519
4520         cancel_lru_locks mdc
4521         count=$(stat --format=%h $DIR/$tdir/d0/foo)
4522         [ $count -eq 2 ] || error "(8) Fail to repair nlink count: $count"
4523 }
4524 run_test 29b "LFSCK can repair bad nlink count (2)"
4525
4526 test_29c()
4527 {
4528         echo "#####"
4529         echo "The namespace LFSCK will create many hard links to the target"
4530         echo "file as to exceed the linkEA size limitation. Under such case"
4531         echo "the linkEA will be marked as overflow that will prevent the"
4532         echo "target file to be migrated. Then remove some hard links to"
4533         echo "make the left hard links to be held within the linkEA size"
4534         echo "limitation. But before the namespace LFSCK adding all the"
4535         echo "missed linkEA entries back, the overflow mark (timestamp)"
4536         echo "will not be cleared."
4537         echo "#####"
4538
4539         check_mount_and_prep
4540
4541         mkdir -p $DIR/$tdir/guard || error "(0.1) Fail to mkdir"
4542         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/foo ||
4543                 error "(0.2) Fail to mkdir"
4544         touch $DIR/$tdir/guard/f0 || error "(1) Fail to create"
4545         local oldfid=$($LFS path2fid $DIR/$tdir/guard/f0)
4546
4547         # define MAX_LINKEA_SIZE        4096
4548         # sizeof(link_ea_header) = 24
4549         # sizeof(link_ea_entry) = 18
4550         # nlink_min=$(((MAX_LINKEA_SIZE - sizeof(link_ea_header)) /
4551         #             (sizeof(link_ea_entry) + name_length))
4552         # If the average name length is 12 bytes, then 150 hard links
4553         # is totally enough to overflow the linkEA
4554         echo "Create 150 hard links should succeed although the linkEA overflow"
4555         createmany -l $DIR/$tdir/guard/f0 $DIR/$tdir/foo/ttttttttttt 150 ||
4556                 error "(2) Fail to hard link"
4557
4558         cancel_lru_locks mdc
4559         if [ $MDSCOUNT -ge 2 ]; then
4560                 $LFS migrate -m 1 $DIR/$tdir/guard 2>/dev/null &&
4561                         error "(3.1) Migrate should fail"
4562
4563                 echo "The object with linkEA overflow should NOT be migrated"
4564                 local newfid=$($LFS path2fid $DIR/$tdir/guard/f0)
4565                 [ "$newfid" == "$oldfid" ] ||
4566                         error "(3.2) Migrate should fail: $newfid != $oldfid"
4567         fi
4568
4569         # Remove 100 hard links, then the linkEA should have space
4570         # to hold the missed linkEA entries.
4571         echo "Remove 100 hard links to save space for the missed linkEA entries"
4572         unlinkmany $DIR/$tdir/foo/ttttttttttt 100 || error "(4) Fail to unlink"
4573
4574         if [ $MDSCOUNT -ge 2 ]; then
4575                 $LFS migrate -m 1 $DIR/$tdir/guard 2>/dev/null &&
4576                         error "(5.1) Migrate should fail"
4577
4578                 # The overflow timestamp is still there, so migration will fail.
4579                 local newfid=$($LFS path2fid $DIR/$tdir/guard/f0)
4580                 [ "$newfid" == "$oldfid" ] ||
4581                         error "(5.2) Migrate should fail: $newfid != $oldfid"
4582         fi
4583
4584         # sleep 3 seconds to guarantee that the overflow is recognized
4585         sleep 3
4586
4587         echo "Trigger namespace LFSCK to clear the overflow timestamp"
4588         $START_NAMESPACE -r -A ||
4589                 error "(6) Fail to start LFSCK for namespace"
4590
4591         wait_all_targets_blocked namespace completed 7
4592
4593         local repaired=$($SHOW_NAMESPACE |
4594                          awk '/^linkea_overflow_cleared/ { print $2 }')
4595         [ $repaired -eq 1 ] ||
4596                 error "(8) Fail to clear linkea overflow: $repaired"
4597
4598         repaired=$($SHOW_NAMESPACE |
4599                    awk '/^nlinks_repaired/ { print $2 }')
4600         [ $repaired -eq 0 ] ||
4601                 error "(9) Unexpected nlink repaired: $repaired"
4602
4603         if [ $MDSCOUNT -ge 2 ]; then
4604                 $LFS migrate -m 1 $DIR/$tdir/guard 2>/dev/null ||
4605                         error "(10.1) Migrate failure"
4606
4607                 # Migration should succeed after clear the overflow timestamp.
4608                 local newfid=$($LFS path2fid $DIR/$tdir/guard/f0)
4609                 [ "$newfid" != "$oldfid" ] ||
4610                         error "(10.2) Migrate should succeed"
4611
4612                 ls -l $DIR/$tdir/foo > /dev/null ||
4613                         error "(11) 'ls' failed after migration"
4614         fi
4615
4616         rm -f $DIR/$tdir/guard/f0 || error "(12) Fail to unlink f0"
4617         rm -rf $DIR/$tdir/foo || error "(13) Fail to rmdir foo"
4618 }
4619 run_test 29c "verify linkEA size limitation"
4620
4621 test_30() {
4622         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
4623                 skip "ldiskfs only test" && return
4624         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
4625
4626         echo "#####"
4627         echo "The namespace LFSCK will move the orphans from backend"
4628         echo "/lost+found directory to normal client visible namespace"
4629         echo "or to global visible ./lustre/lost+found/MDTxxxx/ directory"
4630         echo "#####"
4631
4632         check_mount_and_prep
4633
4634         $LFS mkdir -i 0 $DIR/$tdir/foo || error "(1) Fail to mkdir foo"
4635         touch $DIR/$tdir/foo/f0 || error "(2) Fail to touch f1"
4636
4637         echo "Inject failure stub on MDT0 to simulate the case that"
4638         echo "directory d0 has no linkEA entry, then the LFSCK will"
4639         echo "move it into .lustre/lost+found/MDTxxxx/ later."
4640
4641         #define OBD_FAIL_LFSCK_NO_LINKEA        0x161d
4642         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161d
4643         mkdir $DIR/$tdir/foo/d0 || error "(3) Fail to mkdir d0"
4644         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4645
4646         local pfid=$($LFS path2fid $DIR/$tdir/foo)
4647         local cfid=$($LFS path2fid $DIR/$tdir/foo/d0)
4648
4649         touch $DIR/$tdir/foo/d0/f1 || error "(4) Fail to touch f1"
4650         mkdir $DIR/$tdir/foo/d0/d1 || error "(5) Fail to mkdir d1"
4651
4652         echo "Inject failure stub on MDT0 to simulate the case that the"
4653         echo "object's name entry will be removed, but not destroy the"
4654         echo "object. Then backend e2fsck will handle it as orphan and"
4655         echo "add them into the backend /lost+found directory."
4656
4657         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
4658         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
4659         rmdir $DIR/$tdir/foo/d0/d1 || error "(6) Fail to rmdir d1"
4660         rm -f $DIR/$tdir/foo/d0/f1 || error "(7) Fail to unlink f1"
4661         rmdir $DIR/$tdir/foo/d0 || error "(8) Fail to rmdir d0"
4662         rm -f $DIR/$tdir/foo/f0 || error "(9) Fail to unlink f0"
4663         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4664
4665         umount_client $MOUNT || error "(10) Fail to stop client!"
4666
4667         stop $SINGLEMDS || error "(11) Fail to stop MDT0"
4668
4669         echo "run e2fsck"
4670         run_e2fsck $(facet_host $SINGLEMDS) $MDT_DEVNAME "-y" ||
4671                 error "(12) Fail to run e2fsck"
4672
4673         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
4674                 error "(13) Fail to start MDT0"
4675
4676         echo "Trigger namespace LFSCK to recover backend orphans"
4677         $START_NAMESPACE -r -A ||
4678                 error "(14) Fail to start LFSCK for namespace"
4679
4680         wait_all_targets_blocked namespace completed 15
4681
4682         local repaired=$($SHOW_NAMESPACE |
4683                          awk '/^local_lost_found_moved/ { print $2 }')
4684         [ $repaired -ge 4 ] ||
4685                 error "(16) Fail to recover backend orphans: $repaired"
4686
4687         mount_client $MOUNT || error "(17) Fail to start client!"
4688
4689         stat $DIR/$tdir/foo/f0 || error "(18) f0 is not recovered"
4690
4691         ls -ail $MOUNT/.lustre/lost+found/
4692
4693         echo "d0 should become orphan under .lustre/lost+found/MDT0000/"
4694         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
4695                 error "(19) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
4696
4697         ls -ail $MOUNT/.lustre/lost+found/MDT0000/
4698
4699         local cname=$MOUNT/.lustre/lost+found/MDT0000/${cfid}-${pfid}-D-0
4700         [ ! -z "$cname" ] || error "(20) d0 is not recovered"
4701
4702         stat ${cname}/d1 || error "(21) d1 is not recovered"
4703         stat ${cname}/f1 || error "(22) f1 is not recovered"
4704 }
4705 run_test 30 "LFSCK can recover the orphans from backend /lost+found"
4706
4707 test_31a() {
4708         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4709
4710         echo "#####"
4711         echo "For the name entry under a striped directory, if the name"
4712         echo "hash does not match the shard, then the LFSCK will repair"
4713         echo "the bad name entry"
4714         echo "#####"
4715
4716         check_mount_and_prep
4717
4718         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4719                 error "(1) Fail to create striped directory"
4720
4721         echo "Inject failure stub on client to simulate the case that"
4722         echo "some name entry should be inserted into other non-first"
4723         echo "shard, but inserted into the first shard by wrong"
4724
4725         #define OBD_FAIL_LFSCK_BAD_NAME_HASH    0x1628
4726         $LCTL set_param fail_loc=0x1628 fail_val=0
4727         createmany -d $DIR/$tdir/striped_dir/d $MDSCOUNT ||
4728                 error "(2) Fail to create file under striped directory"
4729         $LCTL set_param fail_loc=0 fail_val=0
4730
4731         echo "Trigger namespace LFSCK to repair bad name hash"
4732         $START_NAMESPACE -r -A ||
4733                 error "(3) Fail to start LFSCK for namespace"
4734
4735         wait_all_targets_blocked namespace completed 4
4736
4737         local repaired=$($SHOW_NAMESPACE |
4738                          awk '/^name_hash_repaired/ { print $2 }')
4739         [ $repaired -ge 1 ] ||
4740                 error "(5) Fail to repair bad name hash: $repaired"
4741
4742         umount_client $MOUNT || error "(6) umount failed"
4743         mount_client $MOUNT || error "(7) mount failed"
4744
4745         for ((i = 0; i < $MDSCOUNT; i++)); do
4746                 stat $DIR/$tdir/striped_dir/d$i ||
4747                         error "(8) Fail to stat d$i after LFSCK"
4748                 rmdir $DIR/$tdir/striped_dir/d$i ||
4749                         error "(9) Fail to unlink d$i after LFSCK"
4750         done
4751
4752         rmdir $DIR/$tdir/striped_dir ||
4753                 error "(10) Fail to remove the striped directory after LFSCK"
4754 }
4755 run_test 31a "The LFSCK can find/repair the name entry with bad name hash (1)"
4756
4757 test_31b() {
4758         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4759
4760         echo "#####"
4761         echo "For the name entry under a striped directory, if the name"
4762         echo "hash does not match the shard, then the LFSCK will repair"
4763         echo "the bad name entry"
4764         echo "#####"
4765
4766         check_mount_and_prep
4767
4768         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4769                 error "(1) Fail to create striped directory"
4770
4771         echo "Inject failure stub on client to simulate the case that"
4772         echo "some name entry should be inserted into other non-second"
4773         echo "shard, but inserted into the secod shard by wrong"
4774
4775         #define OBD_FAIL_LFSCK_BAD_NAME_HASH    0x1628
4776         $LCTL set_param fail_loc=0x1628 fail_val=1
4777         createmany -d $DIR/$tdir/striped_dir/d $MDSCOUNT ||
4778                 error "(2) Fail to create file under striped directory"
4779         $LCTL set_param fail_loc=0 fail_val=0
4780
4781         echo "Trigger namespace LFSCK to repair bad name hash"
4782         $START_NAMESPACE -r -A ||
4783                 error "(3) Fail to start LFSCK for namespace"
4784
4785         wait_all_targets_blocked namespace completed 4
4786
4787         local repaired=$(do_facet mds2 $LCTL get_param -n \
4788                          mdd.$(facet_svc mds2).lfsck_namespace |
4789                          awk '/^name_hash_repaired/ { print $2 }')
4790         [ $repaired -ge 1 ] ||
4791                 error "(5) Fail to repair bad name hash: $repaired"
4792
4793         umount_client $MOUNT || error "(6) umount failed"
4794         mount_client $MOUNT || error "(7) mount failed"
4795
4796         for ((i = 0; i < $MDSCOUNT; i++)); do
4797                 stat $DIR/$tdir/striped_dir/d$i ||
4798                         error "(8) Fail to stat d$i after LFSCK"
4799                 rmdir $DIR/$tdir/striped_dir/d$i ||
4800                         error "(9) Fail to unlink d$i after LFSCK"
4801         done
4802
4803         rmdir $DIR/$tdir/striped_dir ||
4804                 error "(10) Fail to remove the striped directory after LFSCK"
4805 }
4806 run_test 31b "The LFSCK can find/repair the name entry with bad name hash (2)"
4807
4808 test_31c() {
4809         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4810
4811         echo "#####"
4812         echo "For some reason, the master MDT-object of the striped directory"
4813         echo "may lost its master LMV EA. If nobody created files under the"
4814         echo "master directly after the master LMV EA lost, then the LFSCK"
4815         echo "should re-generate the master LMV EA."
4816         echo "#####"
4817
4818         check_mount_and_prep
4819
4820         echo "Inject failure stub on MDT0 to simulate the case that the"
4821         echo "master MDT-object of the striped directory lost the LMV EA."
4822
4823         #define OBD_FAIL_LFSCK_LOST_MASTER_LMV  0x1629
4824         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1629
4825         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4826                 error "(1) Fail to create striped directory"
4827         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
4828
4829         echo "Trigger namespace LFSCK to re-generate master LMV EA"
4830         $START_NAMESPACE -r -A ||
4831                 error "(2) Fail to start LFSCK for namespace"
4832
4833         wait_all_targets_blocked namespace completed 3
4834
4835         local repaired=$($SHOW_NAMESPACE |
4836                          awk '/^striped_dirs_repaired/ { print $2 }')
4837         [ $repaired -eq 1 ] ||
4838                 error "(4) Fail to re-generate master LMV EA: $repaired"
4839
4840         umount_client $MOUNT || error "(5) umount failed"
4841         mount_client $MOUNT || error "(6) mount failed"
4842
4843         local empty=$(ls $DIR/$tdir/striped_dir/)
4844         [ -z "$empty" ] || error "(7) The master LMV EA is not repaired: $empty"
4845
4846         rmdir $DIR/$tdir/striped_dir ||
4847                 error "(8) Fail to remove the striped directory after LFSCK"
4848 }
4849 run_test 31c "Re-generate the lost master LMV EA for striped directory"
4850
4851 test_31d() {
4852         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4853
4854         echo "#####"
4855         echo "For some reason, the master MDT-object of the striped directory"
4856         echo "may lost its master LMV EA. If somebody created files under the"
4857         echo "master directly after the master LMV EA lost, then the LFSCK"
4858         echo "should NOT re-generate the master LMV EA, instead, it should"
4859         echo "change the broken striped dirctory as read-only to prevent"
4860         echo "further damage"
4861         echo "#####"
4862
4863         check_mount_and_prep
4864
4865         echo "Inject failure stub on MDT0 to simulate the case that the"
4866         echo "master MDT-object of the striped directory lost the LMV EA."
4867
4868         #define OBD_FAIL_LFSCK_LOST_MASTER_LMV  0x1629
4869         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1629
4870         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4871                 error "(1) Fail to create striped directory"
4872         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0
4873
4874         umount_client $MOUNT || error "(2) umount failed"
4875         mount_client $MOUNT || error "(3) mount failed"
4876
4877         touch $DIR/$tdir/striped_dir/dummy ||
4878                 error "(4) Fail to touch under broken striped directory"
4879
4880         echo "Trigger namespace LFSCK to find out the inconsistency"
4881         $START_NAMESPACE -r -A ||
4882                 error "(5) Fail to start LFSCK for namespace"
4883
4884         wait_all_targets_blocked namespace completed 6
4885
4886         local repaired=$($SHOW_NAMESPACE |
4887                          awk '/^striped_dirs_repaired/ { print $2 }')
4888         [ $repaired -eq 0 ] ||
4889                 error "(7) Re-generate master LMV EA unexpected: $repaired"
4890
4891         stat $DIR/$tdir/striped_dir/dummy ||
4892                 error "(8) Fail to stat $DIR/$tdir/striped_dir/dummy"
4893
4894         touch $DIR/$tdir/striped_dir/foo &&
4895                 error "(9) The broken striped directory should be read-only"
4896
4897         chattr -i $DIR/$tdir/striped_dir ||
4898                 error "(10) Fail to chattr on the broken striped directory"
4899
4900         rmdir $DIR/$tdir/striped_dir ||
4901                 error "(11) Fail to remove the striped directory after LFSCK"
4902 }
4903 run_test 31d "Set broken striped directory (modified after broken) as read-only"
4904
4905 test_31e() {
4906         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4907
4908         echo "#####"
4909         echo "For some reason, the slave MDT-object of the striped directory"
4910         echo "may lost its slave LMV EA. The LFSCK should re-generate the"
4911         echo "slave LMV EA."
4912         echo "#####"
4913
4914         check_mount_and_prep
4915
4916         echo "Inject failure stub on MDT0 to simulate the case that the"
4917         echo "slave MDT-object (that resides on the same MDT as the master"
4918         echo "MDT-object resides on) lost the LMV EA."
4919
4920         #define OBD_FAIL_LFSCK_LOST_SLAVE_LMV   0x162a
4921         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162a fail_val=0
4922         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4923                 error "(1) Fail to create striped directory"
4924         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
4925
4926         echo "Trigger namespace LFSCK to re-generate slave LMV EA"
4927         $START_NAMESPACE -r -A ||
4928                 error "(2) Fail to start LFSCK for namespace"
4929
4930         wait_all_targets_blocked namespace completed 3
4931
4932         local repaired=$($SHOW_NAMESPACE |
4933                          awk '/^striped_shards_repaired/ { print $2 }')
4934         [ $repaired -eq 1 ] ||
4935                 error "(4) Fail to re-generate slave LMV EA: $repaired"
4936
4937         rmdir $DIR/$tdir/striped_dir ||
4938                 error "(5) Fail to remove the striped directory after LFSCK"
4939 }
4940 run_test 31e "Re-generate the lost slave LMV EA for striped directory (1)"
4941
4942 test_31f() {
4943         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4944
4945         echo "#####"
4946         echo "For some reason, the slave MDT-object of the striped directory"
4947         echo "may lost its slave LMV EA. The LFSCK should re-generate the"
4948         echo "slave LMV EA."
4949         echo "#####"
4950
4951         check_mount_and_prep
4952
4953         echo "Inject failure stub on MDT0 to simulate the case that the"
4954         echo "slave MDT-object (that resides on different MDT as the master"
4955         echo "MDT-object resides on) lost the LMV EA."
4956
4957         #define OBD_FAIL_LFSCK_LOST_SLAVE_LMV   0x162a
4958         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162a fail_val=1
4959         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4960                 error "(1) Fail to create striped directory"
4961         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
4962
4963         echo "Trigger namespace LFSCK to re-generate slave LMV EA"
4964         $START_NAMESPACE -r -A ||
4965                 error "(2) Fail to start LFSCK for namespace"
4966
4967         wait_all_targets_blocked namespace completed 3
4968
4969         local repaired=$(do_facet mds2 $LCTL get_param -n \
4970                          mdd.$(facet_svc mds2).lfsck_namespace |
4971                          awk '/^striped_shards_repaired/ { print $2 }')
4972         [ $repaired -eq 1 ] ||
4973                 error "(4) Fail to re-generate slave LMV EA: $repaired"
4974
4975         rmdir $DIR/$tdir/striped_dir ||
4976                 error "(5) Fail to remove the striped directory after LFSCK"
4977 }
4978 run_test 31f "Re-generate the lost slave LMV EA for striped directory (2)"
4979
4980 test_31g() {
4981         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4982
4983         echo "#####"
4984         echo "For some reason, the stripe index in the slave LMV EA is"
4985         echo "corrupted. The LFSCK should repair the slave LMV EA."
4986         echo "#####"
4987
4988         check_mount_and_prep
4989
4990         echo "Inject failure stub on MDT0 to simulate the case that the"
4991         echo "slave LMV EA on the first shard of the striped directory"
4992         echo "claims the same index as the second shard claims"
4993
4994         #define OBD_FAIL_LFSCK_BAD_SLAVE_LMV    0x162b
4995         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162b fail_val=0
4996         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4997                 error "(1) Fail to create striped directory"
4998         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
4999
5000         echo "Trigger namespace LFSCK to repair the slave LMV EA"
5001         $START_NAMESPACE -r -A ||
5002                 error "(2) Fail to start LFSCK for namespace"
5003
5004         wait_all_targets_blocked namespace completed 3
5005
5006         local repaired=$($SHOW_NAMESPACE |
5007                          awk '/^striped_shards_repaired/ { print $2 }')
5008         [ $repaired -eq 1 ] ||
5009                 error "(4) Fail to repair slave LMV EA: $repaired"
5010
5011         umount_client $MOUNT || error "(5) umount failed"
5012         mount_client $MOUNT || error "(6) mount failed"
5013
5014         touch $DIR/$tdir/striped_dir/foo ||
5015                 error "(7) Fail to touch file after the LFSCK"
5016
5017         rm -f $DIR/$tdir/striped_dir/foo ||
5018                 error "(8) Fail to unlink file after the LFSCK"
5019
5020         rmdir $DIR/$tdir/striped_dir ||
5021                 error "(9) Fail to remove the striped directory after LFSCK"
5022 }
5023 run_test 31g "Repair the corrupted slave LMV EA"
5024
5025 test_31h() {
5026         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5027
5028         echo "#####"
5029         echo "For some reason, the shard's name entry in the striped"
5030         echo "directory may be corrupted. The LFSCK should repair the"
5031         echo "bad shard's name entry."
5032         echo "#####"
5033
5034         check_mount_and_prep
5035
5036         echo "Inject failure stub on MDT0 to simulate the case that the"
5037         echo "first shard's name entry in the striped directory claims"
5038         echo "the same index as the second shard's name entry claims."
5039
5040         #define OBD_FAIL_LFSCK_BAD_SLAVE_NAME   0x162c
5041         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162c fail_val=0
5042         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
5043                 error "(1) Fail to create striped directory"
5044         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
5045
5046         echo "Trigger namespace LFSCK to repair the shard's name entry"
5047         $START_NAMESPACE -r -A ||
5048                 error "(2) Fail to start LFSCK for namespace"
5049
5050         wait_all_targets_blocked namespace completed 3
5051
5052         local repaired=$($SHOW_NAMESPACE |
5053                          awk '/^dirent_repaired/ { print $2 }')
5054         [ $repaired -eq 1 ] ||
5055                 error "(4) Fail to repair shard's name entry: $repaired"
5056
5057         umount_client $MOUNT || error "(5) umount failed"
5058         mount_client $MOUNT || error "(6) mount failed"
5059
5060         touch $DIR/$tdir/striped_dir/foo ||
5061                 error "(7) Fail to touch file after the LFSCK"
5062
5063         rm -f $DIR/$tdir/striped_dir/foo ||
5064                 error "(8) Fail to unlink file after the LFSCK"
5065
5066         rmdir $DIR/$tdir/striped_dir ||
5067                 error "(9) Fail to remove the striped directory after LFSCK"
5068 }
5069 run_test 31h "Repair the corrupted shard's name entry"
5070
5071 test_32a()
5072 {
5073         lfsck_prep 5 5
5074         umount_client $MOUNT
5075
5076         #define OBD_FAIL_LFSCK_ENGINE_DELAY     0x162d
5077         do_facet $SINGLEMDS $LCTL set_param fail_val=3 fail_loc=0x162d
5078         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
5079
5080         local STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
5081         [ "$STATUS" == "scanning-phase1" ] ||
5082                 error "(2) Expect 'scanning-phase1', but got '$STATUS'"
5083
5084         echo "stop ost1"
5085         stop ost1 > /dev/null || error "(3) Fail to stop OST1!"
5086
5087         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
5088         sleep 4
5089
5090         echo "stop LFSCK"
5091         $STOP_LFSCK || error "(4) Fail to stop LFSCK!"
5092
5093         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
5094                 error "(5) Fail to start ost1"
5095 }
5096 run_test 32a "stop LFSCK when some OST failed"
5097
5098 test_32b()
5099 {
5100         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5101
5102         lfsck_prep 5 5
5103         $LFS mkdir -i 1 $DIR/$tdir/dp ||
5104                 error "(1) Fail to create $DIR/$tdir/dp"
5105         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/dp/dc1 ||
5106                 error "(2) Fail to create $DIR/$tdir/dp/dc1"
5107         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/dp/dc2 ||
5108                 error "(3) Fail to create $DIR/$tdir/dp/dc2"
5109         umount_client $MOUNT
5110
5111         #define OBD_FAIL_LFSCK_ENGINE_DELAY     0x162d
5112         do_facet $SINGLEMDS $LCTL set_param fail_val=3 fail_loc=0x162d
5113         $START_NAMESPACE -r -A || error "(4) Fail to start LFSCK for namespace!"
5114
5115         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
5116                 mdd.${MDT_DEV}.lfsck_namespace |
5117                 awk '/^status/ { print \\\$2 }'" "scanning-phase1" 32 || {
5118                 $SHOW_NAMESPACE
5119                 error "(5) unexpected status"
5120         }
5121
5122         echo "stop mds2"
5123         stop mds2 > /dev/null || error "(6) Fail to stop MDT2!"
5124
5125         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
5126         sleep 4
5127
5128         echo "stop LFSCK"
5129         $STOP_LFSCK || error "(7) Fail to stop LFSCK!"
5130
5131         start mds2 $(mdsdevname 2) $MOUNT_OPTS_NOSCRUB > /dev/null ||
5132                 error "(8) Fail to start MDT2"
5133 }
5134 run_test 32b "stop LFSCK when some MDT failed"
5135
5136 test_33()
5137 {
5138         lfsck_prep 5 5
5139
5140         $START_LAYOUT --dryrun -o -r ||
5141                 error "(1) Fail to start layout LFSCK"
5142         wait_all_targets_blocked layout completed 2
5143
5144         local PARAMS=$($SHOW_LAYOUT | awk '/^param/ { print $2 }')
5145         [ "$PARAMS" == "dryrun,all_targets,orphan" ] ||
5146                 error "(3) Expect 'dryrun,all_targets,orphan', got '$PARAMS'"
5147
5148         $START_NAMESPACE -e abort -A -r ||
5149                 error "(4) Fail to start namespace LFSCK"
5150         wait_all_targets_blocked namespace completed 5
5151
5152         PARAMS=$($SHOW_NAMESPACE | awk '/^param/ { print $2 }')
5153         [ "$PARAMS" == "failout,all_targets" ] ||
5154                 error "(6) Expect 'failout,all_targets', got '$PARAMS'"
5155 }
5156 run_test 33 "check LFSCK paramters"
5157
5158 test_34()
5159 {
5160         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5161         [ $(facet_fstype $SINGLEMDS) != zfs ] &&
5162                 skip "Only valid for ZFS backend" && return
5163
5164         lfsck_prep 1 1
5165
5166         #define OBD_FAIL_LFSCK_NO_AGENTOBJ      0x1630
5167         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1630
5168         $LFS mkdir -i 1 $DIR/$tdir/dummy ||
5169                 error "(1) Fail to create $DIR/$tdir/dummy"
5170
5171         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
5172         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
5173         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
5174                 mdd.${MDT_DEV}.lfsck_namespace |
5175                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
5176                 $SHOW_NAMESPACE
5177                 error "(3) unexpected status"
5178         }
5179
5180         local repaired=$($SHOW_NAMESPACE |
5181                          awk '/^dirent_repaired/ { print $2 }')
5182         [ $repaired -eq 1 ] ||
5183                 error "(4) Fail to repair the lost agent object: $repaired"
5184
5185         $START_NAMESPACE -r || error "(5) Fail to start LFSCK for namespace!"
5186         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
5187                 mdd.${MDT_DEV}.lfsck_namespace |
5188                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
5189                 $SHOW_NAMESPACE
5190                 error "(6) unexpected status"
5191         }
5192
5193         repaired=$($SHOW_NAMESPACE | awk '/^dirent_repaired/ { print $2 }')
5194         [ $repaired -eq 0 ] ||
5195                 error "(7) Unexpected repairing: $repaired"
5196 }
5197 run_test 34 "LFSCK can rebuild the lost agent object"
5198
5199 test_35()
5200 {
5201         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5202
5203         lfsck_prep 1 1
5204
5205         #define OBD_FAIL_LFSCK_NO_AGENTENT      0x1631
5206         do_facet mds2 $LCTL set_param fail_loc=0x1631
5207         $LFS mkdir -i 1 $DIR/$tdir/dummy ||
5208                 error "(1) Fail to create $DIR/$tdir/dummy"
5209
5210         sync; sleep 3
5211         do_facet mds2 $LCTL set_param fail_loc=0
5212         $START_NAMESPACE -A -r || error "(2) Fail to start LFSCK for namespace!"
5213         wait_update_facet mds2 "$LCTL get_param -n \
5214                 mdd.$(facet_svc mds2).lfsck_namespace |
5215                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
5216                 error "(3) MDS${k} is not the expected 'completed'"
5217
5218         local repaired=$(do_facet mds2 $LCTL get_param -n \
5219                          mdd.$(facet_svc mds2).lfsck_namespace |
5220                          awk '/^agent_entries_repaired/ { print $2 }')
5221         [ $repaired -eq 1 ] ||
5222                 error "(4) Fail to repair the lost agent entry: $repaired"
5223
5224         echo "stopall to cleanup object cache"
5225         stopall > /dev/null
5226         echo "setupall"
5227         setupall > /dev/null
5228
5229         $START_NAMESPACE -A -r || error "(5) Fail to start LFSCK for namespace!"
5230         wait_update_facet mds2 "$LCTL get_param -n \
5231                 mdd.$(facet_svc mds2).lfsck_namespace |
5232                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
5233                 error "(6) MDS${k} is not the expected 'completed'"
5234
5235         repaired=$(do_facet mds2 $LCTL get_param -n \
5236                    mdd.$(facet_svc mds2).lfsck_namespace |
5237                    awk '/^agent_entries_repaired/ { print $2 }')
5238         [ $repaired -eq 0 ] ||
5239                 error "(7) Unexpected repairing: $repaired"
5240 }
5241 run_test 35 "LFSCK can rebuild the lost agent entry"
5242
5243 test_36a() {
5244         [ $OSTCOUNT -lt 3 ] && skip "needs >= 3 OSTs" && return
5245
5246         echo "#####"
5247         echo "The target MDT-object's LOV EA corrupted as to lose one of the "
5248         echo "mirrors information. The layout LFSCK should rebuild the LOV EA "
5249         echo "with the PFID EA of related OST-object(s) belong to the mirror."
5250         echo "#####"
5251
5252         check_mount_and_prep
5253
5254         $LFS setstripe -N -E 1M -o 0,1 -E -1 -o 2 -N -E 2M -o 1,2 -E -1 -o 0 \
5255                 -N -E 3M -o 2,0 -E -1 -o 1 $DIR/$tdir/f0 ||
5256                 error "(0) Fail to create mirror file $DIR/$tdir/f0"
5257         $LFS setstripe -N -E 1M -o 0,1 -E -1 -o 2 -N -E 2M -o 1,2 -E -1 -o 0 \
5258                 -N -E 3M -o 2,0 -E -1 -o 1 $DIR/$tdir/f1 ||
5259                 error "(1) Fail to create mirror file $DIR/$tdir/f1"
5260         $LFS setstripe -N -E 1M -o 0,1 -E -1 -o 2 -N -E 2M -o 1,2 -E -1 -o 0 \
5261                 -N -E 3M -o 2,0 -E -1 -o 1 $DIR/$tdir/f2 ||
5262                 error "(2) Fail to create mirror file $DIR/$tdir/f2"
5263
5264         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=4 ||
5265                 error "(3) Fail to write $DIR/$tdir/f0"
5266         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=4 ||
5267                 error "(4) Fail to write $DIR/$tdir/f1"
5268         dd if=/dev/zero of=$DIR/$tdir/f2 bs=1M count=4 ||
5269                 error "(5) Fail to write $DIR/$tdir/f2"
5270
5271         $LFS mirror resync $DIR/$tdir/f0 ||
5272                 error "(6) Fail to resync $DIR/$tdir/f0"
5273         $LFS mirror resync $DIR/$tdir/f1 ||
5274                 error "(7) Fail to resync $DIR/$tdir/f1"
5275         $LFS mirror resync $DIR/$tdir/f2 ||
5276                 error "(8) Fail to resync $DIR/$tdir/f2"
5277
5278         cancel_lru_locks mdc
5279         cancel_lru_locks osc
5280
5281         $LFS getstripe $DIR/$tdir/f0 ||
5282                 error "(9) Fail to getstripe for $DIR/$tdir/f0"
5283         $LFS getstripe $DIR/$tdir/f1 ||
5284                 error "(10) Fail to getstripe for $DIR/$tdir/f1"
5285         $LFS getstripe $DIR/$tdir/f2 ||
5286                 error "(11) Fail to getstripe for $DIR/$tdir/f2"
5287
5288         echo "Inject failure, to simulate the case of missing one mirror in LOV"
5289         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
5290         do_facet mds1 $LCTL set_param fail_loc=0x1616
5291
5292         $LFS mirror split --mirror-id 1 -d $DIR/$tdir/f0 ||
5293                 error "(12) Fail to split 1st mirror from $DIR/$tdir/f0"
5294         $LFS mirror split --mirror-id 2 -d $DIR/$tdir/f1 ||
5295                 error "(13) Fail to split 2nd mirror from $DIR/$tdir/f1"
5296         $LFS mirror split --mirror-id 3 -d $DIR/$tdir/f2 ||
5297                 error "(14) Fail to split 3rd mirror from $DIR/$tdir/f2"
5298
5299         sync
5300         sleep 2
5301         do_facet mds1 $LCTL set_param fail_loc=0
5302
5303         $LFS getstripe $DIR/$tdir/f0 | grep "lcme_mirror_id:.*1" &&
5304                 error "(15) The 1st of mirror is not destroyed"
5305         $LFS getstripe $DIR/$tdir/f1 | grep "lcme_mirror_id:.*2" &&
5306                 error "(16) The 2nd of mirror is not destroyed"
5307         $LFS getstripe $DIR/$tdir/f2 | grep "lcme_mirror_id:.*3" &&
5308                 error "(17) The 3rd of mirror is not destroyed"
5309
5310         local mirrors
5311
5312         mirrors=$($LFS getstripe -N $DIR/$tdir/f0)
5313         [ $mirrors -eq 2 ] || error "(18) $DIR/$tdir/f0 has $mirrors mirrors"
5314         mirrors=$($LFS getstripe -N $DIR/$tdir/f1)
5315         [ $mirrors -eq 2 ] || error "(19) $DIR/$tdir/f1 has $mirrors mirrors"
5316         mirrors=$($LFS getstripe -N $DIR/$tdir/f2)
5317         [ $mirrors -eq 2 ] || error "(20) $DIR/$tdir/f2 has $mirrors mirrors"
5318
5319         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
5320         $START_LAYOUT -r -o || error "(21) Fail to start LFSCK for layout!"
5321
5322         for k in $(seq $MDSCOUNT); do
5323                 # The LFSCK status query internal is 30 seconds. For the case
5324                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
5325                 # time to guarantee the status sync up.
5326                 wait_update_facet mds${k} "$LCTL get_param -n \
5327                         mdd.$(facet_svc mds${k}).lfsck_layout |
5328                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
5329                         error "(22) MDS${k} is not the expected 'completed'"
5330         done
5331
5332         for k in $(seq $OSTCOUNT); do
5333                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
5334                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
5335                                 awk '/^status/ { print $2 }')
5336                 [ "$cur_status" == "completed" ] ||
5337                 error "(23) OST${k} Expect 'completed', but got '$cur_status'"
5338         done
5339
5340         local repaired=$(do_facet mds1 $LCTL get_param -n \
5341                          mdd.$(facet_svc mds1).lfsck_layout |
5342                          awk '/^repaired_orphan/ { print $2 }')
5343         [ $repaired -eq 9 ] ||
5344                 error "(24) Expect 9 fixed on mds1, but got: $repaired"
5345
5346         mirrors=$($LFS getstripe -N $DIR/$tdir/f0)
5347         [ $mirrors -eq 3 ] || error "(25) $DIR/$tdir/f0 has $mirrors mirrors"
5348         mirrors=$($LFS getstripe -N $DIR/$tdir/f1)
5349         [ $mirrors -eq 3 ] || error "(26) $DIR/$tdir/f1 has $mirrors mirrors"
5350         mirrors=$($LFS getstripe -N $DIR/$tdir/f2)
5351         [ $mirrors -eq 3 ] || error "(27) $DIR/$tdir/f2 has $mirrors mirrors"
5352
5353         $LFS getstripe $DIR/$tdir/f0 | grep "lcme_mirror_id:.*1" || {
5354                 $LFS getstripe $DIR/$tdir/f0
5355                 error "(28) The 1st of mirror is not recovered"
5356         }
5357
5358         $LFS getstripe $DIR/$tdir/f1 | grep "lcme_mirror_id:.*2" || {
5359                 $LFS getstripe $DIR/$tdir/f1
5360                 error "(29) The 2nd of mirror is not recovered"
5361         }
5362
5363         $LFS getstripe $DIR/$tdir/f2 | grep "lcme_mirror_id:.*3" || {
5364                 $LFS getstripe $DIR/$tdir/f2
5365                 error "(30) The 3rd of mirror is not recovered"
5366         }
5367 }
5368 run_test 36a "rebuild LOV EA for mirrored file (1)"
5369
5370 test_36b() {
5371         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
5372         [ $OSTCOUNT -lt 3 ] && skip "needs >= 3 OSTs" && return
5373
5374         echo "#####"
5375         echo "The mirrored file lost its MDT-object, but relatd OST-objects "
5376         echo "are still there. The layout LFSCK should rebuild the LOV EA "
5377         echo "with the PFID EA of related OST-object(s) belong to the file. "
5378         echo "#####"
5379
5380         check_mount_and_prep
5381
5382         $LFS setstripe -N -E 1M -o 0,1 -E -1 -o 2 -N -E 2M -o 1,2 -E -1 -o 0 \
5383                 -N -E 3M -o 2,0 -E -1 -o 1 $DIR/$tdir/f0 ||
5384                 error "(0) Fail to create mirror file $DIR/$tdir/f0"
5385
5386         local fid=$($LFS path2fid $DIR/$tdir/f0)
5387
5388         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=4 ||
5389                 error "(1) Fail to write $DIR/$tdir/f0"
5390         $LFS mirror resync $DIR/$tdir/f0 ||
5391                 error "(2) Fail to resync $DIR/$tdir/f0"
5392
5393         cancel_lru_locks mdc
5394         cancel_lru_locks osc
5395
5396         $LFS getstripe $DIR/$tdir/f0 ||
5397                 error "(3) Fail to getstripe for $DIR/$tdir/f0"
5398
5399         echo "Inject failure, to simulate the case of missing the MDT-object"
5400         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
5401         do_facet mds1 $LCTL set_param fail_loc=0x1616
5402         rm -f $DIR/$tdir/f0 || error "(4) Fail to remove $DIR/$tdir/f0"
5403
5404         sync
5405         sleep 2
5406         do_facet mds1 $LCTL set_param fail_loc=0
5407
5408         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
5409         $START_LAYOUT -r -o || error "(5) Fail to start LFSCK for layout!"
5410
5411         for k in $(seq $MDSCOUNT); do
5412                 # The LFSCK status query internal is 30 seconds. For the case
5413                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
5414                 # time to guarantee the status sync up.
5415                 wait_update_facet mds${k} "$LCTL get_param -n \
5416                         mdd.$(facet_svc mds${k}).lfsck_layout |
5417                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
5418                         error "(6) MDS${k} is not the expected 'completed'"
5419         done
5420
5421         for k in $(seq $OSTCOUNT); do
5422                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
5423                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
5424                                 awk '/^status/ { print $2 }')
5425                 [ "$cur_status" == "completed" ] ||
5426                 error "(7) OST${k} Expect 'completed', but got '$cur_status'"
5427         done
5428
5429         local count=$(do_facet mds1 $LCTL get_param -n \
5430                       mdd.$(facet_svc mds1).lfsck_layout |
5431                       awk '/^repaired_orphan/ { print $2 }')
5432         [ $count -eq 9 ] || error "(8) Expect 9 fixed on mds1, but got: $count"
5433
5434         local name=$MOUNT/.lustre/lost+found/MDT0000/${fid}-R-0
5435         count=$($LFS getstripe --mirror-count $name)
5436         [ $count -eq 3 ] || error "(9) $DIR/$tdir/f0 has $count mirrors"
5437
5438         count=$($LFS getstripe --component-count $name)
5439         [ $count -eq 6 ] || error "(10) $DIR/$tdir/f0 has $count components"
5440
5441         $LFS getstripe $name | grep "lcme_mirror_id:.*1" || {
5442                 $LFS getstripe $name
5443                 error "(11) The 1st of mirror is not recovered"
5444         }
5445
5446         $LFS getstripe $name | grep "lcme_mirror_id:.*2" || {
5447                 $LFS getstripe $name
5448                 error "(12) The 2nd of mirror is not recovered"
5449         }
5450
5451         $LFS getstripe $name | grep "lcme_mirror_id:.*3" || {
5452                 $LFS getstripe $name
5453                 error "(13) The 3rd of mirror is not recovered"
5454         }
5455 }
5456 run_test 36b "rebuild LOV EA for mirrored file (2)"
5457
5458 test_36c() {
5459         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
5460         [ $OSTCOUNT -lt 3 ] && skip "needs >= 3 OSTs" && return
5461
5462         echo "#####"
5463         echo "The mirrored file has been modified, not resynced yet, then "
5464         echo "lost its MDT-object, but relatd OST-objects are still there. "
5465         echo "The layout LFSCK should rebuild the LOV EA and relatd status "
5466         echo "with the PFID EA of related OST-object(s) belong to the file. "
5467         echo "#####"
5468
5469         check_mount_and_prep
5470
5471         $LFS setstripe -N -E 1M -o 0,1 -E -1 -o 2 -N -E 2M -o 1,2 -E -1 -o 0 \
5472                 $DIR/$tdir/f0 ||
5473                 error "(0) Fail to create mirror file $DIR/$tdir/f0"
5474
5475         local fid=$($LFS path2fid $DIR/$tdir/f0)
5476
5477         # The 1st dd && resync makes all related OST-objects have been written
5478         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=4 ||
5479                 error "(1.1) Fail to write $DIR/$tdir/f0"
5480         $LFS mirror resync $DIR/$tdir/f0 ||
5481                 error "(1.2) Fail to resync $DIR/$tdir/f0"
5482         # The 2nd dd makes one mirror to be stale
5483         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=4 ||
5484                 error "(1.3) Fail to write $DIR/$tdir/f0"
5485
5486         cancel_lru_locks mdc
5487         cancel_lru_locks osc
5488
5489         $LFS getstripe $DIR/$tdir/f0 ||
5490                 error "(2) Fail to getstripe for $DIR/$tdir/f0"
5491
5492         local saved_flags1=$($LFS getstripe $DIR/$tdir/f0 | head -n 10 |
5493                              awk '/lcme_flags/ { print $2 }')
5494         local saved_flags2=$($LFS getstripe $DIR/$tdir/f0 | tail -n 10 |
5495                              awk '/lcme_flags/ { print $2 }')
5496
5497         echo "Inject failure, to simulate the case of missing the MDT-object"
5498         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
5499         do_facet mds1 $LCTL set_param fail_loc=0x1616
5500         rm -f $DIR/$tdir/f0 || error "(3) Fail to remove $DIR/$tdir/f0"
5501
5502         sync
5503         sleep 2
5504         do_facet mds1 $LCTL set_param fail_loc=0
5505
5506         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
5507         $START_LAYOUT -r -o || error "(4) Fail to start LFSCK for layout!"
5508
5509         for k in $(seq $MDSCOUNT); do
5510                 # The LFSCK status query internal is 30 seconds. For the case
5511                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
5512                 # time to guarantee the status sync up.
5513                 wait_update_facet mds${k} "$LCTL get_param -n \
5514                         mdd.$(facet_svc mds${k}).lfsck_layout |
5515                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
5516                         error "(5) MDS${k} is not the expected 'completed'"
5517         done
5518
5519         for k in $(seq $OSTCOUNT); do
5520                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
5521                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
5522                                 awk '/^status/ { print $2 }')
5523                 [ "$cur_status" == "completed" ] ||
5524                 error "(6) OST${k} Expect 'completed', but got '$cur_status'"
5525         done
5526
5527         local count=$(do_facet mds1 $LCTL get_param -n \
5528                       mdd.$(facet_svc mds1).lfsck_layout |
5529                       awk '/^repaired_orphan/ { print $2 }')
5530         [ $count -eq 6 ] || error "(7) Expect 9 fixed on mds1, but got: $count"
5531
5532         local name=$MOUNT/.lustre/lost+found/MDT0000/${fid}-R-0
5533         count=$($LFS getstripe --mirror-count $name)
5534         [ $count -eq 2 ] || error "(8) $DIR/$tdir/f0 has $count mirrors"
5535
5536         count=$($LFS getstripe --component-count $name)
5537         [ $count -eq 4 ] || error "(9) $DIR/$tdir/f0 has $count components"
5538
5539         local flags=$($LFS getstripe $name | head -n 10 |
5540                 awk '/lcme_flags/ { print $2 }')
5541         [ "$flags" == "$saved_flags1" ] || {
5542                 $LFS getstripe $name
5543                 error "(10) expect flags $saved_flags1, got $flags"
5544         }
5545
5546         flags=$($LFS getstripe $name | tail -n 10 |
5547                 awk '/lcme_flags/ { print $2 }')
5548         [ "$flags" == "$saved_flags2" ] || {
5549                 $LFS getstripe $name
5550                 error "(11) expect flags $saved_flags2, got $flags"
5551         }
5552 }
5553 run_test 36c "rebuild LOV EA for mirrored file (3)"
5554
5555 test_37()
5556 {
5557         local PID
5558         local rc
5559         local t_dir="$DIR/$tdir/d0"
5560         check_mount_and_prep
5561
5562         $LFS mkdir -i 0 $t_dir || error "(2) Fail to mkdir $t_dir on MDT0"
5563         multiop_bg_pause $t_dir D_c || { error "multiop failed: $?"; return 1; }
5564         PID=$!
5565         rmdir $t_dir
5566
5567         $START_NAMESPACE -r -A || {
5568             error "(3) Fail to start LFSCK for namespace!"; kill -USR1 $PID; }
5569
5570         wait_all_targets_blocked namespace completed 4
5571         stat $t_dir && rc=1
5572         kill -USR1 $PID
5573         return $rc
5574 }
5575 run_test 37 "LFSCK must skip a ORPHAN"
5576
5577
5578 # restore MDS/OST size
5579 MDSSIZE=${SAVED_MDSSIZE}
5580 OSTSIZE=${SAVED_OSTSIZE}
5581 OSTCOUNT=${SAVED_OSTCOUNT}
5582
5583 # cleanup the system at last
5584 REFORMAT="yes" cleanup_and_setup_lustre
5585
5586 complete $SECONDS
5587 check_and_cleanup_lustre
5588 exit_status