Whamcloud - gitweb
23e5ffbd51ca6c34eb5999ab20c985867482b033
[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 ||