Whamcloud - gitweb
LU-12068 tests: add debug for sanity-lfsck test_6b
[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_POS1" == "N/A" ]; then
790                 [[ $O_POS0 -lt $O_POS1 ]] ||
791                         error "(7.1) $O_POS1 is not larger than $O_POS0"
792         else
793                 [[ $D_POS0 -lt $D_POS1 ]] ||
794                         error "(7.2) $D_POS1 is not larger than $D_POS0"
795         fi
796
797         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
798         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
799                 mdd.${MDT_DEV}.lfsck_namespace |
800                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
801                 $SHOW_NAMESPACE
802                 error "(8) unexpected status"
803         }
804 }
805 run_test 6b "LFSCK resumes from last checkpoint (2)"
806
807 test_7a()
808 {
809         lfsck_prep 5 5
810         umount_client $MOUNT
811
812         #define OBD_FAIL_LFSCK_DELAY2           0x1601
813         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
814         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
815
816         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
817         [ "$STATUS" == "scanning-phase1" ] ||
818                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
819
820         # Sleep 3 sec to guarantee at least one object processed by LFSCK
821         sleep 3
822         echo "stop $SINGLEMDS"
823         stop $SINGLEMDS > /dev/null || error "(4) Fail to stop MDS!"
824
825         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
826         echo "start $SINGLEMDS"
827         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
828                 error "(5) Fail to start MDS!"
829
830         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
831                 mdd.${MDT_DEV}.lfsck_namespace |
832                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
833                 $SHOW_NAMESPACE
834                 error "(6) unexpected status"
835         }
836 }
837 run_test 7a "non-stopped LFSCK should auto restarts after MDS remount (1)"
838
839 test_7b()
840 {
841         lfsck_prep 2 2
842
843         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
844         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
845         for ((i = 0; i < 20; i++)); do
846                 touch $DIR/$tdir/dummy${i}
847         done
848
849         #define OBD_FAIL_LFSCK_DELAY3           0x1602
850         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1602
851         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
852         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
853                 mdd.${MDT_DEV}.lfsck_namespace |
854                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
855                 $SHOW_NAMESPACE
856                 error "(4) unexpected status"
857         }
858
859         umount_client $MOUNT
860         echo "stop $SINGLEMDS"
861         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop MDS!"
862
863         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
864         echo "start $SINGLEMDS"
865         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
866                 error "(6) Fail to start MDS!"
867
868         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
869                 mdd.${MDT_DEV}.lfsck_namespace |
870                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
871                 $SHOW_NAMESPACE
872                 error "(7) unexpected status"
873         }
874 }
875 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
876
877 test_8()
878 {
879         echo "formatall"
880         formatall > /dev/null
881         echo "setupall"
882         setupall > /dev/null
883
884         lfsck_prep 20 20
885
886         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
887         [ "$STATUS" == "init" ] ||
888                 error "(2) Expect 'init', but got '$STATUS'"
889
890         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
891         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
892         mkdir $DIR/$tdir/crashed
893
894         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
895         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
896         for ((i = 0; i < 5; i++)); do
897                 touch $DIR/$tdir/dummy${i}
898         done
899
900         umount_client $MOUNT || error "(3) Fail to stop client!"
901
902         #define OBD_FAIL_LFSCK_DELAY2           0x1601
903         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1601
904         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
905
906         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
907         [ "$STATUS" == "scanning-phase1" ] ||
908                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
909
910         $STOP_LFSCK || error "(6) Fail to stop LFSCK!"
911
912         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
913         [ "$STATUS" == "stopped" ] ||
914                 error "(7) Expect 'stopped', but got '$STATUS'"
915
916         $START_NAMESPACE || error "(8) Fail to start LFSCK for namespace!"
917
918         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
919         [ "$STATUS" == "scanning-phase1" ] ||
920                 error "(9) Expect 'scanning-phase1', but got '$STATUS'"
921
922         #define OBD_FAIL_LFSCK_FATAL2           0x1609
923         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
924         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
925                 mdd.${MDT_DEV}.lfsck_namespace |
926                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
927                 $SHOW_NAMESPACE
928                 error "(10) unexpected status"
929         }
930
931         #define OBD_FAIL_LFSCK_DELAY1           0x1600
932         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
933         $START_NAMESPACE || error "(11) Fail to start LFSCK for namespace!"
934
935         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
936         [ "$STATUS" == "scanning-phase1" ] ||
937                 error "(12) Expect 'scanning-phase1', but got '$STATUS'"
938
939         #define OBD_FAIL_LFSCK_CRASH            0x160a
940         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
941         sleep 5
942
943         echo "stop $SINGLEMDS"
944         stop $SINGLEMDS > /dev/null || error "(13) Fail to stop MDS!"
945
946         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
947         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
948
949         echo "start $SINGLEMDS"
950         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
951                 error "(14) Fail to start MDS!"
952
953         local timeout=$(max_recovery_time)
954         local timer=0
955
956         while [ $timer -lt $timeout ]; do
957                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
958                         mdt.${MDT_DEV}.recovery_status |
959                         awk '/^status/ { print \\\$2 }'")
960                 [ "$STATUS" != "RECOVERING" ] && break;
961                 sleep 1
962                 timer=$((timer + 1))
963         done
964
965         [ $timer != $timeout ] ||
966                 error "(14.1) recovery timeout"
967
968         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
969         [ "$STATUS" == "crashed" ] ||
970                 error "(15) Expect 'crashed', but got '$STATUS'"
971
972         #define OBD_FAIL_LFSCK_DELAY2           0x1601
973         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
974         $START_NAMESPACE || error "(16) Fail to start LFSCK for namespace!"
975
976         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
977         [ "$STATUS" == "scanning-phase1" ] ||
978                 error "(17) Expect 'scanning-phase1', but got '$STATUS'"
979
980         echo "stop $SINGLEMDS"
981         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop MDS!"
982
983         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
984         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
985
986         echo "start $SINGLEMDS"
987         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
988                 error "(19) Fail to start MDS!"
989
990         timer=0
991         while [ $timer -lt $timeout ]; do
992                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
993                         mdt.${MDT_DEV}.recovery_status |
994                         awk '/^status/ { print \\\$2 }'")
995                 [ "$STATUS" != "RECOVERING" ] && break;
996                 sleep 1
997                 timer=$((timer + 1))
998         done
999
1000         [ $timer != $timeout ] ||
1001                 error "(19.1) recovery timeout"
1002
1003         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1004         [ "$STATUS" == "paused" ] ||
1005                 error "(20) Expect 'paused', but got '$STATUS'"
1006
1007         echo "stop $SINGLEMDS"
1008         stop $SINGLEMDS > /dev/null || error "(20.1) Fail to stop MDS!"
1009
1010         echo "start $SINGLEMDS without resume LFSCK"
1011         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SKIP_LFSCK > /dev/null ||
1012                 error "(20.2) Fail to start MDS!"
1013
1014         timer=0
1015         while [ $timer -lt $timeout ]; do
1016                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1017                         mdt.${MDT_DEV}.recovery_status |
1018                         awk '/^status/ { print \\\$2 }'")
1019                 [ "$STATUS" != "RECOVERING" ] && break;
1020                 sleep 1
1021                 timer=$((timer + 1))
1022         done
1023
1024         [ $timer != $timeout ] ||
1025                 error "(20.3) recovery timeout"
1026
1027         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1028         [ "$STATUS" == "paused" ] ||
1029                 error "(20.4) Expect 'paused', but got '$STATUS'"
1030
1031         #define OBD_FAIL_LFSCK_DELAY3           0x1602
1032         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1602
1033
1034         $START_NAMESPACE || error "(21) Fail to start LFSCK for namespace!"
1035         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1036                 mdd.${MDT_DEV}.lfsck_namespace |
1037                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
1038                 $SHOW_NAMESPACE
1039                 error "(22) unexpected status"
1040         }
1041
1042         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1043         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
1044                 error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
1045
1046         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1047         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1048                 mdd.${MDT_DEV}.lfsck_namespace |
1049                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1050                 $SHOW_NAMESPACE
1051                 error "(24) unexpected status"
1052         }
1053
1054         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1055         [ -z "$FLAGS" ] || error "(25) Expect empty flags, but got '$FLAGS'"
1056 }
1057 run_test 8 "LFSCK state machine"
1058
1059 test_9a() {
1060         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1061                 skip "Testing on UP system, the speed may be inaccurate."
1062                 return 0
1063         fi
1064
1065         check_mount_and_prep
1066         $LFS mkdir -i 0 $DIR/$tdir/lfsck || error "(1) Fail to mkdir lfsck"
1067         $LFS setstripe -c 1 -i -1 $DIR/$tdir/lfsck
1068         createmany -o $DIR/$tdir/lfsck/f 5000
1069
1070         local BASE_SPEED1=100
1071         local RUN_TIME1=10
1072         $START_LAYOUT -r -s $BASE_SPEED1 || error "(2) Fail to start LFSCK!"
1073
1074         sleep $RUN_TIME1
1075         STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
1076         [ "$STATUS" == "scanning-phase1" ] ||
1077                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
1078
1079         local SPEED=$($SHOW_LAYOUT |
1080                       awk '/^average_speed_phase1/ { print $2 }')
1081
1082         # There may be time error, normally it should be less than 2 seconds.
1083         # We allow another 20% schedule error.
1084         local TIME_DIFF=2
1085         # MAX_MARGIN = 1.3 = 13 / 10
1086         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
1087                            RUN_TIME1 * 13 / 10))
1088         [ $SPEED -lt $MAX_SPEED ] || {
1089                 $SHOW_LAYOUT
1090                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1091                 error "(4) Speed $SPEED, expected < $MAX_SPEED"
1092         }
1093
1094         # adjust speed limit
1095         local BASE_SPEED2=300
1096         local RUN_TIME2=10
1097         do_facet $SINGLEMDS \
1098                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1099         sleep $RUN_TIME2
1100
1101         SPEED=$($SHOW_LAYOUT | awk '/^average_speed_phase1/ { print $2 }')
1102         # MIN_MARGIN = 0.7 = 7 / 10
1103         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
1104                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
1105                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1106         [ $SPEED -gt $MIN_SPEED ] || {
1107                 if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
1108                         error_ignore LU-5624 \
1109                         "(5.1) Got speed $SPEED, expected more than $MIN_SPEED"
1110                 else
1111                         error \
1112                         "(5.2) Got speed $SPEED, expected more than $MIN_SPEED"
1113                 fi
1114         }
1115
1116         # MAX_MARGIN = 1.3 = 13 / 10
1117         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
1118                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
1119                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1120         [ $SPEED -lt $MAX_SPEED ] || {
1121                 $SHOW_LAYOUT
1122                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1123                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1124                 error "(6) Speed $SPEED, expected < $MAX_SPEED"
1125         }
1126
1127         do_nodes $(comma_list $(mdts_nodes)) \
1128                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1129         do_nodes $(comma_list $(osts_nodes)) \
1130                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1131
1132         wait_update_facet $SINGLEMDS \
1133                 "$LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout |
1134                 awk '/^status/ { print \\\$2 }'" "completed" 30 ||
1135                 error "(7) Failed to get expected 'completed'"
1136 }
1137 run_test 9a "LFSCK speed control (1)"
1138
1139 test_9b() {
1140         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1141                 skip "Testing on UP system, the speed may be inaccurate."
1142                 return 0
1143         fi
1144
1145         lfsck_prep 0 0
1146
1147         echo "Preparing another 50 * 50 files (with error) at $(date)."
1148         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1149         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1150         createmany -d $DIR/$tdir/d 50
1151         createmany -m $DIR/$tdir/f 50
1152         for ((i = 0; i < 50; i++)); do
1153                 createmany -m $DIR/$tdir/d${i}/f 50 > /dev/null
1154         done
1155
1156         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
1157         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
1158         $START_NAMESPACE -r || error "(4) Fail to start LFSCK!"
1159         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1160                 mdd.${MDT_DEV}.lfsck_namespace |
1161                 awk '/^status/ { print \\\$2 }'" "stopped" 10 || {
1162                 $SHOW_NAMESPACE
1163                 error "(5) unexpected status"
1164         }
1165
1166         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1167         echo "Prepared at $(date)."
1168
1169         local BASE_SPEED1=50
1170         local RUN_TIME1=10
1171         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
1172
1173         sleep $RUN_TIME1
1174         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1175         [ "$STATUS" == "scanning-phase2" ] ||
1176                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
1177
1178         local SPEED=$($SHOW_NAMESPACE |
1179                       awk '/^average_speed_phase2/ { print $2 }')
1180         # There may be time error, normally it should be less than 2 seconds.
1181         # We allow another 20% schedule error.
1182         local TIME_DIFF=2
1183         # MAX_MARGIN = 1.3 = 13 / 10
1184         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
1185                           RUN_TIME1 * 13 / 10))
1186         [ $SPEED -lt $MAX_SPEED ] || {
1187                 $SHOW_NAMESPACE
1188                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1189                 error "(8) Speed $SPEED, expected < $MAX_SPEED"
1190         }
1191
1192         # adjust speed limit
1193         local BASE_SPEED2=150
1194         local RUN_TIME2=10
1195         do_facet $SINGLEMDS \
1196                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1197         sleep $RUN_TIME2
1198
1199         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
1200         # MIN_MARGIN = 0.7 = 7 / 10
1201         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
1202                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
1203                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1204         [ $SPEED -gt $MIN_SPEED ] || {
1205                 if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
1206                         error_ignore LU-5624 \
1207                         "(9.1) Got speed $SPEED, expected more than $MIN_SPEED"
1208                 else
1209                         error \
1210                         "(9.2) Got speed $SPEED, expected more than $MIN_SPEED"
1211                 fi
1212         }
1213
1214         # MAX_MARGIN = 1.3 = 13 / 10
1215         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
1216                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
1217                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1218         [ $SPEED -lt $MAX_SPEED ] || {
1219                 $SHOW_NAMESPACE
1220                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1221                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1222                 error "(10) Speed $SPEED, expected < $MAX_SPEED"
1223         }
1224
1225         do_nodes $(comma_list $(mdts_nodes)) \
1226                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1227         do_nodes $(comma_list $(osts_nodes)) \
1228                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1229         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1230                 mdd.${MDT_DEV}.lfsck_namespace |
1231                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1232                 $SHOW_NAMESPACE
1233                 error "(11) unexpected status"
1234         }
1235 }
1236 run_test 9b "LFSCK speed control (2)"
1237
1238 test_10()
1239 {
1240         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
1241                 skip "lookup(..)/linkea on ZFS issue" && return
1242
1243         lfsck_prep 1 1
1244
1245         echo "Preparing more files with error at $(date)."
1246         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
1247         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
1248
1249         for ((i = 0; i < 1000; i = $((i+2)))); do
1250                 mkdir -p $DIR/$tdir/d${i}
1251                 touch $DIR/$tdir/f${i}
1252                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1253         done
1254
1255         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1256         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1257
1258         for ((i = 1; i < 1000; i = $((i+2)))); do
1259                 mkdir -p $DIR/$tdir/d${i}
1260                 touch $DIR/$tdir/f${i}
1261                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1262         done
1263
1264         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1265         echo "Prepared at $(date)."
1266
1267         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
1268
1269         umount_client $MOUNT
1270         mount_client $MOUNT || error "(3) Fail to start client!"
1271
1272         $START_NAMESPACE -r -s 100 || error "(5) Fail to start LFSCK!"
1273
1274         sleep 10
1275         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1276         [ "$STATUS" == "scanning-phase1" ] ||
1277                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
1278
1279         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
1280
1281         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
1282
1283         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
1284
1285         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
1286
1287         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
1288
1289         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
1290
1291         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
1292
1293         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
1294                 error "(14) Fail to softlink!"
1295
1296         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1297         [ "$STATUS" == "scanning-phase1" ] ||
1298                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
1299
1300         do_nodes $(comma_list $(mdts_nodes)) \
1301                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1302         do_nodes $(comma_list $(osts_nodes)) \
1303                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1304         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1305                 mdd.${MDT_DEV}.lfsck_namespace |
1306                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1307                 $SHOW_NAMESPACE
1308                 error "(16) unexpected status"
1309         }
1310 }
1311 run_test 10 "System is available during LFSCK scanning"
1312
1313 # remove LAST_ID
1314 ost_remove_lastid() {
1315         local ost=$1
1316         local idx=$2
1317         local rcmd="do_facet ost${ost}"
1318
1319         echo "remove LAST_ID on ost${ost}: idx=${idx}"
1320
1321         # step 1: local mount
1322         mount_fstype ost${ost} || return 1
1323         # step 2: remove the specified LAST_ID
1324         ${rcmd} rm -fv $(facet_mntpt ost${ost})/O/${idx}/{LAST_ID,d0/0}
1325         # step 3: umount
1326         unmount_fstype ost${ost} || return 2
1327 }
1328
1329 test_11a() {
1330         check_mount_and_prep
1331         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1332         createmany -o $DIR/$tdir/f 64 || error "(0) Fail to create 64 files."
1333
1334         echo "stopall"
1335         stopall > /dev/null
1336
1337         ost_remove_lastid 1 0 || error "(1) Fail to remove LAST_ID"
1338
1339         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
1340                 error "(2) Fail to start ost1"
1341
1342         #define OBD_FAIL_LFSCK_DELAY4           0x160e
1343         do_facet ost1 $LCTL set_param fail_val=3 fail_loc=0x160e
1344
1345         echo "trigger LFSCK for layout on ost1 to rebuild the LAST_ID(s)"
1346         $START_LAYOUT_ON_OST -r || error "(4) Fail to start LFSCK on OST!"
1347
1348         wait_update_facet ost1 "$LCTL get_param -n \
1349                 obdfilter.${OST_DEV}.lfsck_layout |
1350                 awk '/^flags/ { print \\\$2 }'" "crashed_lastid" 60 || {
1351                 $SHOW_LAYOUT_ON_OST
1352                 error "(5) unexpected status"
1353         }
1354
1355         do_facet ost1 $LCTL set_param fail_val=0 fail_loc=0
1356
1357         wait_update_facet ost1 "$LCTL get_param -n \
1358                 obdfilter.${OST_DEV}.lfsck_layout |
1359                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1360                 $SHOW_LAYOUT_ON_OST
1361                 error "(6) unexpected status"
1362         }
1363
1364         echo "the LAST_ID(s) should have been rebuilt"
1365         FLAGS=$($SHOW_LAYOUT_ON_OST | awk '/^flags/ { print $2 }')
1366         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
1367 }
1368 run_test 11a "LFSCK can rebuild lost last_id"
1369
1370 test_11b() {
1371         check_mount_and_prep
1372         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1373
1374         echo "set fail_loc=0x160d to skip the updating LAST_ID on-disk"
1375         #define OBD_FAIL_LFSCK_SKIP_LASTID      0x160d
1376         do_facet ost1 $LCTL set_param fail_loc=0x160d
1377
1378         local count=$(precreated_ost_obj_count 0 0)
1379
1380         createmany -o $DIR/$tdir/f $((count + 32))
1381
1382         local proc_path="${FSNAME}-OST0000-osc-MDT0000"
1383         local seq=$(do_facet mds1 $LCTL get_param -n \
1384                     osp.${proc_path}.prealloc_last_seq)
1385         local lastid1=$(do_facet ost1 "lctl get_param -n \
1386                 obdfilter.${ost1_svc}.last_id" | grep $seq |
1387                 awk -F: '{ print $2 }')
1388
1389         umount_client $MOUNT
1390         stop ost1 || error "(1) Fail to stop ost1"
1391
1392         #define OBD_FAIL_OST_ENOSPC              0x215
1393         do_facet ost1 $LCTL set_param fail_loc=0x215
1394
1395         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1396                 error "(2) Fail to start ost1"
1397
1398         for ((i = 0; i < 60; i++)); do
1399                 lastid2=$(do_facet ost1 "lctl get_param -n \
1400                         obdfilter.${ost1_svc}.last_id" | grep $seq |
1401                         awk -F: '{ print $2 }')
1402                 [ ! -z $lastid2 ] && break;
1403                 sleep 1
1404         done
1405
1406         echo "the on-disk LAST_ID should be smaller than the expected one"
1407         [ $lastid1 -gt $lastid2 ] ||
1408                 error "(4) expect lastid1 [ $lastid1 ] > lastid2 [ $lastid2 ]"
1409
1410         echo "trigger LFSCK for layout on ost1 to rebuild the on-disk LAST_ID"
1411         $START_LAYOUT_ON_OST -r || error "(5) Fail to start LFSCK on OST!"
1412
1413         wait_update_facet ost1 "$LCTL get_param -n \
1414                 obdfilter.${OST_DEV}.lfsck_layout |
1415                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1416                 $SHOW_LAYOUT_ON_OST
1417                 error "(6) unexpected status"
1418         }
1419
1420         stop ost1 || error "(7) Fail to stop ost1"
1421
1422         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1423                 error "(8) Fail to start ost1"
1424
1425         echo "the on-disk LAST_ID should have been rebuilt"
1426         wait_update_facet ost1 "$LCTL get_param -n \
1427                 obdfilter.${ost1_svc}.last_id | grep $seq |
1428                 awk -F: '{ print \\\$2 }'" "$lastid1" 60 || {
1429                 do_facet ost1 $LCTL get_param -n \
1430                 obdfilter.${ost1_svc}.last_id
1431                 error "(9) expect lastid1 $seq:$lastid1"
1432         }
1433
1434         do_facet ost1 $LCTL set_param fail_loc=0
1435         stopall || error "(10) Fail to stopall"
1436 }
1437 run_test 11b "LFSCK can rebuild crashed last_id"
1438
1439 test_12a() {
1440         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1441
1442         check_mount_and_prep
1443         for k in $(seq $MDSCOUNT); do
1444                 $LFS mkdir -i $((k - 1)) $DIR/$tdir/${k}
1445                 createmany -o $DIR/$tdir/${k}/f 100 ||
1446                         error "(0) Fail to create 100 files."
1447         done
1448
1449         echo "Start namespace LFSCK on all targets by single command (-s 1)."
1450         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1451                 -s 1 -r || error "(2) Fail to start LFSCK on all devices!"
1452
1453         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1454         wait_all_targets namespace scanning-phase1 3
1455
1456         echo "Stop namespace LFSCK on all targets by single lctl command."
1457         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1458                 error "(4) Fail to stop LFSCK on all devices!"
1459
1460         echo "All the LFSCK targets should be in 'stopped' status."
1461         wait_all_targets_blocked namespace stopped 5
1462
1463         echo "Re-start namespace LFSCK on all targets by single command (-s 0)."
1464         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1465                 -s 0 -r || error "(6) Fail to start LFSCK on all devices!"
1466
1467         echo "All the LFSCK targets should be in 'completed' status."
1468         wait_all_targets_blocked namespace completed 7
1469
1470         start_full_debug_logging
1471
1472         echo "Start layout LFSCK on all targets by single command (-s 1)."
1473         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1474                 -s 1 -r || error "(8) Fail to start LFSCK on all devices!"
1475
1476         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1477         wait_all_targets layout scanning-phase1 9
1478
1479         echo "Stop layout LFSCK on all targets by single lctl command."
1480         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1481                 error "(10) Fail to stop LFSCK on all devices!"
1482
1483         echo "All the LFSCK targets should be in 'stopped' status."
1484         wait_all_targets_blocked layout stopped 11
1485
1486         for k in $(seq $OSTCOUNT); do
1487                 local STATUS=$(do_facet ost${k} $LCTL get_param -n \
1488                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1489                                 awk '/^status/ { print $2 }')
1490                 [ "$STATUS" == "stopped" ] ||
1491                         error "(12) OST${k} Expect 'stopped', but got '$STATUS'"
1492         done
1493
1494         echo "Re-start layout LFSCK on all targets by single command (-s 0)."
1495         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1496                 -s 0 -r || error "(13) Fail to start LFSCK on all devices!"
1497
1498         echo "All the LFSCK targets should be in 'completed' status."
1499         wait_all_targets_blocked layout completed 14
1500
1501         stop_full_debug_logging
1502 }
1503 run_test 12a "single command to trigger LFSCK on all devices"
1504
1505 test_12b() {
1506         check_mount_and_prep
1507
1508         echo "Start LFSCK without '-M' specified."
1509         do_facet mds1 $LCTL lfsck_start -A -r ||
1510                 error "(0) Fail to start LFSCK without '-M'"
1511
1512         wait_all_targets_blocked namespace completed 1
1513         wait_all_targets_blocked layout completed 2
1514
1515         local count=$(do_facet mds1 $LCTL dl |
1516                       awk '{ print $3 }' | grep mdt | wc -l)
1517         if [ $count -gt 1 ]; then
1518                 echo
1519                 echo "Start layout LFSCK on the node with multipe targets,"
1520                 echo "but not specify '-M'/'-A' option. Should get failure."
1521                 echo
1522                 do_facet mds1 $LCTL lfsck_start -t layout -r &&
1523                         error "(3) Start layout LFSCK should fail" || true
1524         fi
1525 }
1526 run_test 12b "auto detect Lustre device"
1527
1528 test_13() {
1529         echo "#####"
1530         echo "The lmm_oi in layout EA should be consistent with the MDT-object"
1531         echo "FID; otherwise, the LFSCK should re-generate the lmm_oi from the"
1532         echo "MDT-object FID."
1533         echo "#####"
1534
1535         check_mount_and_prep
1536
1537         echo "Inject failure stub to simulate bad lmm_oi"
1538         #define OBD_FAIL_LFSCK_BAD_LMMOI        0x160f
1539         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160f
1540         createmany -o $DIR/$tdir/f 1
1541         $LFS setstripe -E 1M -S 1M -E -1 $DIR/$tdir/f1 ||
1542                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1543         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1544
1545         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
1546         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1547
1548         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1549                 mdd.${MDT_DEV}.lfsck_layout |
1550                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1551                 $SHOW_LAYOUT
1552                 error "(2) unexpected status"
1553         }
1554
1555         local repaired=$($SHOW_LAYOUT |
1556                          awk '/^repaired_others/ { print $2 }')
1557         [ $repaired -eq 2 ] ||
1558                 error "(3) Fail to repair crashed lmm_oi: $repaired"
1559 }
1560 run_test 13 "LFSCK can repair crashed lmm_oi"
1561
1562 test_14a() {
1563         echo "#####"
1564         echo "The OST-object referenced by the MDT-object should be there;"
1565         echo "otherwise, the LFSCK should re-create the missing OST-object."
1566         echo "without '--delay-create-ostobj' option."
1567         echo "#####"
1568
1569         check_mount_and_prep
1570         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1571
1572         echo "Inject failure stub to simulate dangling referenced MDT-object"
1573         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1574         do_facet ost1 $LCTL set_param fail_loc=0x1610
1575         local count=$(precreated_ost_obj_count 0 0)
1576
1577         createmany -o $DIR/$tdir/f $((count + 16)) ||
1578                 error "(0.1) Fail to create $DIR/$tdir/fx"
1579         touch $DIR/$tdir/guard0
1580
1581         for ((i = 0; i < 16; i++)); do
1582                 $LFS setstripe -E 512K -S 256K -o 0 -E 2M \
1583                         $DIR/$tdir/f_comp${i} ||
1584                         error "(0.2) Fail to create $DIR/$tdir/f_comp${i}"
1585         done
1586         touch $DIR/$tdir/guard1
1587
1588         do_facet ost1 $LCTL set_param fail_loc=0
1589
1590         start_full_debug_logging
1591
1592         # exhaust other pre-created dangling cases
1593         count=$(precreated_ost_obj_count 0 0)
1594         createmany -o $DIR/$tdir/a $count ||
1595                 error "(0.5) Fail to create $count files."
1596
1597         echo "'ls' should fail because of dangling referenced MDT-object"
1598         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1599
1600         echo "Trigger layout LFSCK to find out dangling reference"
1601         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1602
1603         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1604                 mdd.${MDT_DEV}.lfsck_layout |
1605                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1606                 $SHOW_LAYOUT
1607                 error "(3) unexpected status"
1608         }
1609
1610         local repaired=$($SHOW_LAYOUT |
1611                          awk '/^repaired_dangling/ { print $2 }')
1612         [ $repaired -ge 32 ] ||
1613                 error "(4) Fail to repair dangling reference: $repaired"
1614
1615         echo "'stat' should fail because of not repair dangling by default"
1616         stat $DIR/$tdir/guard0 > /dev/null 2>&1 &&
1617                 error "(5.1) stat should fail"
1618         stat $DIR/$tdir/guard1 > /dev/null 2>&1 &&
1619                 error "(5.2) stat should fail"
1620
1621         echo "Trigger layout LFSCK to repair dangling reference"
1622         $START_LAYOUT -r -c || error "(6) Fail to start LFSCK for layout!"
1623
1624         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1625                 mdd.${MDT_DEV}.lfsck_layout |
1626                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1627                 $SHOW_LAYOUT
1628                 error "(7) unexpected status"
1629         }
1630
1631         # There may be some async LFSCK updates in processing, wait for
1632         # a while until the target reparation has been done. LU-4970.
1633
1634         echo "'stat' should success after layout LFSCK repairing"
1635         wait_update_facet client "stat $DIR/$tdir/guard0 |
1636                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1637                 stat $DIR/$tdir/guard0
1638                 $SHOW_LAYOUT
1639                 error "(8.1) unexpected size"
1640         }
1641
1642         wait_update_facet client "stat $DIR/$tdir/guard1 |
1643                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1644                 stat $DIR/$tdir/guard1
1645                 $SHOW_LAYOUT
1646                 error "(8.2) unexpected size"
1647         }
1648
1649         repaired=$($SHOW_LAYOUT |
1650                          awk '/^repaired_dangling/ { print $2 }')
1651         [ $repaired -ge 32 ] ||
1652                 error "(9) Fail to repair dangling reference: $repaired"
1653
1654         stop_full_debug_logging
1655
1656         echo "stopall to cleanup object cache"
1657         stopall > /dev/null
1658         echo "setupall"
1659         setupall > /dev/null
1660 }
1661 run_test 14a "LFSCK can repair MDT-object with dangling LOV EA reference (1)"
1662
1663 test_14b() {
1664         echo "#####"
1665         echo "The OST-object referenced by the MDT-object should be there;"
1666         echo "otherwise, the LFSCK should re-create the missing OST-object."
1667         echo "with '--delay-create-ostobj' option."
1668         echo "#####"
1669
1670         check_mount_and_prep
1671         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1672
1673         echo "Inject failure stub to simulate dangling referenced MDT-object"
1674         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1675         do_facet ost1 $LCTL set_param fail_loc=0x1610
1676         local count=$(precreated_ost_obj_count 0 0)
1677
1678         createmany -o $DIR/$tdir/f $((count + 31))
1679         touch $DIR/$tdir/guard
1680         do_facet ost1 $LCTL set_param fail_loc=0
1681
1682         start_full_debug_logging
1683
1684         # exhaust other pre-created dangling cases
1685         count=$(precreated_ost_obj_count 0 0)
1686         createmany -o $DIR/$tdir/a $count ||
1687                 error "(0) Fail to create $count files."
1688
1689         echo "'ls' should fail because of dangling referenced MDT-object"
1690         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1691
1692         echo "Trigger layout LFSCK to find out dangling reference"
1693         $START_LAYOUT -r -o -d || error "(2) Fail to start LFSCK for layout!"
1694
1695         wait_all_targets_blocked layout completed 3
1696
1697         local repaired=$($SHOW_LAYOUT |
1698                          awk '/^repaired_dangling/ { print $2 }')
1699         [ $repaired -ge 32 ] ||
1700                 error "(4) Fail to repair dangling reference: $repaired"
1701
1702         echo "'stat' should fail because of not repair dangling by default"
1703         stat $DIR/$tdir/guard > /dev/null 2>&1 && error "(5) stat should fail"
1704
1705         echo "Trigger layout LFSCK to repair dangling reference"
1706         $START_LAYOUT -r -o -c -d || error "(6) Fail to start LFSCK for layout!"
1707
1708         wait_all_targets_blocked layout completed 7
1709
1710         # There may be some async LFSCK updates in processing, wait for
1711         # a while until the target reparation has been done. LU-4970.
1712
1713         echo "'stat' should success after layout LFSCK repairing"
1714         wait_update_facet client "stat $DIR/$tdir/guard |
1715                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1716                 stat $DIR/$tdir/guard
1717                 $SHOW_LAYOUT
1718                 error "(8) unexpected size"
1719         }
1720
1721         repaired=$($SHOW_LAYOUT |
1722                          awk '/^repaired_dangling/ { print $2 }')
1723         [ $repaired -ge 32 ] ||
1724                 error "(9) Fail to repair dangling reference: $repaired"
1725
1726         stop_full_debug_logging
1727
1728         echo "stopall to cleanup object cache"
1729         stopall > /dev/null
1730         echo "setupall"
1731         setupall > /dev/null
1732 }
1733 run_test 14b "LFSCK can repair MDT-object with dangling LOV EA reference (2)"
1734
1735 test_15a() {
1736         echo "#####"
1737         echo "If the OST-object referenced by the MDT-object back points"
1738         echo "to some non-exist MDT-object, then the LFSCK should repair"
1739         echo "the OST-object to back point to the right MDT-object."
1740         echo "#####"
1741
1742         check_mount_and_prep
1743         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1744
1745         echo "Inject failure stub to make the OST-object to back point to"
1746         echo "non-exist MDT-object."
1747         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
1748
1749         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
1750         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1751         $LFS setstripe -E 1M -S 256K -c 1 -E -1 -S 512K -c $OSTCOUNT \
1752                 $DIR/$tdir/f1 ||
1753                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1754         # 'dd' will trigger punch RPC firstly on every OST-objects.
1755         # So even though some OST-object will not be write by 'dd',
1756         # as long as it is allocated (may be NOT allocated in pfl_3b)
1757         # its layout information will be set also.
1758         dd if=/dev/zero of=$DIR/$tdir/f1 bs=4K count=257
1759         cancel_lru_locks osc
1760         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1761
1762         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1763         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1764
1765         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1766                 mdd.${MDT_DEV}.lfsck_layout |
1767                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1768                 $SHOW_LAYOUT
1769                 error "(2) unexpected status"
1770         }
1771
1772         local repaired=$($SHOW_LAYOUT |
1773                          awk '/^repaired_unmatched_pair/ { print $2 }')
1774         [ $repaired -ge 3 ] ||
1775                 error "(3) Fail to repair unmatched pair: $repaired"
1776 }
1777 run_test 15a "LFSCK can repair unmatched MDT-object/OST-object pairs (1)"
1778
1779 test_15b() {
1780         echo "#####"
1781         echo "If the OST-object referenced by the MDT-object back points"
1782         echo "to other MDT-object that doesn't recognize the OST-object,"
1783         echo "then the LFSCK should repair it to back point to the right"
1784         echo "MDT-object (the first one)."
1785         echo "#####"
1786
1787         check_mount_and_prep
1788         mkdir -p $DIR/$tdir/0
1789         $LFS setstripe -c 1 -i 0 $DIR/$tdir/0
1790         dd if=/dev/zero of=$DIR/$tdir/0/guard bs=1M count=1
1791         cancel_lru_locks osc
1792
1793         echo "Inject failure stub to make the OST-object to back point to"
1794         echo "other MDT-object"
1795
1796         local stripes=1
1797         [ $OSTCOUNT -ge 2 ] && stripes=2
1798
1799         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR2  0x1612
1800         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1612
1801         dd if=/dev/zero of=$DIR/$tdir/0/f0 bs=1M count=1
1802         $LFS setstripe -E 1M -S 256K -c $stripes -E 2M -S 512K -c 1 \
1803                 $DIR/$tdir/f1 ||
1804                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1805         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2
1806         cancel_lru_locks osc
1807         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1808
1809         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1810         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1811
1812         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1813                 mdd.${MDT_DEV}.lfsck_layout |
1814                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1815                 $SHOW_LAYOUT
1816                 error "(2) unexpected status"
1817         }
1818
1819         local repaired=$($SHOW_LAYOUT |
1820                          awk '/^repaired_unmatched_pair/ { print $2 }')
1821         [ $repaired -eq 4 ] ||
1822                 error "(3) Fail to repair unmatched pair: $repaired"
1823 }
1824 run_test 15b "LFSCK can repair unmatched MDT-object/OST-object pairs (2)"
1825
1826 test_15c() {
1827         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
1828
1829         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.7.55) ] &&
1830                 skip "Skip the test after 2.7.55 see LU-6437" && return
1831
1832         echo "#####"
1833         echo "According to current metadata migration implementation,"
1834         echo "before the old MDT-object is removed, both the new MDT-object"
1835         echo "and old MDT-object will reference the same LOV layout. Then if"
1836         echo "the layout LFSCK finds the new MDT-object by race, it will"
1837         echo "regard related OST-object(s) as multiple referenced case, and"
1838         echo "will try to create new OST-object(s) for the new MDT-object."
1839         echo "To avoid such trouble, the layout LFSCK needs to lock the old"
1840         echo "MDT-object before confirm the multiple referenced case."
1841         echo "#####"
1842
1843         check_mount_and_prep
1844         $LFS mkdir -i 1 $DIR/$tdir/a1
1845         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
1846         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=1
1847         cancel_lru_locks osc
1848
1849         echo "Inject failure stub on MDT1 to delay the migration"
1850
1851         #define OBD_FAIL_MIGRATE_DELAY                  0x1803
1852         do_facet mds2 $LCTL set_param fail_val=5 fail_loc=0x1803
1853         echo "Migrate $DIR/$tdir/a1 from MDT1 to MDT0 with delay"
1854         $LFS migrate -m 0 $DIR/$tdir/a1 &
1855
1856         sleep 1
1857         echo "Trigger layout LFSCK to race with the migration"
1858         $START_LAYOUT -A -r || error "(1) Fail to start layout LFSCK!"
1859
1860         wait_all_targets_blocked layout completed 2
1861
1862         do_facet mds2 $LCTL set_param fail_loc=0 fail_val=0
1863         local repaired=$($SHOW_LAYOUT |
1864                          awk '/^repaired_unmatched_pair/ { print $2 }')
1865         [ $repaired -eq 1 ] ||
1866                 error "(3) Fail to repair unmatched pair: $repaired"
1867
1868         repaired=$($SHOW_LAYOUT |
1869                    awk '/^repaired_multiple_referenced/ { print $2 }')
1870         [ $repaired -eq 0 ] ||
1871                 error "(4) Unexpectedly repaird multiple references: $repaired"
1872 }
1873 run_test 15c "LFSCK can repair unmatched MDT-object/OST-object pairs (3)"
1874
1875 test_16() {
1876         echo "#####"
1877         echo "If the OST-object's owner information does not match the owner"
1878         echo "information stored in the MDT-object, then the LFSCK trust the"
1879         echo "MDT-object and update the OST-object's owner information."
1880         echo "#####"
1881
1882         check_mount_and_prep
1883         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1884         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1885         cancel_lru_locks osc
1886
1887         # created but no setattr or write to the file.
1888         mkdir $DIR/$tdir/d1
1889         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/d1
1890         $RUNAS createmany -o $DIR/$tdir/d1/o 100 || error "create failed"
1891
1892         echo "Inject failure stub to skip OST-object owner changing"
1893         #define OBD_FAIL_LFSCK_BAD_OWNER        0x1613
1894         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1613
1895         chown 1.1 $DIR/$tdir/f0
1896         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1897
1898         echo "Trigger layout LFSCK to find out inconsistent OST-object owner"
1899         echo "and fix them"
1900
1901         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1902
1903         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1904                 mdd.${MDT_DEV}.lfsck_layout |
1905                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1906                 $SHOW_LAYOUT
1907                 error "(2) unexpected status"
1908         }
1909
1910         local repaired=$($SHOW_LAYOUT |
1911                          awk '/^repaired_inconsistent_owner/ { print $2 }')
1912         [ $repaired -eq 1 ] ||
1913                 error "(3) Fail to repair inconsistent owner: $repaired"
1914 }
1915 run_test 16 "LFSCK can repair inconsistent MDT-object/OST-object owner"
1916
1917 test_17() {
1918         echo "#####"
1919         echo "If more than one MDT-objects reference the same OST-object,"
1920         echo "and the OST-object only recognizes one MDT-object, then the"
1921         echo "LFSCK should create new OST-objects for such non-recognized"
1922         echo "MDT-objects."
1923         echo "#####"
1924
1925         check_mount_and_prep
1926         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1927
1928         echo "Inject failure stub to make two MDT-objects to refernce"
1929         echo "the OST-object"
1930
1931         #define OBD_FAIL_LFSCK_MULTIPLE_REF     0x1614
1932         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0x1614
1933         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
1934         cancel_lru_locks mdc
1935         cancel_lru_locks osc
1936
1937         createmany -o $DIR/$tdir/f 1
1938         cancel_lru_locks mdc
1939         cancel_lru_locks osc
1940
1941         $LFS setstripe -E 2M -S 256K -o 0 -E 4M -S 512K -o 0 \
1942                 $DIR/$tdir/f1 ||
1943                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1944         cancel_lru_locks mdc
1945         cancel_lru_locks osc
1946         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1947
1948         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard use the same OST-objects"
1949         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard use the same OST-objects"
1950         local size=$(ls -l $DIR/$tdir/f0 | awk '{ print $5 }')
1951         [ $size -eq 1048576 ] ||
1952                 error "(1.1) f0 (wrong) size should be 1048576, but got $size"
1953
1954         size=$(ls -l $DIR/$tdir/f1 | awk '{ print $5 }')
1955         [ $size -eq 1048576 ] ||
1956                 error "(1.2) f1 (wrong) size should be 1048576, but got $size"
1957
1958         echo "Trigger layout LFSCK to find out multiple refenced MDT-objects"
1959         echo "and fix them"
1960
1961         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1962
1963         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1964                 mdd.${MDT_DEV}.lfsck_layout |
1965                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1966                 $SHOW_LAYOUT
1967                 error "(3) unexpected status"
1968         }
1969
1970         local repaired=$($SHOW_LAYOUT |
1971                          awk '/^repaired_multiple_referenced/ { print $2 }')
1972         [ $repaired -eq 2 ] ||
1973                 error "(4) Fail to repair multiple references: $repaired"
1974
1975         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard should use diff OST-objects"
1976         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=2 ||
1977                 error "(5) Fail to write f0."
1978         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
1979         [ $size -eq 1048576 ] ||
1980                 error "(6) guard size should be 1048576, but got $size"
1981
1982         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard should use diff OST-objects"
1983         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2 ||
1984                 error "(7) Fail to write f1."
1985         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
1986         [ $size -eq 1048576 ] ||
1987                 error "(8) guard size should be 1048576, but got $size"
1988 }
1989 run_test 17 "LFSCK can repair multiple references"
1990
1991 $LCTL set_param debug=+cache > /dev/null
1992
1993 test_18a() {
1994         echo "#####"
1995         echo "The target MDT-object is there, but related stripe information"
1996         echo "is lost or partly lost. The LFSCK should regenerate the missing"
1997         echo "layout EA entries."
1998         echo "#####"
1999
2000         check_mount_and_prep
2001         $LFS mkdir -i 0 $DIR/$tdir/a1
2002         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2003         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2004
2005         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2006
2007         $LFS path2fid $DIR/$tdir/a1/f1
2008         $LFS getstripe $DIR/$tdir/a1/f1
2009
2010         if [ $MDSCOUNT -ge 2 ]; then
2011                 $LFS mkdir -i 1 $DIR/$tdir/a2
2012                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2013                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2014                 $LFS path2fid $DIR/$tdir/a2/f2
2015                 $LFS getstripe $DIR/$tdir/a2/f2
2016         fi
2017
2018         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2019                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2020
2021         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2022
2023         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2024
2025         $LFS path2fid $DIR/$tdir/f3
2026         $LFS getstripe $DIR/$tdir/f3
2027
2028         cancel_lru_locks osc
2029
2030         echo "Inject failure, to make the MDT-object lost its layout EA"
2031         #define OBD_FAIL_LFSCK_LOST_STRIPE 0x1615
2032         do_facet mds1 $LCTL set_param fail_loc=0x1615
2033         chown 1.1 $DIR/$tdir/a1/f1
2034
2035         if [ $MDSCOUNT -ge 2 ]; then
2036                 do_facet mds2 $LCTL set_param fail_loc=0x1615
2037                 chown 1.1 $DIR/$tdir/a2/f2
2038         fi
2039
2040         chown 1.1 $DIR/$tdir/f3
2041
2042         sync
2043         sleep 2
2044
2045         do_facet mds1 $LCTL set_param fail_loc=0
2046         if [ $MDSCOUNT -ge 2 ]; then
2047                 do_facet mds2 $LCTL set_param fail_loc=0
2048         fi
2049
2050         cancel_lru_locks mdc
2051         cancel_lru_locks osc
2052
2053         echo "The file size should be incorrect since layout EA is lost"
2054         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2055         [ "$cur_size" != "$saved_size1" ] ||
2056                 error "(1) Expect incorrect file1 size"
2057
2058         if [ $MDSCOUNT -ge 2 ]; then
2059                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2060                 [ "$cur_size" != "$saved_size1" ] ||
2061                         error "(2) Expect incorrect file2 size"
2062         fi
2063
2064         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2065         [ "$cur_size" != "$saved_size2" ] ||
2066                 error "(1.2) Expect incorrect file3 size"
2067
2068         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2069         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
2070
2071         for k in $(seq $MDSCOUNT); do
2072                 # The LFSCK status query internal is 30 seconds. For the case
2073                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2074                 # time to guarantee the status sync up.
2075                 wait_update_facet mds${k} "$LCTL get_param -n \
2076                         mdd.$(facet_svc mds${k}).lfsck_layout |
2077                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2078                         error "(4) MDS${k} is not the expected 'completed'"
2079         done
2080
2081         for k in $(seq $OSTCOUNT); do
2082                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2083                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2084                                 awk '/^status/ { print $2 }')
2085                 [ "$cur_status" == "completed" ] ||
2086                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2087         done
2088
2089         local repaired=$(do_facet mds1 $LCTL get_param -n \
2090                          mdd.$(facet_svc mds1).lfsck_layout |
2091                          awk '/^repaired_orphan/ { print $2 }')
2092         [ $repaired -eq 3 ] ||
2093         error "(6.1) Expect 3 fixed on mds1, but got: $repaired"
2094
2095         if [ $MDSCOUNT -ge 2 ]; then
2096                 repaired=$(do_facet mds2 $LCTL get_param -n \
2097                          mdd.$(facet_svc mds2).lfsck_layout |
2098                                  awk '/^repaired_orphan/ { print $2 }')
2099                 [ $repaired -eq 2 ] ||
2100                 error "(6.2) Expect 2 fixed on mds2, but got: $repaired"
2101         fi
2102
2103         $LFS path2fid $DIR/$tdir/a1/f1
2104         $LFS getstripe $DIR/$tdir/a1/f1
2105
2106         if [ $MDSCOUNT -ge 2 ]; then
2107                 $LFS path2fid $DIR/$tdir/a2/f2
2108                 $LFS getstripe $DIR/$tdir/a2/f2
2109         fi
2110
2111         $LFS path2fid $DIR/$tdir/f3
2112         $LFS getstripe $DIR/$tdir/f3
2113
2114         echo "The file size should be correct after layout LFSCK scanning"
2115         cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2116         [ "$cur_size" == "$saved_size1" ] ||
2117                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2118
2119         if [ $MDSCOUNT -ge 2 ]; then
2120                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2121                 [ "$cur_size" == "$saved_size1" ] ||
2122                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2123         fi
2124
2125         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2126         [ "$cur_size" == "$saved_size2" ] ||
2127                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2128 }
2129 run_test 18a "Find out orphan OST-object and repair it (1)"
2130
2131 test_18b() {
2132         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2133
2134         echo "#####"
2135         echo "The target MDT-object is lost. The LFSCK should re-create the"
2136         echo "MDT-object under .lustre/lost+found/MDTxxxx. The admin should"
2137         echo "can move it back to normal namespace manually."
2138         echo "#####"
2139
2140         check_mount_and_prep
2141         $LFS mkdir -i 0 $DIR/$tdir/a1
2142         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2143         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2144         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2145         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2146         echo ${fid1}
2147         $LFS getstripe $DIR/$tdir/a1/f1
2148
2149         if [ $MDSCOUNT -ge 2 ]; then
2150                 $LFS mkdir -i 1 $DIR/$tdir/a2
2151                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2152                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2153                 fid2=$($LFS path2fid $DIR/$tdir/a2/f2)
2154                 echo ${fid2}
2155                 $LFS getstripe $DIR/$tdir/a2/f2
2156         fi
2157
2158         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2159                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2160
2161         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2162
2163         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2164         local fid3=$($LFS path2fid $DIR/$tdir/f3)
2165         echo ${fid3}
2166         $LFS getstripe $DIR/$tdir/f3
2167
2168         cancel_lru_locks osc
2169
2170         echo "Inject failure, to simulate the case of missing the MDT-object"
2171         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2172         do_facet mds1 $LCTL set_param fail_loc=0x1616
2173         rm -f $DIR/$tdir/a1/f1
2174
2175         if [ $MDSCOUNT -ge 2 ]; then
2176                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2177                 rm -f $DIR/$tdir/a2/f2
2178         fi
2179
2180         rm -f $DIR/$tdir/f3
2181
2182         sync
2183         sleep 2
2184
2185         do_facet mds1 $LCTL set_param fail_loc=0
2186         if [ $MDSCOUNT -ge 2 ]; then
2187                 do_facet mds2 $LCTL set_param fail_loc=0
2188         fi
2189
2190         cancel_lru_locks mdc
2191         cancel_lru_locks osc
2192
2193         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2194         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2195
2196         for k in $(seq $MDSCOUNT); do
2197                 # The LFSCK status query internal is 30 seconds. For the case
2198                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2199                 # time to guarantee the status sync up.
2200                 wait_update_facet mds${k} "$LCTL get_param -n \
2201                         mdd.$(facet_svc mds${k}).lfsck_layout |
2202                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2203                         error "(2) MDS${k} is not the expected 'completed'"
2204         done
2205
2206         for k in $(seq $OSTCOUNT); do
2207                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2208                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2209                                 awk '/^status/ { print $2 }')
2210                 [ "$cur_status" == "completed" ] ||
2211                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2212         done
2213
2214         local repaired=$(do_facet mds1 $LCTL get_param -n \
2215                          mdd.$(facet_svc mds1).lfsck_layout |
2216                          awk '/^repaired_orphan/ { print $2 }')
2217         [ $repaired -eq 3 ] ||
2218         error "(4.1) Expect 3 fixed on mds1, but got: $repaired"
2219
2220         if [ $MDSCOUNT -ge 2 ]; then
2221                 repaired=$(do_facet mds2 $LCTL get_param -n \
2222                          mdd.$(facet_svc mds2).lfsck_layout |
2223                          awk '/^repaired_orphan/ { print $2 }')
2224                 [ $repaired -eq 2 ] ||
2225                 error "(4.2) Expect 2 fixed on mds2, but got: $repaired"
2226         fi
2227
2228         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2229         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2230         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2231
2232         if [ $MDSCOUNT -ge 2 ]; then
2233                 local name=$MOUNT/.lustre/lost+found/MDT0001/${fid2}-R-0
2234                 mv $name $DIR/$tdir/a2/f2 || error "(6) Fail to move $name"
2235         fi
2236
2237         mv $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0 $DIR/$tdir/f3 ||
2238         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
2239
2240         $LFS path2fid $DIR/$tdir/a1/f1
2241         $LFS getstripe $DIR/$tdir/a1/f1
2242
2243         if [ $MDSCOUNT -ge 2 ]; then
2244                 $LFS path2fid $DIR/$tdir/a2/f2
2245                 $LFS getstripe $DIR/$tdir/a2/f2
2246         fi
2247
2248         $LFS path2fid $DIR/$tdir/f3
2249         $LFS getstripe $DIR/$tdir/f3
2250
2251         echo "The file size should be correct after layout LFSCK scanning"
2252         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2253         [ "$cur_size" == "$saved_size1" ] ||
2254                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2255
2256         if [ $MDSCOUNT -ge 2 ]; then
2257                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2258                 [ "$cur_size" == "$saved_size1" ] ||
2259                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2260         fi
2261
2262         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2263         [ "$cur_size" == "$saved_size2" ] ||
2264                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2265 }
2266 run_test 18b "Find out orphan OST-object and repair it (2)"
2267
2268 test_18c() {
2269         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2270
2271         echo "#####"
2272         echo "The target MDT-object is lost, and the OST-object FID is missing."
2273         echo "The LFSCK should re-create the MDT-object with new FID under the "
2274         echo "directory .lustre/lost+found/MDTxxxx."
2275         echo "#####"
2276
2277         check_mount_and_prep
2278         $LFS mkdir -i 0 $DIR/$tdir/a1
2279         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2280
2281         echo "Inject failure, to simulate the case of missing parent FID"
2282         #define OBD_FAIL_LFSCK_NOPFID           0x1617
2283         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1617
2284
2285         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2286         $LFS getstripe $DIR/$tdir/a1/f1
2287
2288         if [ $MDSCOUNT -ge 2 ]; then
2289                 $LFS mkdir -i 1 $DIR/$tdir/a2
2290                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a2
2291                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2292                 $LFS getstripe $DIR/$tdir/a2/f2
2293         fi
2294
2295         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2296                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2297
2298         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2299         $LFS getstripe $DIR/$tdir/f3
2300
2301         cancel_lru_locks osc
2302         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
2303
2304         echo "Inject failure, to simulate the case of missing the MDT-object"
2305         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2306         do_facet mds1 $LCTL set_param fail_loc=0x1616
2307         rm -f $DIR/$tdir/a1/f1
2308
2309         if [ $MDSCOUNT -ge 2 ]; then
2310                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2311                 rm -f $DIR/$tdir/a2/f2
2312         fi
2313
2314         rm -f $DIR/$tdir/f3
2315
2316         sync
2317         sleep 2
2318
2319         do_facet mds1 $LCTL set_param fail_loc=0
2320         if [ $MDSCOUNT -ge 2 ]; then
2321                 do_facet mds2 $LCTL set_param fail_loc=0
2322         fi
2323
2324         cancel_lru_locks mdc
2325         cancel_lru_locks osc
2326
2327         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2328         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2329
2330         for k in $(seq $MDSCOUNT); do
2331                 # The LFSCK status query internal is 30 seconds. For the case
2332                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2333                 # time to guarantee the status sync up.
2334                 wait_update_facet mds${k} "$LCTL get_param -n \
2335                         mdd.$(facet_svc mds${k}).lfsck_layout |
2336                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2337                         error "(2) MDS${k} is not the expected 'completed'"
2338         done
2339
2340         for k in $(seq $OSTCOUNT); do
2341                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2342                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2343                                 awk '/^status/ { print $2 }')
2344                 [ "$cur_status" == "completed" ] ||
2345                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2346         done
2347
2348         if [ $MDSCOUNT -ge 2 ]; then
2349                 expected=4
2350         else
2351                 expected=3
2352         fi
2353
2354         local repaired=$(do_facet mds1 $LCTL get_param -n \
2355                          mdd.$(facet_svc mds1).lfsck_layout |
2356                          awk '/^repaired_orphan/ { print $2 }')
2357         [ $repaired -eq $expected ] ||
2358                 error "(4) Expect $expected fixed on mds1, but got: $repaired"
2359
2360         if [ $MDSCOUNT -ge 2 ]; then
2361                 repaired=$(do_facet mds2 $LCTL get_param -n \
2362                            mdd.$(facet_svc mds2).lfsck_layout |
2363                            awk '/^repaired_orphan/ { print $2 }')
2364                 [ $repaired -eq 0 ] ||
2365                         error "(5) Expect 0 fixed on mds2, but got: $repaired"
2366         fi
2367
2368         ls -ail $MOUNT/.lustre/lost+found/
2369
2370         echo "There should NOT be some stub under .lustre/lost+found/MDT0001/"
2371         if [ -d $MOUNT/.lustre/lost+found/MDT0001 ]; then
2372                 cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-N-*)
2373                 [ -z "$cname" ] ||
2374                         error "(6) .lustre/lost+found/MDT0001/ should be empty"
2375         fi
2376
2377         echo "There should be some stub under .lustre/lost+found/MDT0000/"
2378         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2379                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2380
2381         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-N-*)
2382         [ ! -z "$cname" ] ||
2383                 error "(8) .lustre/lost+found/MDT0000/ should not be empty"
2384 }
2385 run_test 18c "Find out orphan OST-object and repair it (3)"
2386
2387 test_18d() {
2388         echo "#####"
2389         echo "The target MDT-object layout EA is corrupted, but the right"
2390         echo "OST-object is still alive as orphan. The layout LFSCK will"
2391         echo "not create new OST-object to occupy such slot."
2392         echo "#####"
2393
2394         check_mount_and_prep
2395         mkdir $DIR/$tdir/a1
2396         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2397         echo "guard" > $DIR/$tdir/a1/f1
2398         echo "foo" > $DIR/$tdir/a1/f2
2399
2400         echo "guard" > $DIR/$tdir/a1/f3
2401         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2402                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2403         echo "foo" > $DIR/$tdir/a1/f4
2404
2405         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2406         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2407         $LFS path2fid $DIR/$tdir/a1/f1
2408         $LFS getstripe $DIR/$tdir/a1/f1
2409         $LFS path2fid $DIR/$tdir/a1/f2
2410         $LFS getstripe $DIR/$tdir/a1/f2
2411         $LFS path2fid $DIR/$tdir/a1/f3
2412         $LFS getstripe $DIR/$tdir/a1/f3
2413         $LFS path2fid $DIR/$tdir/a1/f4
2414         $LFS getstripe $DIR/$tdir/a1/f4
2415         cancel_lru_locks osc
2416
2417         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2418         echo "to reference the same OST-object (which is f1's OST-obejct)."
2419         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2420         echo "dangling reference case, but f2's old OST-object is there."
2421
2422         echo "The failure also makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2423         echo "to reference the same OST-object (which is f3's OST-obejct)."
2424         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2425         echo "dangling reference case, but f4's old OST-object is there."
2426         echo
2427
2428         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2429         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2430         chown 1.1 $DIR/$tdir/a1/f2
2431         chown 1.1 $DIR/$tdir/a1/f4
2432         rm -f $DIR/$tdir/a1/f1
2433         rm -f $DIR/$tdir/a1/f3
2434         sync
2435         sleep 2
2436         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2437
2438         echo "stopall to cleanup object cache"
2439         stopall > /dev/null
2440         echo "setupall"
2441         setupall > /dev/null
2442
2443         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2444         $START_LAYOUT -r -o -c -d || error "(2) Fail to start LFSCK for layout!"
2445
2446         for k in $(seq $MDSCOUNT); do
2447                 # The LFSCK status query internal is 30 seconds. For the case
2448                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2449                 # time to guarantee the status sync up.
2450                 wait_update_facet mds${k} "$LCTL get_param -n \
2451                         mdd.$(facet_svc mds${k}).lfsck_layout |
2452                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2453                         error "(3) MDS${k} is not the expected 'completed'"
2454         done
2455
2456         for k in $(seq $OSTCOUNT); do
2457                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2458                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2459                                 awk '/^status/ { print $2 }')
2460                 [ "$cur_status" == "completed" ] ||
2461                 error "(4) OST${k} Expect 'completed', but got '$cur_status'"
2462         done
2463
2464         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2465                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2466                          awk '/^repaired_orphan/ { print $2 }')
2467         [ $repaired -eq 2 ] ||
2468                 error "(5) Expect 2 orphans have been fixed, but got: $repaired"
2469
2470         repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2471                    mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2472                    awk '/^repaired_dangling/ { print $2 }')
2473         [ $repaired -eq 0 ] ||
2474                 error "(6) Expect 0 dangling has been fixed, but got: $repaired"
2475
2476         echo "The file size should be correct after layout LFSCK scanning"
2477         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2478         [ "$cur_size" == "$saved_size1" ] ||
2479                 error "(7) Expect file2 size $saved_size1, but got $cur_size"
2480
2481         cur_size=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2482         [ "$cur_size" == "$saved_size2" ] ||
2483                 error "(8) Expect file4 size $saved_size2, but got $cur_size"
2484
2485         echo "The LFSCK should find back the original data."
2486         cat $DIR/$tdir/a1/f2
2487         $LFS path2fid $DIR/$tdir/a1/f2
2488         $LFS getstripe $DIR/$tdir/a1/f2
2489         cat $DIR/$tdir/a1/f4
2490         $LFS path2fid $DIR/$tdir/a1/f4
2491         $LFS getstripe $DIR/$tdir/a1/f4
2492 }
2493 run_test 18d "Find out orphan OST-object and repair it (4)"
2494
2495 test_18e() {
2496         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2497
2498         echo "#####"
2499         echo "The target MDT-object layout EA slot is occpuied by some new"
2500         echo "created OST-object when repair dangling reference case. Such"
2501         echo "conflict OST-object has been modified by others. To keep the"
2502         echo "new data, the LFSCK will create a new file to refernece this"
2503         echo "old orphan OST-object."
2504         echo "#####"
2505
2506         check_mount_and_prep
2507         mkdir $DIR/$tdir/a1
2508         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2509         echo "guard" > $DIR/$tdir/a1/f1
2510         echo "foo" > $DIR/$tdir/a1/f2
2511
2512         echo "guard" > $DIR/$tdir/a1/f3
2513         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2514                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2515         echo "foo" > $DIR/$tdir/a1/f4
2516
2517         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2518         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2519
2520         $LFS path2fid $DIR/$tdir/a1/f1
2521         $LFS getstripe $DIR/$tdir/a1/f1
2522         $LFS path2fid $DIR/$tdir/a1/f2
2523         $LFS getstripe $DIR/$tdir/a1/f2
2524         $LFS path2fid $DIR/$tdir/a1/f3
2525         $LFS getstripe $DIR/$tdir/a1/f3
2526         $LFS path2fid $DIR/$tdir/a1/f4
2527         $LFS getstripe $DIR/$tdir/a1/f4
2528         cancel_lru_locks osc
2529
2530         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2531         echo "to reference the same OST-object (which is f1's OST-obejct)."
2532         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2533         echo "dangling reference case, but f2's old OST-object is there."
2534
2535         echo "Also the failure makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2536         echo "to reference the same OST-object (which is f3's OST-obejct)."
2537         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2538         echo "dangling reference case, but f4's old OST-object is there."
2539         echo
2540
2541         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2542         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2543         chown 1.1 $DIR/$tdir/a1/f2
2544         chown 1.1 $DIR/$tdir/a1/f4
2545         rm -f $DIR/$tdir/a1/f1
2546         rm -f $DIR/$tdir/a1/f3
2547         sync
2548         sleep 2
2549         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2550
2551         echo "stopall to cleanup object cache"
2552         stopall > /dev/null
2553         echo "setupall"
2554         setupall > /dev/null
2555
2556         #define OBD_FAIL_LFSCK_DELAY3           0x1602
2557         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
2558
2559         start_full_debug_logging
2560
2561         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2562         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
2563
2564         wait_update_facet mds1 "$LCTL get_param -n \
2565                 mdd.$(facet_svc mds1).lfsck_layout |
2566                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" $LTIME ||
2567                 error "(3) MDS1 is not the expected 'scanning-phase2'"
2568
2569         # to guarantee all updates are synced.
2570         sync
2571         sleep 2
2572
2573         echo "Write new data to f2/f4 to modify the new created OST-object."
2574         echo "dummy" >> $DIR/$tdir/a1/f2 || error "write a1/f2 failed"
2575         echo "dummy" >> $DIR/$tdir/a1/f4 || error "write a1/f4 failed"
2576
2577         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2578
2579         for k in $(seq $MDSCOUNT); do
2580                 # The LFSCK status query internal is 30 seconds. For the case
2581                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2582                 # time to guarantee the status sync up.
2583                 wait_update_facet mds${k} "$LCTL get_param -n \
2584                         mdd.$(facet_svc mds${k}).lfsck_layout |
2585                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2586                         error "(4) MDS${k} is not the expected 'completed'"
2587         done
2588
2589         for k in $(seq $OSTCOUNT); do
2590                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2591                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2592                                 awk '/^status/ { print $2 }')
2593                 [ "$cur_status" == "completed" ] ||
2594                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2595         done
2596
2597         stop_full_debug_logging
2598
2599         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2600                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2601                          awk '/^repaired_orphan/ { print $2 }')
2602         [ $repaired -eq 2 ] ||
2603                 error "(6) Expect 2 orphans have been fixed, but got: $repaired"
2604
2605         echo "There should be stub file under .lustre/lost+found/MDT0000/"
2606         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2607                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2608
2609         local count=$(ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-* | wc -l)
2610         if [ $count -ne 2 ]; then
2611                 ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-*
2612                 error "(8) Expect 2 stubs under lost+found, but got $count"
2613         fi
2614
2615         echo "The stub file should keep the original f2 or f4 data"
2616         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | head -n 1)
2617         local cur_size=$(ls -il $cname | awk '{ print $6 }')
2618         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2619                 error "(9) Got unexpected $cur_size"
2620
2621         cat $cname
2622         $LFS path2fid $cname
2623         $LFS getstripe $cname
2624
2625         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | tail -n 1)
2626         cur_size=$(ls -il $cname | awk '{ print $6 }')
2627         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2628                 error "(10) Got unexpected $cur_size"
2629
2630         cat $cname
2631         $LFS path2fid $cname
2632         $LFS getstripe $cname
2633
2634         echo "The f2/f4 should contains new data."
2635         cat $DIR/$tdir/a1/f2
2636         $LFS path2fid $DIR/$tdir/a1/f2
2637         $LFS getstripe $DIR/$tdir/a1/f2
2638         cat $DIR/$tdir/a1/f4
2639         $LFS path2fid $DIR/$tdir/a1/f4
2640         $LFS getstripe $DIR/$tdir/a1/f4
2641 }
2642 run_test 18e "Find out orphan OST-object and repair it (5)"
2643
2644 test_18f() {
2645         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2646
2647         echo "#####"
2648         echo "The target MDT-object is lost. The LFSCK should re-create the"
2649         echo "MDT-object under .lustre/lost+found/MDTxxxx. If some OST fail"
2650         echo "to verify some OST-object(s) during the first stage-scanning,"
2651         echo "the LFSCK should skip orphan OST-objects for such OST. Others"
2652         echo "should not be affected."
2653         echo "#####"
2654
2655         check_mount_and_prep
2656         $LFS mkdir -i 0 $DIR/$tdir/a1
2657         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2658         dd if=/dev/zero of=$DIR/$tdir/a1/guard bs=1M count=2
2659         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2660         $LFS mkdir -i 0 $DIR/$tdir/a2
2661         $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a2
2662         dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2663         $LFS getstripe $DIR/$tdir/a1/f1
2664         $LFS getstripe $DIR/$tdir/a2/f2
2665
2666         if [ $MDSCOUNT -ge 2 ]; then
2667                 $LFS mkdir -i 1 $DIR/$tdir/a3
2668                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a3
2669                 dd if=/dev/zero of=$DIR/$tdir/a3/guard bs=1M count=2
2670                 dd if=/dev/zero of=$DIR/$tdir/a3/f3 bs=1M count=2
2671                 $LFS mkdir -i 1 $DIR/$tdir/a4
2672                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a4
2673                 dd if=/dev/zero of=$DIR/$tdir/a4/f4 bs=1M count=2
2674                 $LFS getstripe $DIR/$tdir/a3/f3
2675                 $LFS getstripe $DIR/$tdir/a4/f4
2676         fi
2677
2678         cancel_lru_locks osc
2679
2680         echo "Inject failure, to simulate the case of missing the MDT-object"
2681         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2682         do_facet mds1 $LCTL set_param fail_loc=0x1616
2683         rm -f $DIR/$tdir/a1/f1
2684         rm -f $DIR/$tdir/a2/f2
2685
2686         if [ $MDSCOUNT -ge 2 ]; then
2687                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2688                 rm -f $DIR/$tdir/a3/f3
2689                 rm -f $DIR/$tdir/a4/f4
2690         fi
2691
2692         sync
2693         sleep 2
2694
2695         do_facet mds1 $LCTL set_param fail_loc=0
2696         if [ $MDSCOUNT -ge 2 ]; then
2697                 do_facet mds2 $LCTL set_param fail_loc=0
2698         fi
2699
2700         cancel_lru_locks mdc
2701         cancel_lru_locks osc
2702
2703         echo "Inject failure, to simulate the OST0 fail to handle"
2704         echo "MDT0 LFSCK request during the first-stage scanning."
2705         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
2706         do_facet mds1 $LCTL set_param fail_loc=0x161c fail_val=0
2707
2708         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2709         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2710
2711         for k in $(seq $MDSCOUNT); do
2712                 # The LFSCK status query internal is 30 seconds. For the case
2713                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2714                 # time to guarantee the status sync up.
2715                 wait_update_facet mds${k} "$LCTL get_param -n \
2716                         mdd.$(facet_svc mds${k}).lfsck_layout |
2717                         awk '/^status/ { print \\\$2 }'" "partial" $LTIME ||
2718                         error "(2) MDS${k} is not the expected 'partial'"
2719         done
2720
2721         wait_update_facet ost1 "$LCTL get_param -n \
2722                 obdfilter.$(facet_svc ost1).lfsck_layout |
2723                 awk '/^status/ { print \\\$2 }'" "partial" $LTIME || {
2724                 error "(3) OST1 is not the expected 'partial'"
2725         }
2726
2727         wait_update_facet ost2 "$LCTL get_param -n \
2728                 obdfilter.$(facet_svc ost2).lfsck_layout |
2729                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME || {
2730                 error "(4) OST2 is not the expected 'completed'"
2731         }
2732
2733         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2734
2735         local repaired=$(do_facet mds1 $LCTL get_param -n \
2736                          mdd.$(facet_svc mds1).lfsck_layout |
2737                          awk '/^repaired_orphan/ { print $2 }')
2738         [ $repaired -eq 1 ] ||
2739                 error "(5) Expect 1 fixed on mds{1}, but got: $repaired"
2740
2741         if [ $MDSCOUNT -ge 2 ]; then
2742                 repaired=$(do_facet mds2 $LCTL get_param -n \
2743                          mdd.$(facet_svc mds2).lfsck_layout |
2744                          awk '/^repaired_orphan/ { print $2 }')
2745                 [ $repaired -eq 1 ] ||
2746                 error "(6) Expect 1 fixed on mds{2}, but got: $repaired"
2747         fi
2748
2749         echo "Trigger layout LFSCK on all devices again to cleanup"
2750         $START_LAYOUT -r -o || error "(7) Fail to start LFSCK for layout!"
2751
2752         for k in $(seq $MDSCOUNT); do
2753                 # The LFSCK status query internal is 30 seconds. For the case
2754                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2755                 # time to guarantee the status sync up.
2756                 wait_update_facet mds${k} "$LCTL get_param -n \
2757                         mdd.$(facet_svc mds${k}).lfsck_layout |
2758                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2759                         error "(8) MDS${k} is not the expected 'completed'"
2760         done
2761
2762         for k in $(seq $OSTCOUNT); do
2763                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2764                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2765                              awk '/^status/ { print $2 }')
2766                 [ "$cur_status" == "completed" ] ||
2767                 error "(9) OST${k} Expect 'completed', but got '$cur_status'"
2768
2769         done
2770
2771         local repaired=$(do_facet mds1 $LCTL get_param -n \
2772                          mdd.$(facet_svc mds1).lfsck_layout |
2773                          awk '/^repaired_orphan/ { print $2 }')
2774         [ $repaired -eq 2 ] ||
2775                 error "(10) Expect 2 fixed on mds{1}, but got: $repaired"
2776
2777         if [ $MDSCOUNT -ge 2 ]; then
2778                 repaired=$(do_facet mds2 $LCTL get_param -n \
2779                          mdd.$(facet_svc mds2).lfsck_layout |
2780                          awk '/^repaired_orphan/ { print $2 }')
2781                 [ $repaired -eq 2 ] ||
2782                 error "(11) Expect 2 fixed on mds{2}, but got: $repaired"
2783         fi
2784 }
2785 run_test 18f "Skip the failed OST(s) when handle orphan OST-objects"
2786
2787 test_18g() {
2788         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2789
2790         echo "#####"
2791         echo "The target MDT-object is lost, but related OI mapping is there"
2792         echo "The LFSCK should recreate the lost MDT-object without affected"
2793         echo "by the stale OI mapping."
2794         echo "#####"
2795
2796         check_mount_and_prep
2797         $LFS mkdir -i 0 $DIR/$tdir/a1
2798         $LFS setstripe -c -1 -i 0 -S 1M $DIR/$tdir/a1
2799         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=$OSTCOUNT
2800         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2801         echo ${fid1}
2802         $LFS getstripe $DIR/$tdir/a1/f1
2803         cancel_lru_locks osc
2804
2805         echo "Inject failure to simulate lost MDT-object but keep OI mapping"
2806         #define OBD_FAIL_LFSCK_LOST_MDTOBJ2     0x162e
2807         do_facet mds1 $LCTL set_param fail_loc=0x162e
2808         rm -f $DIR/$tdir/a1/f1
2809
2810         do_facet mds1 $LCTL set_param fail_loc=0
2811         cancel_lru_locks mdc
2812         cancel_lru_locks osc
2813
2814         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2815         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2816
2817         for k in $(seq $MDSCOUNT); do
2818                 # The LFSCK status query internal is 30 seconds. For the case
2819                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2820                 # time to guarantee the status sync up.
2821                 wait_update_facet mds${k} "$LCTL get_param -n \
2822                         mdd.$(facet_svc mds${k}).lfsck_layout |
2823                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2824                         error "(2) MDS${k} is not the expected 'completed'"
2825         done
2826
2827         for k in $(seq $OSTCOUNT); do
2828                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2829                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2830                                 awk '/^status/ { print $2 }')
2831                 [ "$cur_status" == "completed" ] ||
2832                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2833         done
2834
2835         local repaired=$(do_facet mds1 $LCTL get_param -n \
2836                          mdd.$(facet_svc mds1).lfsck_layout |
2837                          awk '/^repaired_orphan/ { print $2 }')
2838         [ $repaired -eq $OSTCOUNT ] ||
2839                 error "(4) Expect $OSTCOUNT fixed, but got: $repaired"
2840
2841         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2842         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2843         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2844
2845         $LFS path2fid $DIR/$tdir/a1/f1
2846         $LFS getstripe $DIR/$tdir/a1/f1
2847 }
2848 run_test 18g "Find out orphan OST-object and repair it (7)"
2849
2850 test_18h() {
2851         echo "#####"
2852         echo "The PFL extent crashed. During the first cycle LFSCK scanning,"
2853         echo "the layout LFSCK will keep the bad PFL file(s) there without"
2854         echo "scanning its OST-object(s). Then in the second stage scanning,"
2855         echo "the OST will return related OST-object(s) to the MDT as orphan."
2856         echo "And then the LFSCK on the MDT can rebuild the PFL extent with"
2857         echo "the 'orphan(s)' stripe information."
2858         echo "#####"
2859
2860         check_mount_and_prep
2861
2862         $LFS setstripe -E 2M -S 1M -c 1 -E -1 $DIR/$tdir/f0 ||
2863                 error "(0) Fail to create PFL $DIR/$tdir/f0"
2864
2865         cat $LUSTRE/tests/test-framework.sh > $DIR/$tdir/f0 ||
2866                 error "(1.1) Fail to write $DIR/$tdir/f0"
2867
2868         dd if=$LUSTRE/tests/test-framework.sh of=$DIR/$tdir/f0 bs=1M seek=2 ||
2869                 error "(1.2) Fail to write $DIR/$tdir/f0"
2870
2871         cp $DIR/$tdir/f0 $DIR/$tdir/guard
2872
2873         echo "Inject failure stub to simulate bad PFL extent range"
2874         #define OBD_FAIL_LFSCK_BAD_PFL_RANGE    0x162f
2875         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162f
2876
2877         chown 1.1 $DIR/$tdir/f0
2878
2879         cancel_lru_locks mdc
2880         cancel_lru_locks osc
2881         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2882
2883         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 &&
2884                 error "(2) Write to bad PFL file should fail"
2885
2886         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
2887         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
2888
2889         for k in $(seq $MDSCOUNT); do
2890                 # The LFSCK status query internal is 30 seconds. For the case
2891                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2892                 # time to guarantee the status sync up.
2893                 wait_update_facet mds${k} "$LCTL get_param -n \
2894                         mdd.$(facet_svc mds${k}).lfsck_layout |
2895                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2896                         error "(4.1) MDS${k} is not the expected 'completed'"
2897         done
2898
2899         for k in $(seq $OSTCOUNT); do
2900                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2901                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2902                              awk '/^status/ { print $2 }')
2903                 [ "$cur_status" == "completed" ] ||
2904                 error "(4.2) OST${k} Expect 'completed', but got '$cur_status'"
2905
2906         done
2907
2908         local repaired=$($SHOW_LAYOUT |
2909                          awk '/^repaired_orphan/ { print $2 }')
2910         [ $repaired -eq 2 ] ||
2911                 error "(5) Fail to repair crashed PFL range: $repaired"
2912
2913         echo "Data in $DIR/$tdir/f0 should not be broken"
2914         diff $DIR/$tdir/f0 $DIR/$tdir/guard ||
2915                 error "(6) Data in $DIR/$tdir/f0 is broken"
2916
2917         echo "Write should succeed after LFSCK repairing the bad PFL range"
2918         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 ||
2919                 error "(7) Write should succeed after LFSCK"
2920 }
2921 run_test 18h "LFSCK can repair crashed PFL extent range"
2922
2923 $LCTL set_param debug=-cache > /dev/null
2924
2925 test_19a() {
2926         check_mount_and_prep
2927         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2928
2929         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2930                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
2931
2932         echo "foo1" > $DIR/$tdir/a0
2933         $LFS setstripe -E 512K -S 512K -o 0 -E -1 -S 1M $DIR/$tdir/a1 ||
2934                 error "(0) Fail to create PFL $DIR/$tdir/a1"
2935         echo "foo2" > $DIR/$tdir/a1
2936         echo "guard" > $DIR/$tdir/a2
2937         cancel_lru_locks osc
2938
2939         echo "Inject failure, then client will offer wrong parent FID when read"
2940         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2941                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2942
2943         #define OBD_FAIL_LFSCK_INVALID_PFID     0x1619
2944         $LCTL set_param fail_loc=0x1619
2945
2946         echo "Read RPC with wrong parent FID should be denied"
2947         cat $DIR/$tdir/a0 && error "(3.1) Read a0 should be denied!"
2948         cat $DIR/$tdir/a1 && error "(3.2) Read a1 should be denied!"
2949         $LCTL set_param fail_loc=0
2950 }
2951 run_test 19a "OST-object inconsistency self detect"
2952
2953 test_19b() {
2954         check_mount_and_prep
2955         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2956
2957         echo "Inject failure stub to make the OST-object to back point to"
2958         echo "non-exist MDT-object"
2959
2960         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2961                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
2962
2963         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
2964         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
2965         echo "foo1" > $DIR/$tdir/f0
2966         $LFS setstripe -E 1M -S 1M -o 0 -E 4M -S 256K $DIR/$tdir/f1 ||
2967                 error "(0) Fail to create PFL $DIR/$tdir/f1"
2968         echo "foo2" > $DIR/$tdir/f1
2969         cancel_lru_locks osc
2970         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
2971
2972         do_facet ost1 $LCTL set_param -n \
2973                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
2974         echo "Nothing should be fixed since self detect and repair is disabled"
2975         local repaired=$(do_facet ost1 $LCTL get_param -n \
2976                         obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2977                         awk '/^repaired/ { print $2 }')
2978         [ $repaired -eq 0 ] ||
2979                 error "(1) Expected 0 repaired, but got $repaired"
2980
2981         echo "Read RPC with right parent FID should be accepted,"
2982         echo "and cause parent FID on OST to be fixed"
2983
2984         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
2985                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2986
2987         cat $DIR/$tdir/f0 || error "(2.1) Read f0 should not be denied!"
2988         cat $DIR/$tdir/f1 || error "(2.2) Read f1 should not be denied!"
2989
2990         repaired=$(do_facet ost1 $LCTL get_param -n \
2991                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2992                 awk '/^repaired/ { print $2 }')
2993         [ $repaired -eq 2 ] ||
2994                 error "(3) Expected 1 repaired, but got $repaired"
2995 }
2996 run_test 19b "OST-object inconsistency self repair"
2997
2998 PATTERN_WITH_HOLE="40000001"
2999 PATTERN_WITHOUT_HOLE="raid0"
3000
3001 test_20a() {
3002         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
3003         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
3004
3005         echo "#####"
3006         echo "The target MDT-object and some of its OST-object are lost."
3007         echo "The LFSCK should find out the left OST-objects and re-create"
3008         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
3009         echo "with the partial OST-objects (LOV EA hole)."
3010
3011         echo "New client can access the file with LOV EA hole via normal"
3012         echo "system tools or commands without crash the system."
3013
3014         echo "For old client, even though it cannot access the file with"
3015         echo "LOV EA hole, it should not cause the system crash."
3016         echo "#####"
3017
3018         check_mount_and_prep
3019         $LFS mkdir -i 0 $DIR/$tdir/a1
3020         if [ $OSTCOUNT -gt 2 ]; then
3021                 $LFS setstripe -c 3 -i 0 -S 1M $DIR/$tdir/a1
3022                 bcount=513
3023         else
3024                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a1
3025                 bcount=257
3026         fi
3027
3028         # 256 blocks on the stripe0.
3029         # 1 block on the stripe1 for 2 OSTs case.
3030         # 256 blocks on the stripe1 for other cases.
3031         # 1 block on the stripe2 if OSTs > 2
3032         dd if=/dev/zero of=$DIR/$tdir/a1/f0 bs=4096 count=$bcount
3033         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=4096 count=$bcount
3034         dd if=/dev/zero of=$DIR/$tdir/a1/f2 bs=4096 count=$bcount
3035
3036         local fid0=$($LFS path2fid $DIR/$tdir/a1/f0)
3037         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
3038         local fid2=$($LFS path2fid $DIR/$tdir/a1/f2)
3039
3040         echo ${fid0}
3041         $LFS getstripe $DIR/$tdir/a1/f0
3042         echo ${fid1}
3043         $LFS getstripe $DIR/$tdir/a1/f1
3044         echo ${fid2}
3045         $LFS getstripe $DIR/$tdir/a1/f2
3046
3047         if [ $OSTCOUNT -gt 2 ]; then
3048                 dd if=/dev/zero of=$DIR/$tdir/a1/f3 bs=4096 count=$bcount
3049                 fid3=$($LFS path2fid $DIR/$tdir/a1/f3)
3050                 echo ${fid3}
3051                 $LFS getstripe $DIR/$tdir/a1/f3
3052         fi
3053
3054         cancel_lru_locks osc
3055
3056         echo "Inject failure..."
3057         echo "To simulate f0 lost MDT-object"
3058         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
3059         do_facet mds1 $LCTL set_param fail_loc=0x1616
3060         rm -f $DIR/$tdir/a1/f0
3061
3062         echo "To simulate f1 lost MDT-object and OST-object0"
3063         #define OBD_FAIL_LFSCK_LOST_SPEOBJ      0x161a
3064         do_facet mds1 $LCTL set_param fail_loc=0x161a
3065         rm -f $DIR/$tdir/a1/f1
3066
3067         echo "To simulate f2 lost MDT-object and OST-object1"
3068         do_facet mds1 $LCTL set_param fail_val=1
3069         rm -f $DIR/$tdir/a1/f2
3070
3071         if [ $OSTCOUNT -gt 2 ]; then
3072                 echo "To simulate f3 lost MDT-object and OST-object2"
3073                 do_facet mds1 $LCTL set_param fail_val=2
3074                 rm -f $DIR/$tdir/a1/f3
3075         fi
3076
3077         umount_client $MOUNT
3078         sync
3079         sleep 2
3080         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
3081
3082         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
3083         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
3084
3085         for k in $(seq $MDSCOUNT); do
3086                 # The LFSCK status query internal is 30 seconds. For the case
3087                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3088                 # time to guarantee the status sync up.
3089                 wait_update_facet mds${k} "$LCTL get_param -n \
3090                         mdd.$(facet_svc mds${k}).lfsck_layout |
3091                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
3092                         error "(2) MDS${k} is not the expected 'completed'"
3093         done
3094
3095         for k in $(seq $OSTCOUNT); do
3096                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
3097                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
3098                                 awk '/^status/ { print $2 }')
3099                 [ "$cur_status" == "completed" ] ||
3100                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
3101         done
3102
3103         local repaired=$(do_facet mds1 $LCTL get_param -n \
3104                          mdd.$(facet_svc mds1).lfsck_layout |
3105                          awk '/^repaired_orphan/ { print $2 }')
3106         if [ $OSTCOUNT -gt 2 ]; then
3107                 [ $repaired -eq 9 ] ||
3108                         error "(4.1) Expect 9 fixed on mds1, but got: $repaired"
3109         else
3110                 [ $repaired -eq 4 ] ||
3111                         error "(4.2) Expect 4 fixed on mds1, but got: $repaired"
3112         fi
3113
3114         mount_client $MOUNT || error "(5.0) Fail to start client!"
3115
3116         LOV_PATTERN_F_HOLE=0x40000000
3117
3118         #
3119         # ${fid0}-R-0 is the old f0
3120         #
3121         local name="$MOUNT/.lustre/lost+found/MDT0000/${fid0}-R-0"
3122         echo "Check $name, which is the old f0"
3123
3124         $LFS getstripe -v $name || error "(5.1) cannot getstripe on $name"
3125
3126         local pattern=$($LFS getstripe -L $name)
3127         [[ "$pattern" = "$PATTERN_WITHOUT_HOLE" ]] ||
3128                 error "(5.2) NOT expect pattern flag hole, but got $pattern"
3129
3130         local stripes=$($LFS getstripe -c $name)
3131         if [ $OSTCOUNT -gt 2 ]; then
3132                 [ $stripes -eq 3 ] ||
3133                 error "(5.3.1) expect the stripe count is 3, but got $stripes"
3134         else
3135                 [ $stripes -eq 2 ] ||
3136                 error "(5.3.2) expect the stripe count is 2, but got $stripes"
3137         fi
3138
3139         local size=$(stat $name | awk '/Size:/ { print $2 }')
3140         [ $size -eq $((4096 * $bcount)) ] ||
3141                 error "(5.4) expect the size $((4096 * $bcount)), but got $size"
3142
3143         cat $name > /dev/null || error "(5.5) cannot read $name"
3144
3145         echo "dummy" >> $name || error "(5.6) cannot write $name"
3146
3147         chown $RUNAS_ID:$RUNAS_GID $name || error "(5.7) cannot chown on $name"
3148
3149         touch $name || error "(5.8) cannot touch $name"
3150
3151         rm -f $name || error "(5.9) cannot unlink $name"
3152
3153         #
3154         # ${fid1}-R-0 contains the old f1's stripe1 (and stripe2 if OSTs > 2)
3155         #
3156         name="$MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
3157         if [ $OSTCOUNT -gt 2 ]; then
3158                 echo "Check $name, it contains the old f1's stripe1 and stripe2"
3159         else
3160                 echo "Check $name, it contains the old f1's stripe1"
3161         fi
3162
3163         $LFS getstripe -v $name || error "(6.1) cannot getstripe on $name"
3164
3165         pattern=$($LFS getstripe -L $name)
3166         [[ "$pattern" = "$PATTERN_WITH_HOLE" ]] ||
3167                 error "(6.2) expect pattern flag hole, but got $pattern"
3168
3169         stripes=$($LFS getstripe -c $name)
3170         if [ $OSTCOUNT -gt 2 ]; then
3171                 [ $stripes -eq 3 ] ||
3172                 error "(6.3.1) expect the stripe count is 3, but got $stripes"
3173         else
3174                 [ $stripes -eq 2 ] ||
3175                 error "(6.3.2) expect the stripe count is 2, but got $stripes"
3176         fi
3177
3178         size=$(stat $name | awk '/Size:/ { print $2 }')
3179         [ $size -eq $((4096 * $bcount)) ] ||
3180                 error "(6.4) expect the size $((4096 * $bcount)), but got $size"
3181
3182         cat $name > /dev/null && error "(6.5) normal read $name should fail"
3183
3184         local failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
3185                          bs=4096 2>&1 | grep "Input/output error" | wc -l)
3186
3187         # stripe0 is dummy
3188         [ $failures -eq 256 ] ||
3189                 error "(6.6) expect 256 IO failures, but get $failures"