Whamcloud - gitweb
LU-13284 tests: few tests miss MDS_MOUNT_OPTS/OST_MOUNT_OPTS
[fs/lustre-release.git] / lustre / tests / sanity-lfsck.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 LUSTRE=${LUSTRE:-$(dirname $0)/..}
12 . $LUSTRE/tests/test-framework.sh
13 init_test_env $@
14 init_logging
15
16 # bug number for skipped test:
17 ALWAYS_EXCEPT="$SANITY_LFSCK_EXCEPT "
18 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
19
20 [ "$SLOW" = "no" ] && EXCEPT_SLOW=""
21 build_test_filter
22
23 require_dsh_mds || exit 0
24
25 load_modules
26
27 if ! check_versions; then
28         skip "It is NOT necessary to test lfsck under interoperation mode"
29         exit 0
30 fi
31
32 (( $MDS1_VERSION >= $(version_code 2.3.60) )) ||
33         skip "Need MDS version at least 2.3.60"
34
35 LTIME=${LTIME:-120}
36
37 SAVED_MDSSIZE=${MDSSIZE}
38 SAVED_OSTSIZE=${OSTSIZE}
39 SAVED_OSTCOUNT=${OSTCOUNT}
40 # use small MDS + OST size to speed formatting time
41 # do not use too small MDSSIZE/OSTSIZE, which affect the default journal size
42 MDSSIZE=100000
43 [ "$mds1_FSTYPE" == zfs ] && MDSSIZE=300000
44 OSTSIZE=100000
45 [ "$ost1_FSTYPE" == zfs ] && OSTSIZE=300000
46
47 # no need too many OSTs, to reduce the format/start/stop overhead
48 cleanupall
49 [ $OSTCOUNT -gt 4 ] && OSTCOUNT=4
50
51 # build up a clean test environment.
52 REFORMAT="yes" check_and_setup_lustre
53
54 MDT_DEV="${FSNAME}-MDT0000"
55 OST_DEV="${FSNAME}-OST0000"
56 MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
57 START_NAMESPACE="do_facet $SINGLEMDS \
58                 $LCTL lfsck_start -M ${MDT_DEV} -t namespace"
59 START_LAYOUT="do_facet $SINGLEMDS \
60                 $LCTL lfsck_start -M ${MDT_DEV} -t layout"
61 START_LAYOUT_ON_OST="do_facet ost1 $LCTL lfsck_start -M ${OST_DEV} -t layout"
62 STOP_LFSCK="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
63 SHOW_NAMESPACE="do_facet $SINGLEMDS \
64                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace"
65 SHOW_LAYOUT="do_facet $SINGLEMDS \
66                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout"
67 SHOW_LAYOUT_ON_OST="do_facet ost1 \
68                 $LCTL get_param -n obdfilter.${OST_DEV}.lfsck_layout"
69 MOUNT_OPTS_SCRUB="$MDS_MOUNT_OPTS -o user_xattr"
70 MOUNT_OPTS_NOSCRUB="$MDS_MOUNT_OPTS -o user_xattr,noscrub"
71 MOUNT_OPTS_SKIP_LFSCK="$MDS_MOUNT_OPTS -o user_xattr,skip_lfsck"
72
73 lfsck_prep() {
74         local ndirs=$1
75         local nfiles=$2
76         local igif=$3
77
78         check_mount_and_prep
79
80         echo "preparing... $nfiles * $ndirs files will be created $(date)."
81         if [ ! -z $igif ]; then
82                 #define OBD_FAIL_FID_IGIF       0x1504
83                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
84         fi
85
86         cp $LUSTRE/tests/*.sh $DIR/$tdir/
87         if [ $ndirs -gt 0 ]; then
88                 createmany -d $DIR/$tdir/d $ndirs
89                 createmany -m $DIR/$tdir/f $ndirs
90                 if [ $nfiles -gt 0 ]; then
91                         for ((i = 0; i < $ndirs; i++)); do
92                                 createmany -m $DIR/$tdir/d${i}/f $nfiles > \
93                                         /dev/null || error "createmany $nfiles"
94                         done
95                 fi
96                 createmany -d $DIR/$tdir/e $ndirs
97         fi
98
99         if [ ! -z $igif ]; then
100                 touch $DIR/$tdir/dummy
101                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0
102         fi
103
104         echo "prepared $(date)."
105 }
106
107 run_e2fsck_on_mdt0() {
108         [ $mds1_FSTYPE == ldiskfs ] || return 0
109
110         stop $SINGLEMDS > /dev/null || error "(0) Fail to the stop MDT0"
111         run_e2fsck $(facet_active_host $SINGLEMDS) $(mdsdevname 1) "-n" |
112                 grep "Fix? no" && {
113                 run_e2fsck $(facet_active_host $SINGLEMDS) $(mdsdevname 1) "-n"
114                 error "(2) Detected inconsistency on MDT0"
115         }
116         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
117                 error "(3) Fail to start MDT0"
118 }
119
120 wait_all_targets_blocked() {
121         local com=$1
122         local status=$2
123         local err=$3
124
125         local count=$(do_facet mds1 \
126                      "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000 -w |
127                       awk '/^${com}_mdts_${status}/ { print \\\$2 }'")
128         [[ $count -eq $MDSCOUNT ]] || {
129                 do_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000"
130                 error "($err) only $count of $MDSCOUNT MDTs are in ${status}"
131         }
132 }
133
134 wait_all_targets() {
135         local com=$1
136         local status=$2
137         local err=$3
138
139         wait_update_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000 |
140                 awk '/^${com}_mdts_${status}/ { print \\\$2 }'" \
141                 "$MDSCOUNT" $LTIME || {
142                 do_facet mds1 "$LCTL lfsck_query -t $com -M ${FSNAME}-MDT0000"
143                 error "($err) some MDTs are not in ${status}"
144         }
145 }
146
147 test_0() {
148         lfsck_prep 3 3
149
150         #define OBD_FAIL_LFSCK_DELAY1           0x1600
151         do_facet $SINGLEMDS $LCTL set_param fail_val=3 fail_loc=0x1600
152         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
153
154         $SHOW_NAMESPACE || error "Fail to monitor LFSCK (3)"
155
156         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
157         [ "$STATUS" == "scanning-phase1" ] ||
158                 error "(4) Expect 'scanning-phase1', but got '$STATUS'"
159
160         $STOP_LFSCK || error "(5) Fail to stop LFSCK!"
161
162         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
163         [ "$STATUS" == "stopped" ] ||
164                 error "(6) Expect 'stopped', but got '$STATUS'"
165
166         $START_NAMESPACE || error "(7) Fail to start LFSCK for namespace!"
167
168         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
169         [ "$STATUS" == "scanning-phase1" ] ||
170                 error "(8) Expect 'scanning-phase1', but got '$STATUS'"
171
172         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
173         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
174                 mdd.${MDT_DEV}.lfsck_namespace |
175                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
176                 $SHOW_NAMESPACE
177                 error "(9) unexpected status"
178         }
179
180         local repaired=$($SHOW_NAMESPACE |
181                          awk '/^updated_phase1/ { print $2 }')
182         [ $repaired -eq 0 ] ||
183                 error "(10) Expect nothing to be repaired, but got: $repaired"
184
185         local scanned1=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
186         $START_NAMESPACE -r || error "(11) Fail to reset LFSCK!"
187         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
188                 mdd.${MDT_DEV}.lfsck_namespace |
189                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
190                 $SHOW_NAMESPACE
191                 error "(12) unexpected status"
192         }
193
194         local scanned2=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
195         [ $((scanned1 + 1)) -eq $scanned2 ] ||
196                 error "(13) Expect success $((scanned1 + 1)), but got $scanned2"
197
198         echo "stopall, should NOT crash LU-3649"
199         stopall || error "(14) Fail to stopall"
200 }
201 run_test 0 "Control LFSCK manually"
202
203 test_1a() {
204         lfsck_prep 1 1
205
206         #define OBD_FAIL_FID_INDIR      0x1501
207         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1501
208         touch $DIR/$tdir/dummy
209
210         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
211         umount_client $MOUNT
212         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
213         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
214                 mdd.${MDT_DEV}.lfsck_namespace |
215                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
216                 $SHOW_NAMESPACE
217                 error "(4) unexpected status"
218         }
219
220         local repaired=$($SHOW_NAMESPACE |
221                          awk '/^dirent_repaired/ { print $2 }')
222         # for interop with old server
223         [ -z "$repaired" ] &&
224                 repaired=$($SHOW_NAMESPACE |
225                          awk '/^updated_phase1/ { print $2 }')
226
227         [ $repaired -eq 1 ] ||
228                 error "(5) Fail to repair crashed FID-in-dirent: $repaired"
229
230         run_e2fsck_on_mdt0
231
232         mount_client $MOUNT || error "(6) Fail to start client!"
233
234         #define OBD_FAIL_FID_LOOKUP     0x1505
235         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
236         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
237
238         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
239 }
240 run_test 1a "LFSCK can find out and repair crashed FID-in-dirent"
241
242 test_1b()
243 {
244         [ "$mds1_FSTYPE" != ldiskfs ] &&
245                 skip "OI Scrub not implemented for ZFS"
246
247         lfsck_prep 1 1
248
249         #define OBD_FAIL_FID_INLMA      0x1502
250         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1502
251         touch $DIR/$tdir/dummy
252
253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
254         umount_client $MOUNT
255         #define OBD_FAIL_FID_NOLMA      0x1506
256         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1506
257         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
258         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
259                 mdd.${MDT_DEV}.lfsck_namespace |
260                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
261                 $SHOW_NAMESPACE
262                 error "(4) unexpected status"
263         }
264
265         local repaired=$($SHOW_NAMESPACE |
266                          awk '/^dirent_repaired/ { print $2 }')
267         # for interop with old server
268         [ -z "$repaired" ] &&
269                 repaired=$($SHOW_NAMESPACE |
270                          awk '/^updated_phase1/ { print $2 }')
271
272         [ $repaired -eq 1 ] ||
273                 error "(5) Fail to repair the missing FID-in-LMA: $repaired"
274
275         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
276         run_e2fsck_on_mdt0
277
278         mount_client $MOUNT || error "(6) Fail to start client!"
279
280         #define OBD_FAIL_FID_LOOKUP     0x1505
281         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
282         stat $DIR/$tdir/dummy > /dev/null || error "(7) no FID-in-LMA."
283
284         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
285 }
286 run_test 1b "LFSCK can find out and repair the missing FID-in-LMA"
287
288 test_1c() {
289         lfsck_prep 1 1
290
291         #define OBD_FAIL_FID_IGIF       0x1504
292         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
293         touch $DIR/$tdir/dummy
294
295         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
296         umount_client $MOUNT
297         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
298         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
299                 mdd.${MDT_DEV}.lfsck_namespace |
300                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
301                 $SHOW_NAMESPACE
302                 error "(4) unexpected status"
303         }
304
305         local repaired=$($SHOW_NAMESPACE |
306                          awk '/^dirent_repaired/ { print $2 }')
307         # for interop with old server
308         [ -z "$repaired" ] &&
309                 repaired=$($SHOW_NAMESPACE |
310                          awk '/^updated_phase1/ { print $2 }')
311
312         [ $repaired -eq 1 ] ||
313                 error "(5) Fail to repair lost FID-in-dirent: $repaired"
314
315         run_e2fsck_on_mdt0
316
317         mount_client $MOUNT || error "(6) Fail to start client!"
318
319         #define OBD_FAIL_FID_LOOKUP     0x1505
320         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
321         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
322
323         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
324 }
325 run_test 1c "LFSCK can find out and repair lost FID-in-dirent"
326
327 test_1d() {
328         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
329                 skip "MDS older than 2.13.57"
330         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
331
332         check_mount_and_prep
333
334         touch $DIR/$tdir/$tfile
335         mkdir $DIR/$tdir/subdir
336         $LFS mkdir -i 1 $DIR/$tdir/remotedir
337         $LFS path2fid $DIR/$tdir
338         ll_decode_linkea $DIR/$tdir/$tfile
339         ll_decode_linkea $DIR/$tdir/subdir
340         ll_decode_linkea $DIR/$tdir/remotedir
341
342         local mntpt=$(facet_mntpt mds1)
343
344         # unlink OI files to remove the stale entry
345         local saved_opts=$MDS_MOUNT_OPTS
346
347         stopall
348         mount_fstype mds1 $mntpt
349         # increase $tdir FID oid in LMA
350         do_facet mds1 "getfattr -d -m trusted.lma -e hex \
351                 --absolute-names $mntpt/ROOT/$tdir | \
352                 sed -E 's/0(.{8})$/1\1/' | setfattr --restore=-"
353         unmount_fstype mds1 $mntpt
354         setupall
355
356         # the FID oid in LMA was increased above, and it's not in OI table,
357         # run scrub first to generate mapping in OI, so the following namespace
358         # check can fix linkea correctly, this is not necessary normally.
359         do_facet mds1 $LCTL lfsck_start -M ${MDT_DEV} -t scrub ||
360                 error "failed to start LFSCK for scrub!"
361         wait_update_facet mds1 "$LCTL get_param -n \
362                 osd-*.$(facet_svc mds1).oi_scrub |
363                 awk '/^status/ { print \\\$2 }'" "completed" 32 ||
364                 error "unexpected status"
365
366         $START_NAMESPACE -r -A || error "fail to start LFSCK for namespace!"
367         wait_update_facet mds1 "$LCTL get_param -n \
368                 mdd.${MDT_DEV}.lfsck_namespace |
369                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
370                 $SHOW_NAMESPACE
371                 error "unexpected status"
372         }
373         $LFS path2fid $DIR/$tdir
374         ll_decode_linkea $DIR/$tdir/$tfile
375         ll_decode_linkea $DIR/$tdir/subdir
376         ll_decode_linkea $DIR/$tdir/remotedir
377
378         local pfid
379         local fid
380
381         fid=$($LFS path2fid $DIR/$tdir)
382         for f in $tfile subdir remotedir; do
383                 pfid=$(ll_decode_linkea $DIR/$tdir/$f |
384                         awk '/pfid/ { print $3 }')
385                 pfid=${pfid%,}
386                 [ "$pfid" == "$fid" ] || error "$fid in LMA != $pfid in linkea"
387         done
388 }
389 run_test 1d "LFSCK can fix mismatch of FID in LMA and FID in child linkea"
390
391 test_2a() {
392         lfsck_prep 1 1
393
394         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
395         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
396         touch $DIR/$tdir/dummy
397
398         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
399         umount_client $MOUNT
400         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
401         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
402                 mdd.${MDT_DEV}.lfsck_namespace |
403                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
404                 $SHOW_NAMESPACE
405                 error "(4) unexpected status"
406         }
407
408         local repaired=$($SHOW_NAMESPACE |
409                          awk '/^linkea_repaired/ { print $2 }')
410         # for interop with old server
411         [ -z "$repaired" ] &&
412                 repaired=$($SHOW_NAMESPACE |
413                          awk '/^updated_phase2/ { print $2 }')
414
415         [ $repaired -eq 1 ] ||
416                 error "(5) Fail to repair crashed linkEA: $repaired"
417
418         run_e2fsck_on_mdt0
419
420         mount_client $MOUNT || error "(6) Fail to start client!"
421
422         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
423                 error "(7) Fail to stat $DIR/$tdir/dummy"
424
425         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
426         local dummyname=$($LFS fid2path $DIR $dummyfid)
427         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
428                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
429 }
430 run_test 2a "LFSCK can find out and repair crashed linkEA entry"
431
432 test_2b()
433 {
434         lfsck_prep 1 1
435
436         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
437         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
438         touch $DIR/$tdir/dummy
439
440         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
441         umount_client $MOUNT
442         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
443         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
444                 mdd.${MDT_DEV}.lfsck_namespace |
445                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
446                 $SHOW_NAMESPACE
447                 error "(4) unexpected status"
448         }
449
450         local repaired=$($SHOW_NAMESPACE |
451                          awk '/^updated_phase2/ { print $2 }')
452         [ $repaired -eq 1 ] ||
453                 error "(5) Fail to repair crashed linkEA: $repaired"
454
455         run_e2fsck_on_mdt0
456
457         mount_client $MOUNT || error "(6) Fail to start client!"
458
459         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
460                 error "(7) Fail to stat $DIR/$tdir/dummy"
461
462         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
463         local dummyname=$($LFS fid2path $DIR $dummyfid)
464         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
465                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
466 }
467 run_test 2b "LFSCK can find out and remove invalid linkEA entry"
468
469 test_2c()
470 {
471         (( $MDS1_VERSION > $(version_code 2.4.90) )) ||
472                 skip "MDS older than 2.4.90"
473
474         lfsck_prep 1 1
475
476         #define OBD_FAIL_LFSCK_LINKEA_MORE2     0x1605
477         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1605
478         touch $DIR/$tdir/dummy
479
480         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
481         umount_client $MOUNT
482         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
483         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
484                 mdd.${MDT_DEV}.lfsck_namespace |
485                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
486                 $SHOW_NAMESPACE
487                 error "(4) unexpected status"
488         }
489
490         local repaired=$($SHOW_NAMESPACE |
491                          awk '/^updated_phase2/ { print $2 }')
492         [ $repaired -eq 1 ] ||
493                 error "(5) Fail to repair crashed linkEA: $repaired"
494
495         run_e2fsck_on_mdt0
496
497         mount_client $MOUNT || error "(6) Fail to start client!"
498
499         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
500                 error "(7) Fail to stat $DIR/$tdir/dummy"
501
502         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
503         local dummyname=$($LFS fid2path $DIR $dummyfid)
504         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
505                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
506 }
507 run_test 2c "LFSCK can find out and remove repeated linkEA entry"
508
509 test_2d()
510 {
511         (( $MDS1_VERSION > $(version_code 2.6.50) )) ||
512                 skip "MDS older than 2.6.50, LU-4788"
513
514         lfsck_prep 1 1
515
516         #define OBD_FAIL_LFSCK_NO_LINKEA        0x161d
517         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161d
518         touch $DIR/$tdir/dummy
519
520         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
521         umount_client $MOUNT
522         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
523         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
524                 mdd.${MDT_DEV}.lfsck_namespace |
525                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
526                 $SHOW_NAMESPACE
527                 error "(4) unexpected status"
528         }
529
530         local repaired=$($SHOW_NAMESPACE |
531                          awk '/^linkea_repaired/ { print $2 }')
532         [ $repaired -eq 1 ] ||
533                 error "(5) Fail to repair crashed linkEA: $repaired"
534
535         run_e2fsck_on_mdt0
536
537         mount_client $MOUNT || error "(6) Fail to start client!"
538
539         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
540                 error "(7) Fail to stat $DIR/$tdir/dummy"
541
542         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
543         local dummyname=$($LFS fid2path $DIR $dummyfid)
544         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
545                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
546 }
547 run_test 2d "LFSCK can recover the missing linkEA entry"
548
549 test_2e()
550 {
551         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
552         (( $MDS1_VERSION > $(version_code 2.6.50) )) ||
553                 skip "MDS older than 2.6.50, LU-5511"
554
555         check_mount_and_prep
556
557         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT1"
558
559         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
560         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
561         $LFS mkdir -i 0 $DIR/$tdir/d0/d1 || error "(2) Fail to mkdir d1 on MDT0"
562         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
563
564         $START_NAMESPACE -r -A || error "(3) Fail to start LFSCK for namespace!"
565
566         wait_all_targets_blocked namespace completed 4
567
568         local repaired=$($SHOW_NAMESPACE |
569                          awk '/^linkea_repaired/ { print $2 }')
570         [ $repaired -eq 1 ] ||
571                 error "(5) Fail to repair crashed linkEA: $repaired"
572
573         local fid=$($LFS path2fid $DIR/$tdir/d0/d1)
574         local name=$($LFS fid2path $DIR $fid)
575         [ "$name" == "$DIR/$tdir/d0/d1" ] ||
576                 error "(6) Fail to repair linkEA: $fid $name"
577 }
578 run_test 2e "namespace LFSCK can verify remote object linkEA"
579
580 test_3()
581 {
582         (( $MDS1_VERSION > $(version_code 2.6.50) )) ||
583                 skip "MDS older than 2.6.50, LU-4788"
584
585         lfsck_prep 4 4
586
587         mkdir $DIR/$tdir/dummy || error "(1) Fail to mkdir"
588         ln $DIR/$tdir/d0/f0 $DIR/$tdir/dummy/f0 || error "(2) Fail to hardlink"
589         ln $DIR/$tdir/d0/f1 $DIR/$tdir/dummy/f1 || error "(3) Fail to hardlink"
590
591         $LFS mkdir -i 0 $DIR/$tdir/edir || error "(4) Fail to mkdir"
592         touch $DIR/$tdir/edir/f0 || error "(5) Fail to touch"
593         touch $DIR/$tdir/edir/f1 || error "(6) Fail to touch"
594
595         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
596         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
597         ln $DIR/$tdir/edir/f0 $DIR/$tdir/edir/w0 || error "(7) Fail to hardlink"
598
599         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
600         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
601         ln $DIR/$tdir/edir/f1 $DIR/$tdir/edir/w1 || error "(8) Fail to hardlink"
602
603         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
604
605         $START_NAMESPACE -r || error "(9) Fail to start LFSCK for namespace!"
606         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
607                 mdd.${MDT_DEV}.lfsck_namespace |
608                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
609                 $SHOW_NAMESPACE
610                 error "(10) unexpected status"
611         }
612
613         local checked=$($SHOW_NAMESPACE |
614                         awk '/^checked_phase2/ { print $2 }')
615         [ $checked -ge 4 ] ||
616                 error "(11) Fail to check multiple-linked object: $checked"
617
618         local repaired=$($SHOW_NAMESPACE |
619                          awk '/^multiple_linked_repaired/ { print $2 }')
620         [ $repaired -ge 2 ] ||
621                 error "(12) Fail to repair multiple-linked object: $repaired"
622 }
623 run_test 3 "LFSCK can verify multiple-linked objects"
624
625 test_4()
626 {
627         [ "$mds1_FSTYPE" != ldiskfs ] &&
628                 skip "OI Scrub not implemented for ZFS"
629
630         lfsck_prep 3 3
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 || 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" 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 9 ] ||
672                 error "(9) Fail to re-generate FID-in-dirent: $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         ls $DIR/$tdir/ > /dev/null || error "(11) no FID-in-dirent."
681         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
682 }
683 run_test 4 "FID-in-dirent can be rebuilt after MDT file-level backup/restore"
684
685 test_5()
686 {
687         [ "$mds1_FSTYPE" != ldiskfs ] &&
688                 skip "OI Scrub not implemented for ZFS"
689
690         lfsck_prep 1 1 1
691         cleanup_mount $MOUNT || error "(0.1) Fail to stop client!"
692         stop $SINGLEMDS > /dev/null || error "(0.2) Fail to stop MDS!"
693
694         mds_backup_restore $SINGLEMDS 1 || error "(1) Fail to backup/restore!"
695         echo "start $SINGLEMDS with disabling OI scrub"
696         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
697                 error "(2) Fail to start MDS!"
698
699         #define OBD_FAIL_LFSCK_DELAY2           0x1601
700         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
701         $START_NAMESPACE -r || error "(4) Fail to start LFSCK for namespace!"
702         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
703                 mdd.${MDT_DEV}.lfsck_namespace |
704                 awk '/^flags/ { print \\\$2 }'" "inconsistent,upgrade" 32 || {
705                 $SHOW_NAMESPACE
706                 error "(5) unexpected status"
707         }
708
709         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
710         [ "$STATUS" == "scanning-phase1" ] ||
711                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
712
713         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
714         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
715                 mdd.${MDT_DEV}.lfsck_namespace |
716                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
717                 $SHOW_NAMESPACE
718                 error "(7) unexpected status"
719         }
720
721         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
722         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
723
724         local repaired=$($SHOW_NAMESPACE |
725                          awk '/^dirent_repaired/ { print $2 }')
726         # for interop with old server
727         [ -z "$repaired" ] &&
728                 repaired=$($SHOW_NAMESPACE |
729                          awk '/^updated_phase1/ { print $2 }')
730
731         [ $repaired -ge 2 ] ||
732                 error "(9) Fail to generate FID-in-dirent for IGIF: $repaired"
733
734         run_e2fsck_on_mdt0
735
736         mount_client $MOUNT || error "(10) Fail to start client!"
737
738         #define OBD_FAIL_FID_LOOKUP     0x1505
739         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
740         stat $DIR/$tdir/dummy > /dev/null || error "(11) no FID-in-LMA."
741
742         ls $DIR/$tdir/ > /dev/null || error "(12) no FID-in-dirent."
743
744         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
745         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
746         local dummyname=$($LFS fid2path $DIR $dummyfid)
747         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
748                 error "(13) Fail to generate linkEA: $dummyfid $dummyname"
749 }
750 run_test 5 "LFSCK can handle IGIF object upgrading"
751
752 test_6a() {
753         lfsck_prep 5 5
754
755         #define OBD_FAIL_LFSCK_DELAY1           0x1600
756         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
757         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
758
759         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
760         [ "$STATUS" == "scanning-phase1" ] ||
761                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
762
763         # Sleep 3 sec to guarantee at least one object processed by LFSCK
764         sleep 3
765         # Fail the LFSCK to guarantee there is at least one checkpoint
766         #define OBD_FAIL_LFSCK_FATAL1           0x1608
767         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001608
768         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
769                 mdd.${MDT_DEV}.lfsck_namespace |
770                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
771                 $SHOW_NAMESPACE
772                 error "(4) unexpected status"
773         }
774
775         local POS0=$($SHOW_NAMESPACE |
776                      awk '/^last_checkpoint_position/ { print $2 }' |
777                      tr -d ',')
778
779         #define OBD_FAIL_LFSCK_DELAY1           0x1600
780         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
781         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
782
783         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
784         [ "$STATUS" == "scanning-phase1" ] ||
785                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
786
787         local POS1=$($SHOW_NAMESPACE |
788                      awk '/^latest_start_position/ { print $2 }' |
789                      tr -d ',')
790         [[ $POS0 -lt $POS1 ]] ||
791                 error "(7) Expect larger than: $POS0, but got $POS1"
792
793         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
794         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
795                 mdd.${MDT_DEV}.lfsck_namespace |
796                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
797                 $SHOW_NAMESPACE
798                 error "(8) unexpected status"
799         }
800 }
801 run_test 6a "LFSCK resumes from last checkpoint (1)"
802
803 test_6b() {
804         lfsck_prep 5 5
805
806         #define OBD_FAIL_LFSCK_DELAY2           0x1601
807         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
808         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
809
810         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
811         [ "$STATUS" == "scanning-phase1" ] ||
812                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
813
814         # Sleep 5 sec to guarantee that we are in the directory scanning
815         sleep 5
816         # Fail the LFSCK to guarantee there is at least one checkpoint
817         #define OBD_FAIL_LFSCK_FATAL2           0x1609
818         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
819         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
820                 mdd.${MDT_DEV}.lfsck_namespace |
821                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
822                 $SHOW_NAMESPACE
823                 error "(4) unexpected status"
824         }
825
826         local O_POS0=$($SHOW_NAMESPACE |
827                        awk '/^last_checkpoint_position/ { print $2 }' |
828                        tr -d ',')
829
830         local D_POS0=$($SHOW_NAMESPACE |
831                        awk '/^last_checkpoint_position/ { print $4 }')
832
833         #define OBD_FAIL_LFSCK_DELAY2           0x1601
834         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
835         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
836
837         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
838         [ "$STATUS" == "scanning-phase1" ] ||
839                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
840
841         local O_POS1=$($SHOW_NAMESPACE |
842                        awk '/^latest_start_position/ { print $2 }' |
843                        tr -d ',')
844         local D_POS1=$($SHOW_NAMESPACE |
845                        awk '/^latest_start_position/ { print $4 }')
846
847         echo "Additional debug for 6b"
848         $SHOW_NAMESPACE
849         if [ "$D_POS0" == "N/A" -o "$D_POS0" == "0x0" \
850              -o "$D_POS1" == "0x0" -o "$D_POS1" == "N/A" ]; then
851                 [[ $O_POS0 -lt $O_POS1 ]] ||
852                         error "(7.1) $O_POS1 is not larger than $O_POS0"
853         else
854                 [[ $D_POS0 -lt $D_POS1 ]] ||
855                         error "(7.2) $D_POS1 is not larger than $D_POS0"
856         fi
857
858         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
859         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
860                 mdd.${MDT_DEV}.lfsck_namespace |
861                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
862                 $SHOW_NAMESPACE
863                 error "(8) unexpected status"
864         }
865 }
866 run_test 6b "LFSCK resumes from last checkpoint (2)"
867
868 test_7a()
869 {
870         lfsck_prep 5 5
871         umount_client $MOUNT
872
873         #define OBD_FAIL_LFSCK_DELAY2           0x1601
874         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
875         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
876
877         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
878         [ "$STATUS" == "scanning-phase1" ] ||
879                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
880
881         # Sleep 3 sec to guarantee at least one object processed by LFSCK
882         sleep 3
883         echo "stop $SINGLEMDS"
884         stop $SINGLEMDS > /dev/null || error "(4) Fail to stop MDS!"
885
886         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
887         echo "start $SINGLEMDS"
888         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
889                 error "(5) Fail to start MDS!"
890
891         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
892                 mdd.${MDT_DEV}.lfsck_namespace |
893                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
894                 $SHOW_NAMESPACE
895                 error "(6) unexpected status"
896         }
897 }
898 run_test 7a "non-stopped LFSCK should auto restarts after MDS remount (1)"
899
900 test_7b()
901 {
902         lfsck_prep 2 2
903
904         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
905         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
906         for ((i = 0; i < 20; i++)); do
907                 touch $DIR/$tdir/dummy${i}
908         done
909
910         #define OBD_FAIL_LFSCK_DELAY3           0x1602
911         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1602
912         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
913         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
914                 mdd.${MDT_DEV}.lfsck_namespace |
915                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
916                 $SHOW_NAMESPACE
917                 error "(4) unexpected status"
918         }
919
920         umount_client $MOUNT
921         echo "stop $SINGLEMDS"
922         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop MDS!"
923
924         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
925         echo "start $SINGLEMDS"
926         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
927                 error "(6) Fail to start MDS!"
928
929         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
930                 mdd.${MDT_DEV}.lfsck_namespace |
931                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
932                 $SHOW_NAMESPACE
933                 error "(7) unexpected status"
934         }
935 }
936 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
937
938 test_8()
939 {
940         echo "formatall"
941         formatall > /dev/null
942         echo "setupall"
943         setupall > /dev/null
944
945         lfsck_prep 20 20
946
947         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
948         [ "$STATUS" == "init" ] ||
949                 error "(2) Expect 'init', but got '$STATUS'"
950
951         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
952         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
953         mkdir $DIR/$tdir/crashed
954
955         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
956         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
957         for ((i = 0; i < 5; i++)); do
958                 touch $DIR/$tdir/dummy${i}
959         done
960
961         umount_client $MOUNT || error "(3) Fail to stop client!"
962
963         #define OBD_FAIL_LFSCK_DELAY2           0x1601
964         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1601
965         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
966
967         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
968         [ "$STATUS" == "scanning-phase1" ] ||
969                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
970
971         $STOP_LFSCK || error "(6) Fail to stop LFSCK!"
972
973         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
974         [ "$STATUS" == "stopped" ] ||
975                 error "(7) Expect 'stopped', but got '$STATUS'"
976
977         $START_NAMESPACE || error "(8) Fail to start LFSCK for namespace!"
978
979         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
980         [ "$STATUS" == "scanning-phase1" ] ||
981                 error "(9) Expect 'scanning-phase1', but got '$STATUS'"
982
983         #define OBD_FAIL_LFSCK_FATAL2           0x1609
984         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
985         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
986                 mdd.${MDT_DEV}.lfsck_namespace |
987                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
988                 $SHOW_NAMESPACE
989                 error "(10) unexpected status"
990         }
991
992         #define OBD_FAIL_LFSCK_DELAY1           0x1600
993         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
994         $START_NAMESPACE || error "(11) Fail to start LFSCK for namespace!"
995
996         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
997         [ "$STATUS" == "scanning-phase1" ] ||
998                 error "(12) Expect 'scanning-phase1', but got '$STATUS'"
999
1000         #define OBD_FAIL_LFSCK_CRASH            0x160a
1001         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
1002         sleep 5
1003
1004         echo "stop $SINGLEMDS"
1005         stop $SINGLEMDS > /dev/null || error "(13) Fail to stop MDS!"
1006
1007         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
1008         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
1009
1010         echo "start $SINGLEMDS"
1011         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
1012                 error "(14) Fail to start MDS!"
1013
1014         local timeout=$(max_recovery_time)
1015         local timer=0
1016
1017         while [ $timer -lt $timeout ]; do
1018                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1019                         mdt.${MDT_DEV}.recovery_status |
1020                         awk '/^status/ { print \\\$2 }'")
1021                 [ "$STATUS" != "RECOVERING" ] && break;
1022                 sleep 1
1023                 timer=$((timer + 1))
1024         done
1025
1026         [ $timer != $timeout ] ||
1027                 error "(14.1) recovery timeout"
1028
1029         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1030         [ "$STATUS" == "crashed" ] ||
1031                 error "(15) Expect 'crashed', but got '$STATUS'"
1032
1033         #define OBD_FAIL_LFSCK_DELAY2           0x1601
1034         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
1035         $START_NAMESPACE || error "(16) Fail to start LFSCK for namespace!"
1036
1037         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1038         [ "$STATUS" == "scanning-phase1" ] ||
1039                 error "(17) Expect 'scanning-phase1', but got '$STATUS'"
1040
1041         echo "stop $SINGLEMDS"
1042         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop MDS!"
1043
1044         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
1045         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
1046
1047         echo "start $SINGLEMDS"
1048         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
1049                 error "(19) Fail to start MDS!"
1050
1051         timer=0
1052         while [ $timer -lt $timeout ]; do
1053                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1054                         mdt.${MDT_DEV}.recovery_status |
1055                         awk '/^status/ { print \\\$2 }'")
1056                 [ "$STATUS" != "RECOVERING" ] && break;
1057                 sleep 1
1058                 timer=$((timer + 1))
1059         done
1060
1061         [ $timer != $timeout ] ||
1062                 error "(19.1) recovery timeout"
1063
1064         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1065         [ "$STATUS" == "paused" ] ||
1066                 error "(20) Expect 'paused', but got '$STATUS'"
1067
1068         echo "stop $SINGLEMDS"
1069         stop $SINGLEMDS > /dev/null || error "(20.1) Fail to stop MDS!"
1070
1071         echo "start $SINGLEMDS without resume LFSCK"
1072         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SKIP_LFSCK > /dev/null ||
1073                 error "(20.2) Fail to start MDS!"
1074
1075         timer=0
1076         while [ $timer -lt $timeout ]; do
1077                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
1078                         mdt.${MDT_DEV}.recovery_status |
1079                         awk '/^status/ { print \\\$2 }'")
1080                 [ "$STATUS" != "RECOVERING" ] && break;
1081                 sleep 1
1082                 timer=$((timer + 1))
1083         done
1084
1085         [ $timer != $timeout ] ||
1086                 error "(20.3) recovery timeout"
1087
1088         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1089         [ "$STATUS" == "paused" ] ||
1090                 error "(20.4) Expect 'paused', but got '$STATUS'"
1091
1092         #define OBD_FAIL_LFSCK_DELAY3           0x1602
1093         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1602
1094
1095         $START_NAMESPACE || error "(21) Fail to start LFSCK for namespace!"
1096         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1097                 mdd.${MDT_DEV}.lfsck_namespace |
1098                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
1099                 $SHOW_NAMESPACE
1100                 error "(22) unexpected status"
1101         }
1102
1103         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1104         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
1105                 error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
1106
1107         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1108         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1109                 mdd.${MDT_DEV}.lfsck_namespace |
1110                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1111                 $SHOW_NAMESPACE
1112                 error "(24) unexpected status"
1113         }
1114
1115         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
1116         [ -z "$FLAGS" ] || error "(25) Expect empty flags, but got '$FLAGS'"
1117 }
1118 run_test 8 "LFSCK state machine"
1119
1120 test_9a() {
1121         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1122                 skip "Testing on UP system, the speed may be inaccurate."
1123                 return 0
1124         fi
1125
1126         check_mount_and_prep
1127         $LFS mkdir -i 0 $DIR/$tdir/lfsck || error "(1) Fail to mkdir lfsck"
1128         $LFS setstripe -c 1 -i -1 $DIR/$tdir/lfsck
1129         createmany -o $DIR/$tdir/lfsck/f 5000
1130
1131         local BASE_SPEED1=100
1132         local RUN_TIME1=10
1133         $START_LAYOUT -r -s $BASE_SPEED1 || error "(2) Fail to start LFSCK!"
1134
1135         sleep $RUN_TIME1
1136         STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
1137         [ "$STATUS" == "scanning-phase1" ] ||
1138                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
1139
1140         local SPEED=$($SHOW_LAYOUT |
1141                       awk '/^average_speed_phase1/ { print $2 }')
1142
1143         # There may be time error, normally it should be less than 2 seconds.
1144         # We allow another 20% schedule error.
1145         local TIME_DIFF=2
1146         # MAX_MARGIN = 1.3 = 13 / 10
1147         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
1148                            RUN_TIME1 * 13 / 10))
1149         [ $SPEED -lt $MAX_SPEED ] || {
1150                 $SHOW_LAYOUT
1151                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1152                 error "(4) Speed $SPEED, expected < $MAX_SPEED"
1153         }
1154
1155         # adjust speed limit
1156         local BASE_SPEED2=300
1157         local RUN_TIME2=10
1158         do_facet $SINGLEMDS \
1159                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1160         sleep $RUN_TIME2
1161
1162         SPEED=$($SHOW_LAYOUT | awk '/^average_speed_phase1/ { print $2 }')
1163         # MIN_MARGIN = 0.7 = 7 / 10
1164         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
1165                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
1166                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1167         [ $SPEED -gt $MIN_SPEED ] || {
1168                 if [ $mds1_FSTYPE != ldiskfs ]; then
1169                         error_ignore LU-5624 \
1170                         "(5.1) Got speed $SPEED, expected more than $MIN_SPEED"
1171                 else
1172                         error \
1173                         "(5.2) Got speed $SPEED, expected more than $MIN_SPEED"
1174                 fi
1175         }
1176
1177         # MAX_MARGIN = 1.3 = 13 / 10
1178         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
1179                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
1180                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1181         [ $SPEED -lt $MAX_SPEED ] || {
1182                 $SHOW_LAYOUT
1183                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1184                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1185                 error "(6) Speed $SPEED, expected < $MAX_SPEED"
1186         }
1187
1188         do_nodes $(comma_list $(mdts_nodes)) \
1189                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1190         do_nodes $(comma_list $(osts_nodes)) \
1191                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1192
1193         wait_update_facet $SINGLEMDS \
1194                 "$LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout |
1195                 awk '/^status/ { print \\\$2 }'" "completed" 30 ||
1196                 error "(7) Failed to get expected 'completed'"
1197 }
1198 run_test 9a "LFSCK speed control (1)"
1199
1200 test_9b() {
1201         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1202                 skip "Testing on UP system, the speed may be inaccurate."
1203                 return 0
1204         fi
1205
1206         lfsck_prep 0 0
1207
1208         echo "Preparing another 50 * 50 files (with error) at $(date)."
1209         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1210         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1211         createmany -d $DIR/$tdir/d 50
1212         createmany -m $DIR/$tdir/f 50
1213         for ((i = 0; i < 50; i++)); do
1214                 createmany -m $DIR/$tdir/d${i}/f 50 > /dev/null
1215         done
1216
1217         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
1218         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
1219         $START_NAMESPACE -r || error "(4) Fail to start LFSCK!"
1220         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1221                 mdd.${MDT_DEV}.lfsck_namespace |
1222                 awk '/^status/ { print \\\$2 }'" "stopped" 10 || {
1223                 $SHOW_NAMESPACE
1224                 error "(5) unexpected status"
1225         }
1226
1227         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1228         echo "Prepared at $(date)."
1229
1230         local BASE_SPEED1=50
1231         local RUN_TIME1=10
1232         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
1233
1234         sleep $RUN_TIME1
1235         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1236         [ "$STATUS" == "scanning-phase2" ] ||
1237                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
1238
1239         local SPEED=$($SHOW_NAMESPACE |
1240                       awk '/^average_speed_phase2/ { print $2 }')
1241         # There may be time error, normally it should be less than 2 seconds.
1242         # We allow another 20% schedule error.
1243         local TIME_DIFF=2
1244         # MAX_MARGIN = 1.3 = 13 / 10
1245         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
1246                           RUN_TIME1 * 13 / 10))
1247         [ $SPEED -lt $MAX_SPEED ] || {
1248                 $SHOW_NAMESPACE
1249                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1250                 error "(8) Speed $SPEED, expected < $MAX_SPEED"
1251         }
1252
1253         # adjust speed limit
1254         local BASE_SPEED2=150
1255         local RUN_TIME2=10
1256         do_facet $SINGLEMDS \
1257                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1258         sleep $RUN_TIME2
1259
1260         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
1261         # MIN_MARGIN = 0.7 = 7 / 10
1262         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
1263                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
1264                            (RUN_TIME1 + RUN_TIME2) * 7 / 10))
1265         [ $SPEED -gt $MIN_SPEED ] || {
1266                 if [ $mds1_FSTYPE != ldiskfs ]; then
1267                         error_ignore LU-5624 \
1268                         "(9.1) Got speed $SPEED, expected more than $MIN_SPEED"
1269                 else
1270                         error \
1271                         "(9.2) Got speed $SPEED, expected more than $MIN_SPEED"
1272                 fi
1273         }
1274
1275         # MAX_MARGIN = 1.3 = 13 / 10
1276         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
1277                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
1278                      (RUN_TIME1 + RUN_TIME2) * 13 / 10))
1279         [ $SPEED -lt $MAX_SPEED ] || {
1280                 $SHOW_NAMESPACE
1281                 log "speed1: $BASE_SPEED1 time1: $RUN_TIME1"
1282                 log "speed2: $BASE_SPEED2 time2: $RUN_TIME2"
1283                 error "(10) Speed $SPEED, expected < $MAX_SPEED"
1284         }
1285
1286         do_nodes $(comma_list $(mdts_nodes)) \
1287                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1288         do_nodes $(comma_list $(osts_nodes)) \
1289                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1290         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1291                 mdd.${MDT_DEV}.lfsck_namespace |
1292                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1293                 $SHOW_NAMESPACE
1294                 error "(11) unexpected status"
1295         }
1296 }
1297 run_test 9b "LFSCK speed control (2)"
1298
1299 test_10()
1300 {
1301         [[ $mds1_FSTYPE == ldiskfs ]] || skip "lookup(..)/linkea on ZFS issue"
1302
1303         lfsck_prep 1 1
1304
1305         echo "Preparing more files with error at $(date)."
1306         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
1307         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
1308
1309         for ((i = 0; i < 1000; i = $((i+2)))); do
1310                 mkdir -p $DIR/$tdir/d${i}
1311                 touch $DIR/$tdir/f${i}
1312                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1313         done
1314
1315         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1316         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1317
1318         for ((i = 1; i < 1000; i = $((i+2)))); do
1319                 mkdir -p $DIR/$tdir/d${i}
1320                 touch $DIR/$tdir/f${i}
1321                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1322         done
1323
1324         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1325         echo "Prepared at $(date)."
1326
1327         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
1328
1329         umount_client $MOUNT
1330         mount_client $MOUNT || error "(3) Fail to start client!"
1331
1332         $START_NAMESPACE -r -s 100 || error "(5) Fail to start LFSCK!"
1333
1334         sleep 10
1335         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1336         [ "$STATUS" == "scanning-phase1" ] ||
1337                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
1338
1339         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
1340
1341         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
1342
1343         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
1344
1345         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
1346
1347         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
1348
1349         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
1350
1351         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
1352
1353         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
1354                 error "(14) Fail to softlink!"
1355
1356         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1357         [ "$STATUS" == "scanning-phase1" ] ||
1358                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
1359
1360         do_nodes $(comma_list $(mdts_nodes)) \
1361                 $LCTL set_param -n mdd.*.lfsck_speed_limit 0
1362         do_nodes $(comma_list $(osts_nodes)) \
1363                 $LCTL set_param -n obdfilter.*.lfsck_speed_limit 0
1364         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1365                 mdd.${MDT_DEV}.lfsck_namespace |
1366                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1367                 $SHOW_NAMESPACE
1368                 error "(16) unexpected status"
1369         }
1370 }
1371 run_test 10 "System is available during LFSCK scanning"
1372
1373 # remove LAST_ID
1374 ost_remove_lastid() {
1375         local ost=$1
1376         local idx=$2
1377         local rcmd="do_facet ost${ost}"
1378
1379         echo "remove LAST_ID on ost${ost}: idx=${idx}"
1380
1381         # step 1: local mount
1382         mount_fstype ost${ost} || return 1
1383         # step 2: remove the specified LAST_ID
1384         ${rcmd} rm -fv $(facet_mntpt ost${ost})/O/${idx}/{LAST_ID,d0/0}
1385         # step 3: umount
1386         unmount_fstype ost${ost} || return 2
1387 }
1388
1389 test_11a() {
1390         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1391                 skip "MDS older than 2.5.55, LU-1267"
1392
1393         check_mount_and_prep
1394         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1395         createmany -o $DIR/$tdir/f 64 || error "(0) Fail to create 64 files."
1396
1397         echo "stopall"
1398         stopall > /dev/null
1399
1400         ost_remove_lastid 1 0 || error "(1) Fail to remove LAST_ID"
1401
1402         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
1403                 error "(2) Fail to start ost1"
1404
1405         #define OBD_FAIL_LFSCK_DELAY4           0x160e
1406         do_facet ost1 $LCTL set_param fail_val=3 fail_loc=0x160e
1407
1408         echo "trigger LFSCK for layout on ost1 to rebuild the LAST_ID(s)"
1409         $START_LAYOUT_ON_OST -r || error "(4) Fail to start LFSCK on OST!"
1410
1411         wait_update_facet ost1 "$LCTL get_param -n \
1412                 obdfilter.${OST_DEV}.lfsck_layout |
1413                 awk '/^flags/ { print \\\$2 }'" "crashed_lastid" 60 || {
1414                 $SHOW_LAYOUT_ON_OST
1415                 error "(5) unexpected status"
1416         }
1417
1418         do_facet ost1 $LCTL set_param fail_val=0 fail_loc=0
1419
1420         wait_update_facet ost1 "$LCTL get_param -n \
1421                 obdfilter.${OST_DEV}.lfsck_layout |
1422                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1423                 $SHOW_LAYOUT_ON_OST
1424                 error "(6) unexpected status"
1425         }
1426
1427         echo "the LAST_ID(s) should have been rebuilt"
1428         FLAGS=$($SHOW_LAYOUT_ON_OST | awk '/^flags/ { print $2 }')
1429         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
1430 }
1431 run_test 11a "LFSCK can rebuild lost last_id"
1432
1433 test_11b() {
1434         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1435                 skip "MDS older than 2.5.55, LU-1267"
1436
1437         check_mount_and_prep
1438         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1439
1440         echo "set fail_loc=0x160d to skip the updating LAST_ID on-disk"
1441         #define OBD_FAIL_LFSCK_SKIP_LASTID      0x160d
1442         do_facet ost1 $LCTL set_param fail_loc=0x160d
1443
1444         local count=$(precreated_ost_obj_count 0 0)
1445
1446         createmany -o $DIR/$tdir/f $((count + 32))
1447
1448         local proc_path="${FSNAME}-OST0000-osc-MDT0000"
1449         local seq=$(do_facet mds1 $LCTL get_param -n \
1450                     osp.${proc_path}.prealloc_last_seq)
1451         local id_used=$(do_facet mds1 $LCTL get_param -n \
1452                         osp.${proc_path}.prealloc_last_id)
1453
1454         umount_client $MOUNT
1455         stop ost1 || error "(1) Fail to stop ost1"
1456
1457         #define OBD_FAIL_OST_ENOSPC              0x215
1458         do_facet ost1 $LCTL set_param fail_loc=0x215
1459
1460         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1461                 error "(2) Fail to start ost1"
1462
1463         for ((i = 0; i < 60; i++)); do
1464                 id_ost1=$(do_facet ost1 \
1465                           "$LCTL get_param -n obdfilter.$ost1_svc.last_id" |
1466                           awk -F: "/$seq/ { print \$2 }")
1467                 [ -n "$id_ost1" ] && break
1468                 sleep 1
1469         done
1470
1471         echo "the on-disk LAST_ID should be smaller than the expected one"
1472         [ $id_used -gt $id_ost1 ] ||
1473                 error "(4) expect id_used '$id_used' > id_ost1 '$id_ost1'"
1474
1475         echo "trigger LFSCK for layout on ost1 to rebuild the on-disk LAST_ID"
1476         $START_LAYOUT_ON_OST -r || error "(5) Fail to start LFSCK on OST!"
1477
1478         wait_update_facet ost1 \
1479                 "$LCTL get_param -n obdfilter.$ost1_svc.lfsck_layout |
1480                  awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1481                 $SHOW_LAYOUT_ON_OST
1482                 error "(6) unexpected status"
1483         }
1484
1485         stop ost1 || error "(7) Fail to stop ost1"
1486
1487         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1488                 error "(8) Fail to start ost1"
1489
1490         echo "the on-disk LAST_ID should have been rebuilt"
1491         # last_id may be larger than $id_used if objects were created/skipped
1492         wait_update_facet_cond ost1 \
1493                 "$LCTL get_param -n obdfilter.$ost1_svc.last_id |
1494                  awk -F: '/$seq/ { print \\\$2 }'" "-ge" "$id_used" 60 || {
1495                 do_facet ost1 $LCTL get_param obdfilter.$ost1_svc.last_id
1496                 error "(9) expect last_id >= id_used $seq:$id_used"
1497         }
1498
1499         do_facet ost1 $LCTL set_param fail_loc=0
1500         stopall || error "(10) Fail to stopall"
1501 }
1502 run_test 11b "LFSCK can rebuild crashed last_id"
1503
1504 test_12a() {
1505         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1506         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1507                 skip "MDS older than 2.5.55, LU-3950"
1508
1509         check_mount_and_prep
1510         for k in $(seq $MDSCOUNT); do
1511                 $LFS mkdir -i $((k - 1)) $DIR/$tdir/${k}
1512                 createmany -o $DIR/$tdir/${k}/f 100 ||
1513                         error "(0) Fail to create 100 files."
1514         done
1515
1516         echo "Start namespace LFSCK on all targets by single command (-s 1)."
1517         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1518                 -s 1 -r || error "(2) Fail to start LFSCK on all devices!"
1519
1520         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1521         wait_all_targets namespace scanning-phase1 3
1522
1523         echo "Stop namespace LFSCK on all targets by single lctl command."
1524         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1525                 error "(4) Fail to stop LFSCK on all devices!"
1526
1527         echo "All the LFSCK targets should be in 'stopped' status."
1528         wait_all_targets_blocked namespace stopped 5
1529
1530         echo "Re-start namespace LFSCK on all targets by single command (-s 0)."
1531         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1532                 -s 0 -r || error "(6) Fail to start LFSCK on all devices!"
1533
1534         echo "All the LFSCK targets should be in 'completed' status."
1535         wait_all_targets_blocked namespace completed 7
1536
1537         start_full_debug_logging
1538
1539         echo "Start layout LFSCK on all targets by single command (-s 1)."
1540         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1541                 -s 1 -r || error "(8) Fail to start LFSCK on all devices!"
1542
1543         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1544         wait_all_targets layout scanning-phase1 9
1545
1546         echo "Stop layout LFSCK on all targets by single lctl command."
1547         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1548                 error "(10) Fail to stop LFSCK on all devices!"
1549
1550         echo "All the LFSCK targets should be in 'stopped' status."
1551         wait_all_targets_blocked layout stopped 11
1552
1553         for k in $(seq $OSTCOUNT); do
1554                 local STATUS=$(do_facet ost${k} $LCTL get_param -n \
1555                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1556                                 awk '/^status/ { print $2 }')
1557                 [ "$STATUS" == "stopped" ] ||
1558                         error "(12) OST${k} Expect 'stopped', but got '$STATUS'"
1559         done
1560
1561         echo "Re-start layout LFSCK on all targets by single command (-s 0)."
1562         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1563                 -s 0 -r || error "(13) Fail to start LFSCK on all devices!"
1564
1565         echo "All the LFSCK targets should be in 'completed' status."
1566         wait_all_targets_blocked layout completed 14
1567
1568         stop_full_debug_logging
1569 }
1570 run_test 12a "single command to trigger LFSCK on all devices"
1571
1572 test_12b() {
1573         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1574                 skip "MDS older than 2.5.55, LU-3950"
1575
1576         check_mount_and_prep
1577
1578         echo "Start LFSCK without '-M' specified."
1579         do_facet mds1 $LCTL lfsck_start -A -r ||
1580                 error "(0) Fail to start LFSCK without '-M'"
1581
1582         wait_all_targets_blocked namespace completed 1
1583         wait_all_targets_blocked layout completed 2
1584
1585         local count=$(do_facet mds1 $LCTL dl |
1586                       awk '{ print $3 }' | grep mdt | wc -l)
1587         if [ $count -gt 1 ]; then
1588                 echo
1589                 echo "Start layout LFSCK on the node with multipe targets,"
1590                 echo "but not specify '-M'/'-A' option. Should get failure."
1591                 echo
1592                 do_facet mds1 $LCTL lfsck_start -t layout -r &&
1593                         error "(3) Start layout LFSCK should fail" || true
1594         fi
1595 }
1596 run_test 12b "auto detect Lustre device"
1597
1598 test_13() {
1599         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1600                 skip "MDS older than 2.5.55, LU-3593"
1601
1602         echo "#####"
1603         echo "The lmm_oi in layout EA should be consistent with the MDT-object"
1604         echo "FID; otherwise, the LFSCK should re-generate the lmm_oi from the"
1605         echo "MDT-object FID."
1606         echo "#####"
1607
1608         check_mount_and_prep
1609
1610         echo "Inject failure stub to simulate bad lmm_oi"
1611         #define OBD_FAIL_LFSCK_BAD_LMMOI        0x160f
1612         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160f
1613         createmany -o $DIR/$tdir/f 1
1614         $LFS setstripe -E 1M -S 1M -E -1 $DIR/$tdir/f1 ||
1615                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1616         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1617
1618         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
1619         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1620
1621         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1622                 mdd.${MDT_DEV}.lfsck_layout |
1623                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1624                 $SHOW_LAYOUT
1625                 error "(2) unexpected status"
1626         }
1627
1628         local repaired=$($SHOW_LAYOUT |
1629                          awk '/^repaired_others/ { print $2 }')
1630         [ $repaired -eq 2 ] ||
1631                 error "(3) Fail to repair crashed lmm_oi: $repaired"
1632 }
1633 run_test 13 "LFSCK can repair crashed lmm_oi"
1634
1635 test_14a() {
1636         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1637                 skip "MDS older than 2.5.55, LU-3590"
1638
1639         echo "#####"
1640         echo "The OST-object referenced by the MDT-object should be there;"
1641         echo "otherwise, the LFSCK should re-create the missing OST-object."
1642         echo "without '--delay-create-ostobj' option."
1643         echo "#####"
1644
1645         check_mount_and_prep
1646         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1647
1648         echo "Inject failure stub to simulate dangling referenced MDT-object"
1649         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1650         do_facet ost1 $LCTL set_param fail_loc=0x1610
1651         local count=$(precreated_ost_obj_count 0 0)
1652
1653         createmany -o $DIR/$tdir/f $((count + 16)) ||
1654                 error "(0.1) Fail to create $DIR/$tdir/fx"
1655         touch $DIR/$tdir/guard0
1656
1657         for ((i = 0; i < 16; i++)); do
1658                 $LFS setstripe -E 512K -S 256K -o 0 -E 2M \
1659                         $DIR/$tdir/f_comp${i} ||
1660                         error "(0.2) Fail to create $DIR/$tdir/f_comp${i}"
1661         done
1662         touch $DIR/$tdir/guard1
1663
1664         do_facet ost1 $LCTL set_param fail_loc=0
1665
1666         start_full_debug_logging
1667
1668         # exhaust other pre-created dangling cases
1669         count=$(precreated_ost_obj_count 0 0)
1670         createmany -o $DIR/$tdir/a $count ||
1671                 error "(0.5) Fail to create $count files."
1672
1673         echo "'ls' should fail because of dangling referenced MDT-object"
1674         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1675
1676         echo "Trigger layout LFSCK to find out dangling reference"
1677         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1678
1679         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1680                 mdd.${MDT_DEV}.lfsck_layout |
1681                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1682                 $SHOW_LAYOUT
1683                 error "(3) unexpected status"
1684         }
1685
1686         local repaired=$($SHOW_LAYOUT |
1687                          awk '/^repaired_dangling/ { print $2 }')
1688         [ $repaired -ge 32 ] ||
1689                 error "(4) Fail to repair dangling reference: $repaired"
1690
1691         echo "'stat' should fail because of not repair dangling by default"
1692         stat $DIR/$tdir/guard0 > /dev/null 2>&1 &&
1693                 error "(5.1) stat should fail"
1694         stat $DIR/$tdir/guard1 > /dev/null 2>&1 &&
1695                 error "(5.2) stat should fail"
1696
1697         echo "Trigger layout LFSCK to repair dangling reference"
1698         $START_LAYOUT -r -c || error "(6) Fail to start LFSCK for layout!"
1699
1700         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1701                 mdd.${MDT_DEV}.lfsck_layout |
1702                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1703                 $SHOW_LAYOUT
1704                 error "(7) unexpected status"
1705         }
1706
1707         # There may be some async LFSCK updates in processing, wait for
1708         # a while until the target reparation has been done. LU-4970.
1709
1710         echo "'stat' should success after layout LFSCK repairing"
1711         wait_update_facet client "stat $DIR/$tdir/guard0 |
1712                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1713                 stat $DIR/$tdir/guard0
1714                 $SHOW_LAYOUT
1715                 error "(8.1) unexpected size"
1716         }
1717
1718         wait_update_facet client "stat $DIR/$tdir/guard1 |
1719                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1720                 stat $DIR/$tdir/guard1
1721                 $SHOW_LAYOUT
1722                 error "(8.2) unexpected size"
1723         }
1724
1725         repaired=$($SHOW_LAYOUT |
1726                          awk '/^repaired_dangling/ { print $2 }')
1727         [ $repaired -ge 32 ] ||
1728                 error "(9) Fail to repair dangling reference: $repaired"
1729
1730         stop_full_debug_logging
1731
1732         echo "stopall to cleanup object cache"
1733         stopall > /dev/null
1734         echo "setupall"
1735         setupall > /dev/null
1736 }
1737 run_test 14a "LFSCK can repair MDT-object with dangling LOV EA reference (1)"
1738
1739 test_14b() {
1740         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1741                 skip "MDS older than 2.5.55, LU-3590"
1742
1743         echo "#####"
1744         echo "The OST-object referenced by the MDT-object should be there;"
1745         echo "otherwise, the LFSCK should re-create the missing OST-object."
1746         echo "with '--delay-create-ostobj' option."
1747         echo "#####"
1748
1749         check_mount_and_prep
1750         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1751
1752         echo "Inject failure stub to simulate dangling referenced MDT-object"
1753         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1754         do_facet ost1 $LCTL set_param fail_loc=0x1610
1755         local count=$(precreated_ost_obj_count 0 0)
1756
1757         createmany -o $DIR/$tdir/f $((count + 31))
1758         touch $DIR/$tdir/guard
1759         do_facet ost1 $LCTL set_param fail_loc=0
1760
1761         start_full_debug_logging
1762
1763         # exhaust other pre-created dangling cases
1764         count=$(precreated_ost_obj_count 0 0)
1765         createmany -o $DIR/$tdir/a $count ||
1766                 error "(0) Fail to create $count files."
1767
1768         echo "'ls' should fail because of dangling referenced MDT-object"
1769         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1770
1771         echo "Trigger layout LFSCK to find out dangling reference"
1772         $START_LAYOUT -r -o -d || error "(2) Fail to start LFSCK for layout!"
1773
1774         wait_all_targets_blocked layout completed 3
1775
1776         local repaired=$($SHOW_LAYOUT |
1777                          awk '/^repaired_dangling/ { print $2 }')
1778         [ $repaired -ge 32 ] ||
1779                 error "(4) Fail to repair dangling reference: $repaired"
1780
1781         echo "'stat' should fail because of not repair dangling by default"
1782         stat $DIR/$tdir/guard > /dev/null 2>&1 && error "(5) stat should fail"
1783
1784         echo "Trigger layout LFSCK to repair dangling reference"
1785         $START_LAYOUT -r -o -c -d || error "(6) Fail to start LFSCK for layout!"
1786
1787         wait_all_targets_blocked layout completed 7
1788
1789         # There may be some async LFSCK updates in processing, wait for
1790         # a while until the target reparation has been done. LU-4970.
1791
1792         echo "'stat' should success after layout LFSCK repairing"
1793         wait_update_facet client "stat $DIR/$tdir/guard |
1794                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1795                 stat $DIR/$tdir/guard
1796                 $SHOW_LAYOUT
1797                 error "(8) unexpected size"
1798         }
1799
1800         repaired=$($SHOW_LAYOUT |
1801                          awk '/^repaired_dangling/ { print $2 }')
1802         [ $repaired -ge 32 ] ||
1803                 error "(9) Fail to repair dangling reference: $repaired"
1804
1805         stop_full_debug_logging
1806
1807         echo "stopall to cleanup object cache"
1808         stopall > /dev/null
1809         echo "setupall"
1810         setupall > /dev/null
1811 }
1812 run_test 14b "LFSCK can repair MDT-object with dangling LOV EA reference (2)"
1813
1814 test_15a() {
1815         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1816                 skip "MDS older than 2.5.55, LU-3591"
1817
1818         echo "#####"
1819         echo "If the OST-object referenced by the MDT-object back points"
1820         echo "to some non-exist MDT-object, then the LFSCK should repair"
1821         echo "the OST-object to back point to the right MDT-object."
1822         echo "#####"
1823
1824         check_mount_and_prep
1825         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1826
1827         echo "Inject failure stub to make the OST-object to back point to"
1828         echo "non-exist MDT-object."
1829         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
1830
1831         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
1832         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1833         $LFS setstripe -E 1M -S 256K -c 1 -E -1 -S 512K -c $OSTCOUNT \
1834                 $DIR/$tdir/f1 ||
1835                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1836         # 'dd' will trigger punch RPC firstly on every OST-objects.
1837         # So even though some OST-object will not be write by 'dd',
1838         # as long as it is allocated (may be NOT allocated in pfl_3b)
1839         # its layout information will be set also.
1840         dd if=/dev/zero of=$DIR/$tdir/f1 bs=4K count=257
1841         cancel_lru_locks osc
1842         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1843
1844         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1845         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1846
1847         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1848                 mdd.${MDT_DEV}.lfsck_layout |
1849                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1850                 $SHOW_LAYOUT
1851                 error "(2) unexpected status"
1852         }
1853
1854         local repaired=$($SHOW_LAYOUT |
1855                          awk '/^repaired_unmatched_pair/ { print $2 }')
1856         [ $repaired -ge 3 ] ||
1857                 error "(3) Fail to repair unmatched pair: $repaired"
1858 }
1859 run_test 15a "LFSCK can repair unmatched MDT-object/OST-object pairs (1)"
1860
1861 test_15b() {
1862         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1863                 skip "MDS older than 2.5.55, LU-3591"
1864
1865         echo "#####"
1866         echo "If the OST-object referenced by the MDT-object back points"
1867         echo "to other MDT-object that doesn't recognize the OST-object,"
1868         echo "then the LFSCK should repair it to back point to the right"
1869         echo "MDT-object (the first one)."
1870         echo "#####"
1871
1872         check_mount_and_prep
1873         mkdir -p $DIR/$tdir/0
1874         $LFS setstripe -c 1 -i 0 $DIR/$tdir/0
1875         dd if=/dev/zero of=$DIR/$tdir/0/guard bs=1M count=1
1876         cancel_lru_locks osc
1877
1878         echo "Inject failure stub to make the OST-object to back point to"
1879         echo "other MDT-object"
1880
1881         local stripes=1
1882         [ $OSTCOUNT -ge 2 ] && stripes=2
1883
1884         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR2  0x1612
1885         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1612
1886         dd if=/dev/zero of=$DIR/$tdir/0/f0 bs=1M count=1
1887         $LFS setstripe -E 1M -S 256K -c $stripes -E 2M -S 512K -c 1 \
1888                 $DIR/$tdir/f1 ||
1889                 error "(0) Fail to create PFL $DIR/$tdir/f1"
1890         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2
1891         cancel_lru_locks osc
1892         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
1893
1894         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1895         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1896
1897         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1898                 mdd.${MDT_DEV}.lfsck_layout |
1899                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1900                 $SHOW_LAYOUT
1901                 error "(2) unexpected status"
1902         }
1903
1904         local repaired=$($SHOW_LAYOUT |
1905                          awk '/^repaired_unmatched_pair/ { print $2 }')
1906         [ $repaired -eq 4 ] ||
1907                 error "(3) Fail to repair unmatched pair: $repaired"
1908 }
1909 run_test 15b "LFSCK can repair unmatched MDT-object/OST-object pairs (2)"
1910
1911 test_15c() {
1912         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1913         (( $MDS1_VERSION < $(version_code 2.7.55) )) ||
1914                 skip "MDS newer than 2.7.55, LU-6475"
1915         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1916                 skip "MDS older than 2.5.55, LU-3591"
1917
1918         echo "#####"
1919         echo "According to current metadata migration implementation,"
1920         echo "before the old MDT-object is removed, both the new MDT-object"
1921         echo "and old MDT-object will reference the same LOV layout. Then if"
1922         echo "the layout LFSCK finds the new MDT-object by race, it will"
1923         echo "regard related OST-object(s) as multiple referenced case, and"
1924         echo "will try to create new OST-object(s) for the new MDT-object."
1925         echo "To avoid such trouble, the layout LFSCK needs to lock the old"
1926         echo "MDT-object before confirm the multiple referenced case."
1927         echo "#####"
1928
1929         check_mount_and_prep
1930         $LFS mkdir -i 1 $DIR/$tdir/a1
1931         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
1932         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=1
1933         cancel_lru_locks osc
1934
1935         echo "Inject failure stub on MDT1 to delay the migration"
1936
1937         #define OBD_FAIL_MIGRATE_DELAY                  0x1803
1938         do_facet mds2 $LCTL set_param fail_val=5 fail_loc=0x1803
1939         echo "Migrate $DIR/$tdir/a1 from MDT1 to MDT0 with delay"
1940         $LFS migrate -m 0 $DIR/$tdir/a1 &
1941
1942         sleep 1
1943         echo "Trigger layout LFSCK to race with the migration"
1944         $START_LAYOUT -A -r || error "(1) Fail to start layout LFSCK!"
1945
1946         wait_all_targets_blocked layout completed 2
1947
1948         do_facet mds2 $LCTL set_param fail_loc=0 fail_val=0
1949         local repaired=$($SHOW_LAYOUT |
1950                          awk '/^repaired_unmatched_pair/ { print $2 }')
1951         [ $repaired -eq 1 ] ||
1952                 error "(3) Fail to repair unmatched pair: $repaired"
1953
1954         repaired=$($SHOW_LAYOUT |
1955                    awk '/^repaired_multiple_referenced/ { print $2 }')
1956         [ $repaired -eq 0 ] ||
1957                 error "(4) Unexpectedly repaird multiple references: $repaired"
1958 }
1959 run_test 15c "LFSCK can repair unmatched MDT-object/OST-object pairs (3)"
1960
1961 test_16() {
1962         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
1963                 skip "MDS older than 2.5.55, LU-3594"
1964
1965         echo "#####"
1966         echo "If the OST-object's owner information does not match the owner"
1967         echo "information stored in the MDT-object, then the LFSCK trust the"
1968         echo "MDT-object and update the OST-object's owner information."
1969         echo "#####"
1970
1971         check_mount_and_prep
1972         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1973         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1974         cancel_lru_locks osc
1975
1976         # created but no setattr or write to the file.
1977         mkdir $DIR/$tdir/d1
1978         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/d1
1979         $RUNAS createmany -o $DIR/$tdir/d1/o 100 || error "create failed"
1980
1981         echo "Inject failure stub to skip OST-object owner changing"
1982         #define OBD_FAIL_LFSCK_BAD_OWNER        0x1613
1983         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1613
1984         chown 1.1 $DIR/$tdir/f0
1985         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1986
1987         echo "Trigger layout LFSCK to find out inconsistent OST-object owner"
1988         echo "and fix them"
1989
1990         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1991
1992         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1993                 mdd.${MDT_DEV}.lfsck_layout |
1994                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1995                 $SHOW_LAYOUT
1996                 error "(2) unexpected status"
1997         }
1998
1999         local repaired=$($SHOW_LAYOUT |
2000                          awk '/^repaired_inconsistent_owner/ { print $2 }')
2001         [ $repaired -eq 1 ] ||
2002                 error "(3) Fail to repair inconsistent owner: $repaired"
2003 }
2004 run_test 16 "LFSCK can repair inconsistent MDT-object/OST-object owner"
2005
2006 test_17() {
2007         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2008                 skip "MDS older than 2.5.55, LU-3594"
2009
2010         echo "#####"
2011         echo "If more than one MDT-objects reference the same OST-object,"
2012         echo "and the OST-object only recognizes one MDT-object, then the"
2013         echo "LFSCK should create new OST-objects for such non-recognized"
2014         echo "MDT-objects."
2015         echo "#####"
2016
2017         check_mount_and_prep
2018         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2019
2020         echo "Inject failure stub to make two MDT-objects to refernce"
2021         echo "the OST-object"
2022
2023         #define OBD_FAIL_LFSCK_MULTIPLE_REF     0x1614
2024         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0x1614
2025         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
2026         cancel_lru_locks mdc
2027         cancel_lru_locks osc
2028
2029         createmany -o $DIR/$tdir/f 1
2030         cancel_lru_locks mdc
2031         cancel_lru_locks osc
2032
2033         $LFS setstripe -E 2M -S 256K -o 0 -E 4M -S 512K -o 0 \
2034                 $DIR/$tdir/f1 ||
2035                 error "(0) Fail to create PFL $DIR/$tdir/f1"
2036         cancel_lru_locks mdc
2037         cancel_lru_locks osc
2038         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
2039
2040         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard use the same OST-objects"
2041         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard use the same OST-objects"
2042         local size=$(ls -l $DIR/$tdir/f0 | awk '{ print $5 }')
2043         [ $size -eq 1048576 ] ||
2044                 error "(1.1) f0 (wrong) size should be 1048576, but got $size"
2045
2046         size=$(ls -l $DIR/$tdir/f1 | awk '{ print $5 }')
2047         [ $size -eq 1048576 ] ||
2048                 error "(1.2) f1 (wrong) size should be 1048576, but got $size"
2049
2050         echo "Trigger layout LFSCK to find out multiple refenced MDT-objects"
2051         echo "and fix them"
2052
2053         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
2054
2055         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2056                 mdd.${MDT_DEV}.lfsck_layout |
2057                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2058                 $SHOW_LAYOUT
2059                 error "(3) unexpected status"
2060         }
2061
2062         local repaired=$($SHOW_LAYOUT |
2063                          awk '/^repaired_multiple_referenced/ { print $2 }')
2064         [ $repaired -eq 2 ] ||
2065                 error "(4) Fail to repair multiple references: $repaired"
2066
2067         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard should use diff OST-objects"
2068         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=2 ||
2069                 error "(5) Fail to write f0."
2070         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
2071         [ $size -eq 1048576 ] ||
2072                 error "(6) guard size should be 1048576, but got $size"
2073
2074         echo "$DIR/$tdir/f1 and $DIR/$tdir/guard should use diff OST-objects"
2075         dd if=/dev/zero of=$DIR/$tdir/f1 bs=1M count=2 ||
2076                 error "(7) Fail to write f1."
2077         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
2078         [ $size -eq 1048576 ] ||
2079                 error "(8) guard size should be 1048576, but got $size"
2080 }
2081 run_test 17 "LFSCK can repair multiple references"
2082
2083 $LCTL set_param debug=+cache > /dev/null
2084
2085 test_18a() {
2086         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2087                 skip "MDS older than 2.5.55, LU-3336"
2088
2089         echo "#####"
2090         echo "The target MDT-object is there, but related stripe information"
2091         echo "is lost or partly lost. The LFSCK should regenerate the missing"
2092         echo "layout EA entries."
2093         echo "#####"
2094
2095         check_mount_and_prep
2096         $LFS mkdir -i 0 $DIR/$tdir/a1
2097         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2098         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2099
2100         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2101
2102         $LFS path2fid $DIR/$tdir/a1/f1
2103         $LFS getstripe $DIR/$tdir/a1/f1
2104
2105         if [ $MDSCOUNT -ge 2 ]; then
2106                 $LFS mkdir -i 1 $DIR/$tdir/a2
2107                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2108                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2109                 $LFS path2fid $DIR/$tdir/a2/f2
2110                 $LFS getstripe $DIR/$tdir/a2/f2
2111         fi
2112
2113         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2114                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2115
2116         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2117
2118         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2119
2120         $LFS path2fid $DIR/$tdir/f3
2121         $LFS getstripe $DIR/$tdir/f3
2122
2123         cancel_lru_locks osc
2124
2125         echo "Inject failure, to make the MDT-object lost its layout EA"
2126         #define OBD_FAIL_LFSCK_LOST_STRIPE 0x1615
2127         do_facet mds1 $LCTL set_param fail_loc=0x1615
2128         chown 1.1 $DIR/$tdir/a1/f1
2129
2130         if [ $MDSCOUNT -ge 2 ]; then
2131                 do_facet mds2 $LCTL set_param fail_loc=0x1615
2132                 chown 1.1 $DIR/$tdir/a2/f2
2133         fi
2134
2135         chown 1.1 $DIR/$tdir/f3
2136
2137         sync
2138         sleep 2
2139
2140         do_facet mds1 $LCTL set_param fail_loc=0
2141         if [ $MDSCOUNT -ge 2 ]; then
2142                 do_facet mds2 $LCTL set_param fail_loc=0
2143         fi
2144
2145         cancel_lru_locks mdc
2146         cancel_lru_locks osc
2147
2148         echo "The file size should be incorrect since layout EA is lost"
2149         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2150         [ "$cur_size" != "$saved_size1" ] ||
2151                 error "(1) Expect incorrect file1 size"
2152
2153         if [ $MDSCOUNT -ge 2 ]; then
2154                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2155                 [ "$cur_size" != "$saved_size1" ] ||
2156                         error "(2) Expect incorrect file2 size"
2157         fi
2158
2159         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2160         [ "$cur_size" != "$saved_size2" ] ||
2161                 error "(1.2) Expect incorrect file3 size"
2162
2163         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2164         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
2165
2166         for k in $(seq $MDSCOUNT); do
2167                 # The LFSCK status query internal is 30 seconds. For the case
2168                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2169                 # time to guarantee the status sync up.
2170                 wait_update_facet mds${k} "$LCTL get_param -n \
2171                         mdd.$(facet_svc mds${k}).lfsck_layout |
2172                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2173                         error "(4) MDS${k} is not the expected 'completed'"
2174         done
2175
2176         for k in $(seq $OSTCOUNT); do
2177                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2178                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2179                                 awk '/^status/ { print $2 }')
2180                 [ "$cur_status" == "completed" ] ||
2181                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2182         done
2183
2184         local repaired=$(do_facet mds1 $LCTL get_param -n \
2185                          mdd.$(facet_svc mds1).lfsck_layout |
2186                          awk '/^repaired_orphan/ { print $2 }')
2187         [ $repaired -eq 3 ] ||
2188         error "(6.1) Expect 3 fixed on mds1, but got: $repaired"
2189
2190         if [ $MDSCOUNT -ge 2 ]; then
2191                 repaired=$(do_facet mds2 $LCTL get_param -n \
2192                          mdd.$(facet_svc mds2).lfsck_layout |
2193                                  awk '/^repaired_orphan/ { print $2 }')
2194                 [ $repaired -eq 2 ] ||
2195                 error "(6.2) Expect 2 fixed on mds2, but got: $repaired"
2196         fi
2197
2198         $LFS path2fid $DIR/$tdir/a1/f1
2199         $LFS getstripe $DIR/$tdir/a1/f1
2200
2201         if [ $MDSCOUNT -ge 2 ]; then
2202                 $LFS path2fid $DIR/$tdir/a2/f2
2203                 $LFS getstripe $DIR/$tdir/a2/f2
2204         fi
2205
2206         $LFS path2fid $DIR/$tdir/f3
2207         $LFS getstripe $DIR/$tdir/f3
2208
2209         echo "The file size should be correct after layout LFSCK scanning"
2210         cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2211         [ "$cur_size" == "$saved_size1" ] ||
2212                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2213
2214         if [ $MDSCOUNT -ge 2 ]; then
2215                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2216                 [ "$cur_size" == "$saved_size1" ] ||
2217                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2218         fi
2219
2220         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2221         [ "$cur_size" == "$saved_size2" ] ||
2222                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2223 }
2224 run_test 18a "Find out orphan OST-object and repair it (1)"
2225
2226 test_18b() {
2227         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2228         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2229                 skip "MDS older than 2.5.55, LU-3336"
2230
2231         echo "#####"
2232         echo "The target MDT-object is lost. The LFSCK should re-create the"
2233         echo "MDT-object under .lustre/lost+found/MDTxxxx. The admin should"
2234         echo "can move it back to normal namespace manually."
2235         echo "#####"
2236
2237         check_mount_and_prep
2238         $LFS mkdir -i 0 $DIR/$tdir/a1
2239         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2240         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2241         local saved_size1=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2242         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2243         echo ${fid1}
2244         $LFS getstripe $DIR/$tdir/a1/f1
2245
2246         if [ $MDSCOUNT -ge 2 ]; then
2247                 $LFS mkdir -i 1 $DIR/$tdir/a2
2248                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
2249                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2250                 fid2=$($LFS path2fid $DIR/$tdir/a2/f2)
2251                 echo ${fid2}
2252                 $LFS getstripe $DIR/$tdir/a2/f2
2253         fi
2254
2255         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2256                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2257
2258         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2259
2260         local saved_size2=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2261         local fid3=$($LFS path2fid $DIR/$tdir/f3)
2262         echo ${fid3}
2263         $LFS getstripe $DIR/$tdir/f3
2264
2265         cancel_lru_locks osc
2266
2267         echo "Inject failure, to simulate the case of missing the MDT-object"
2268         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2269         do_facet mds1 $LCTL set_param fail_loc=0x1616
2270         rm -f $DIR/$tdir/a1/f1
2271
2272         if [ $MDSCOUNT -ge 2 ]; then
2273                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2274                 rm -f $DIR/$tdir/a2/f2
2275         fi
2276
2277         rm -f $DIR/$tdir/f3
2278
2279         sync
2280         sleep 2
2281
2282         do_facet mds1 $LCTL set_param fail_loc=0
2283         if [ $MDSCOUNT -ge 2 ]; then
2284                 do_facet mds2 $LCTL set_param fail_loc=0
2285         fi
2286
2287         cancel_lru_locks mdc
2288         cancel_lru_locks osc
2289
2290         # dryrun mode only check orphans, not repaie
2291         echo "Trigger layout LFSCK --dryrun to find out orphan OST-object"
2292         $START_LAYOUT --dryrun -o -r ||
2293                 error "Fail to start layout LFSCK in dryrun mode"
2294         wait_all_targets_blocked layout completed 2
2295
2296         local PARAMS=$($SHOW_LAYOUT | awk '/^param/ { print $2 }')
2297         [ "$PARAMS" == "dryrun,all_targets,orphan" ] ||
2298                 error "Expect 'dryrun,all_targets,orphan', got '$PARAMS'"
2299
2300         local orphans=$(do_facet mds1 $LCTL get_param -n \
2301                         mdd.$(facet_svc mds1).lfsck_layout |
2302                         awk '/^inconsistent_orphan/ { print $2 }')
2303         [ $orphans -eq 3 ] ||
2304                 error "Expect 3 found on mds1, but got: $orphans"
2305
2306         # orphan parents should not be created
2307         local subdir
2308         for subdir in $MOUNT/.lustre/lost+found/*; do
2309                 [ ! "$(ls -A $subdir)" ] || error "$subdir not empty"
2310         done
2311
2312         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2313         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2314
2315         for k in $(seq $MDSCOUNT); do
2316                 # The LFSCK status query internal is 30 seconds. For the case
2317                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2318                 # time to guarantee the status sync up.
2319                 wait_update_facet mds${k} "$LCTL get_param -n \
2320                         mdd.$(facet_svc mds${k}).lfsck_layout |
2321                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2322                         error "(2) MDS${k} is not the expected 'completed'"
2323         done
2324
2325         for k in $(seq $OSTCOUNT); do
2326                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2327                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2328                                 awk '/^status/ { print $2 }')
2329                 [ "$cur_status" == "completed" ] ||
2330                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2331         done
2332
2333         local repaired=$(do_facet mds1 $LCTL get_param -n \
2334                          mdd.$(facet_svc mds1).lfsck_layout |
2335                          awk '/^repaired_orphan/ { print $2 }')
2336         [ $repaired -eq 3 ] ||
2337         error "(4.1) Expect 3 fixed on mds1, but got: $repaired"
2338
2339         if [ $MDSCOUNT -ge 2 ]; then
2340                 repaired=$(do_facet mds2 $LCTL get_param -n \
2341                          mdd.$(facet_svc mds2).lfsck_layout |
2342                          awk '/^repaired_orphan/ { print $2 }')
2343                 [ $repaired -eq 2 ] ||
2344                 error "(4.2) Expect 2 fixed on mds2, but got: $repaired"
2345         fi
2346
2347         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2348         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2349         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2350
2351         if [ $MDSCOUNT -ge 2 ]; then
2352                 local name=$MOUNT/.lustre/lost+found/MDT0001/${fid2}-R-0
2353                 mv $name $DIR/$tdir/a2/f2 || error "(6) Fail to move $name"
2354         fi
2355
2356         mv $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0 $DIR/$tdir/f3 ||
2357         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
2358
2359         $LFS path2fid $DIR/$tdir/a1/f1
2360         $LFS getstripe $DIR/$tdir/a1/f1
2361
2362         if [ $MDSCOUNT -ge 2 ]; then
2363                 $LFS path2fid $DIR/$tdir/a2/f2
2364                 $LFS getstripe $DIR/$tdir/a2/f2
2365         fi
2366
2367         $LFS path2fid $DIR/$tdir/f3
2368         $LFS getstripe $DIR/$tdir/f3
2369
2370         echo "The file size should be correct after layout LFSCK scanning"
2371         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
2372         [ "$cur_size" == "$saved_size1" ] ||
2373                 error "(7) Expect file1 size $saved_size1, but got $cur_size"
2374
2375         if [ $MDSCOUNT -ge 2 ]; then
2376                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
2377                 [ "$cur_size" == "$saved_size1" ] ||
2378                 error "(8) Expect file2 size $saved_size1, but got $cur_size"
2379         fi
2380
2381         cur_size=$(ls -il $DIR/$tdir/f3 | awk '{ print $6 }')
2382         [ "$cur_size" == "$saved_size2" ] ||
2383                 error "(9) Expect file1 size $saved_size2, but got $cur_size"
2384 }
2385 run_test 18b "Find out orphan OST-object and repair it (2)"
2386
2387 test_18c() {
2388         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2389         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2390                 skip "MDS older than 2.5.55, LU-3336"
2391
2392         echo "#####"
2393         echo "The target MDT-object is lost, and the OST-object FID is missing."
2394         echo "The LFSCK should re-create the MDT-object with new FID under the "
2395         echo "directory .lustre/lost+found/MDTxxxx."
2396         echo "#####"
2397
2398         check_mount_and_prep
2399         $LFS mkdir -i 0 $DIR/$tdir/a1
2400         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2401
2402         echo "Inject failure, to simulate the case of missing parent FID"
2403         #define OBD_FAIL_LFSCK_NOPFID           0x1617
2404         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1617
2405
2406         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2407         $LFS getstripe $DIR/$tdir/a1/f1
2408
2409         if [ $MDSCOUNT -ge 2 ]; then
2410                 $LFS mkdir -i 1 $DIR/$tdir/a2
2411                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a2
2412                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2413                 $LFS getstripe $DIR/$tdir/a2/f2
2414         fi
2415
2416         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/f3 ||
2417                 error "(0) Fail to create PFL $DIR/$tdir/f3"
2418
2419         dd if=/dev/zero of=$DIR/$tdir/f3 bs=1M count=2
2420         $LFS getstripe $DIR/$tdir/f3
2421
2422         cancel_lru_locks osc
2423         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
2424
2425         echo "Inject failure, to simulate the case of missing the MDT-object"
2426         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2427         do_facet mds1 $LCTL set_param fail_loc=0x1616
2428         rm -f $DIR/$tdir/a1/f1
2429
2430         if [ $MDSCOUNT -ge 2 ]; then
2431                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2432                 rm -f $DIR/$tdir/a2/f2
2433         fi
2434
2435         rm -f $DIR/$tdir/f3
2436
2437         sync
2438         sleep 2
2439
2440         do_facet mds1 $LCTL set_param fail_loc=0
2441         if [ $MDSCOUNT -ge 2 ]; then
2442                 do_facet mds2 $LCTL set_param fail_loc=0
2443         fi
2444
2445         cancel_lru_locks mdc
2446         cancel_lru_locks osc
2447
2448         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2449         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2450
2451         for k in $(seq $MDSCOUNT); do
2452                 # The LFSCK status query internal is 30 seconds. For the case
2453                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2454                 # time to guarantee the status sync up.
2455                 wait_update_facet mds${k} "$LCTL get_param -n \
2456                         mdd.$(facet_svc mds${k}).lfsck_layout |
2457                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2458                         error "(2) MDS${k} is not the expected 'completed'"
2459         done
2460
2461         for k in $(seq $OSTCOUNT); do
2462                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2463                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2464                                 awk '/^status/ { print $2 }')
2465                 [ "$cur_status" == "completed" ] ||
2466                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2467         done
2468
2469         if [ $MDSCOUNT -ge 2 ]; then
2470                 expected=4
2471         else
2472                 expected=3
2473         fi
2474
2475         local repaired=$(do_facet mds1 $LCTL get_param -n \
2476                          mdd.$(facet_svc mds1).lfsck_layout |
2477                          awk '/^repaired_orphan/ { print $2 }')
2478         [ $repaired -eq $expected ] ||
2479                 error "(4) Expect $expected fixed on mds1, but got: $repaired"
2480
2481         if [ $MDSCOUNT -ge 2 ]; then
2482                 repaired=$(do_facet mds2 $LCTL get_param -n \
2483                            mdd.$(facet_svc mds2).lfsck_layout |
2484                            awk '/^repaired_orphan/ { print $2 }')
2485                 [ $repaired -eq 0 ] ||
2486                         error "(5) Expect 0 fixed on mds2, but got: $repaired"
2487         fi
2488
2489         ls -ail $MOUNT/.lustre/lost+found/
2490
2491         echo "There should NOT be some stub under .lustre/lost+found/MDT0001/"
2492         if [ -d $MOUNT/.lustre/lost+found/MDT0001 ]; then
2493                 cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-N-*)
2494                 [ -z "$cname" ] ||
2495                         error "(6) .lustre/lost+found/MDT0001/ should be empty"
2496         fi
2497
2498         echo "There should be some stub under .lustre/lost+found/MDT0000/"
2499         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2500                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2501
2502         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-N-*)
2503         [ ! -z "$cname" ] ||
2504                 error "(8) .lustre/lost+found/MDT0000/ should not be empty"
2505 }
2506 run_test 18c "Find out orphan OST-object and repair it (3)"
2507
2508 test_18d() {
2509         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2510                 skip "MDS older than 2.5.55, LU-3336"
2511
2512         echo "#####"
2513         echo "The target MDT-object layout EA is corrupted, but the right"
2514         echo "OST-object is still alive as orphan. The layout LFSCK will"
2515         echo "not create new OST-object to occupy such slot."
2516         echo "#####"
2517
2518         check_mount_and_prep
2519         mkdir $DIR/$tdir/a1
2520         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2521         echo "guard" > $DIR/$tdir/a1/f1
2522         echo "foo" > $DIR/$tdir/a1/f2
2523
2524         echo "guard" > $DIR/$tdir/a1/f3
2525         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2526                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2527         echo "foo" > $DIR/$tdir/a1/f4
2528
2529         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2530         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2531         $LFS path2fid $DIR/$tdir/a1/f1
2532         $LFS getstripe $DIR/$tdir/a1/f1
2533         $LFS path2fid $DIR/$tdir/a1/f2
2534         $LFS getstripe $DIR/$tdir/a1/f2
2535         $LFS path2fid $DIR/$tdir/a1/f3
2536         $LFS getstripe $DIR/$tdir/a1/f3
2537         $LFS path2fid $DIR/$tdir/a1/f4
2538         $LFS getstripe $DIR/$tdir/a1/f4
2539         cancel_lru_locks osc
2540
2541         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2542         echo "to reference the same OST-object (which is f1's OST-obejct)."
2543         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2544         echo "dangling reference case, but f2's old OST-object is there."
2545
2546         echo "The failure also makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2547         echo "to reference the same OST-object (which is f3's OST-obejct)."
2548         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2549         echo "dangling reference case, but f4's old OST-object is there."
2550         echo
2551
2552         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2553         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2554         chown 1.1 $DIR/$tdir/a1/f2
2555         chown 1.1 $DIR/$tdir/a1/f4
2556         rm -f $DIR/$tdir/a1/f1
2557         rm -f $DIR/$tdir/a1/f3
2558         sync
2559         sleep 2
2560         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2561
2562         echo "stopall to cleanup object cache"
2563         stopall > /dev/null
2564         echo "setupall"
2565         setupall > /dev/null
2566
2567         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2568         $START_LAYOUT -r -o -c -d || error "(2) Fail to start LFSCK for layout!"
2569
2570         for k in $(seq $MDSCOUNT); do
2571                 # The LFSCK status query internal is 30 seconds. For the case
2572                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2573                 # time to guarantee the status sync up.
2574                 wait_update_facet mds${k} "$LCTL get_param -n \
2575                         mdd.$(facet_svc mds${k}).lfsck_layout |
2576                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2577                         error "(3) MDS${k} is not the expected 'completed'"
2578         done
2579
2580         for k in $(seq $OSTCOUNT); do
2581                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2582                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2583                                 awk '/^status/ { print $2 }')
2584                 [ "$cur_status" == "completed" ] ||
2585                 error "(4) OST${k} Expect 'completed', but got '$cur_status'"
2586         done
2587
2588         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2589                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2590                          awk '/^repaired_orphan/ { print $2 }')
2591         [ $repaired -eq 2 ] ||
2592                 error "(5) Expect 2 orphans have been fixed, but got: $repaired"
2593
2594         repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2595                    mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2596                    awk '/^repaired_dangling/ { print $2 }')
2597         [ $repaired -eq 0 ] ||
2598                 error "(6) Expect 0 dangling has been fixed, but got: $repaired"
2599
2600         echo "The file size should be correct after layout LFSCK scanning"
2601         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2602         [ "$cur_size" == "$saved_size1" ] ||
2603                 error "(7) Expect file2 size $saved_size1, but got $cur_size"
2604
2605         cur_size=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2606         [ "$cur_size" == "$saved_size2" ] ||
2607                 error "(8) Expect file4 size $saved_size2, but got $cur_size"
2608
2609         echo "The LFSCK should find back the original data."
2610         cat $DIR/$tdir/a1/f2
2611         $LFS path2fid $DIR/$tdir/a1/f2
2612         $LFS getstripe $DIR/$tdir/a1/f2
2613         cat $DIR/$tdir/a1/f4
2614         $LFS path2fid $DIR/$tdir/a1/f4
2615         $LFS getstripe $DIR/$tdir/a1/f4
2616 }
2617 run_test 18d "Find out orphan OST-object and repair it (4)"
2618
2619 test_18e() {
2620         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2621         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
2622                 skip "MDS older than 2.5.55, LU-3336"
2623
2624         echo "#####"
2625         echo "The target MDT-object layout EA slot is occpuied by some new"
2626         echo "created OST-object when repair dangling reference case. Such"
2627         echo "conflict OST-object has been modified by others. To keep the"
2628         echo "new data, the LFSCK will create a new file to refernece this"
2629         echo "old orphan OST-object."
2630         echo "#####"
2631
2632         check_mount_and_prep
2633         mkdir $DIR/$tdir/a1
2634         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2635         echo "guard" > $DIR/$tdir/a1/f1
2636         echo "foo" > $DIR/$tdir/a1/f2
2637
2638         echo "guard" > $DIR/$tdir/a1/f3
2639         $LFS setstripe -E 1M -S 1M -o 0 -E -1 -S 1M $DIR/$tdir/a1/f4 ||
2640                 error "(0) Fail to create PFL $DIR/$tdir/a1/f4"
2641         echo "foo" > $DIR/$tdir/a1/f4
2642
2643         local saved_size1=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2644         local saved_size2=$(ls -il $DIR/$tdir/a1/f4 | awk '{ print $6 }')
2645
2646         $LFS path2fid $DIR/$tdir/a1/f1
2647         $LFS getstripe $DIR/$tdir/a1/f1
2648         $LFS path2fid $DIR/$tdir/a1/f2
2649         $LFS getstripe $DIR/$tdir/a1/f2
2650         $LFS path2fid $DIR/$tdir/a1/f3
2651         $LFS getstripe $DIR/$tdir/a1/f3
2652         $LFS path2fid $DIR/$tdir/a1/f4
2653         $LFS getstripe $DIR/$tdir/a1/f4
2654         cancel_lru_locks osc
2655
2656         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2657         echo "to reference the same OST-object (which is f1's OST-obejct)."
2658         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2659         echo "dangling reference case, but f2's old OST-object is there."
2660
2661         echo "Also the failure makes $DIR/$tdir/a1/f3 and $DIR/$tdir/a1/f4"
2662         echo "to reference the same OST-object (which is f3's OST-obejct)."
2663         echo "Then drop $DIR/$tdir/a1/f3 and its OST-object, so f4 becomes"
2664         echo "dangling reference case, but f4's old OST-object is there."
2665         echo
2666
2667         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2668         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2669         chown 1.1 $DIR/$tdir/a1/f2
2670         chown 1.1 $DIR/$tdir/a1/f4
2671         rm -f $DIR/$tdir/a1/f1
2672         rm -f $DIR/$tdir/a1/f3
2673         sync
2674         sleep 2
2675         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2676
2677         echo "stopall to cleanup object cache"
2678         stopall > /dev/null
2679         echo "setupall"
2680         setupall > /dev/null
2681
2682         #define OBD_FAIL_LFSCK_DELAY3           0x1602
2683         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
2684
2685         start_full_debug_logging
2686
2687         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2688         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
2689
2690         wait_update_facet mds1 "$LCTL get_param -n \
2691                 mdd.$(facet_svc mds1).lfsck_layout |
2692                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" $LTIME ||
2693                 error "(3) MDS1 is not the expected 'scanning-phase2'"
2694
2695         # to guarantee all updates are synced.
2696         sync
2697         sleep 2
2698
2699         echo "Write new data to f2/f4 to modify the new created OST-object."
2700         echo "dummy" >> $DIR/$tdir/a1/f2 || error "write a1/f2 failed"
2701         echo "dummy" >> $DIR/$tdir/a1/f4 || error "write a1/f4 failed"
2702
2703         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2704
2705         for k in $(seq $MDSCOUNT); do
2706                 # The LFSCK status query internal is 30 seconds. For the case
2707                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2708                 # time to guarantee the status sync up.
2709                 wait_update_facet mds${k} "$LCTL get_param -n \
2710                         mdd.$(facet_svc mds${k}).lfsck_layout |
2711                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2712                         error "(4) MDS${k} is not the expected 'completed'"
2713         done
2714
2715         for k in $(seq $OSTCOUNT); do
2716                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2717                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2718                                 awk '/^status/ { print $2 }')
2719                 [ "$cur_status" == "completed" ] ||
2720                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2721         done
2722
2723         stop_full_debug_logging
2724
2725         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2726                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2727                          awk '/^repaired_orphan/ { print $2 }')
2728         [ $repaired -eq 2 ] ||
2729                 error "(6) Expect 2 orphans have been fixed, but got: $repaired"
2730
2731         echo "There should be stub file under .lustre/lost+found/MDT0000/"
2732         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2733                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2734
2735         local count=$(ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-* | wc -l)
2736         if [ $count -ne 2 ]; then
2737                 ls -l $MOUNT/.lustre/lost+found/MDT0000/*-C-*
2738                 error "(8) Expect 2 stubs under lost+found, but got $count"
2739         fi
2740
2741         echo "The stub file should keep the original f2 or f4 data"
2742         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | head -n 1)
2743         local cur_size=$(ls -il $cname | awk '{ print $6 }')
2744         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2745                 error "(9) Got unexpected $cur_size"
2746
2747         cat $cname
2748         $LFS path2fid $cname
2749         $LFS getstripe $cname
2750
2751         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-* | tail -n 1)
2752         cur_size=$(ls -il $cname | awk '{ print $6 }')
2753         [ "$cur_size" != "$saved_size1" -a "$cur_size" != "$saved_size2" ] &&
2754                 error "(10) Got unexpected $cur_size"
2755
2756         cat $cname
2757         $LFS path2fid $cname
2758         $LFS getstripe $cname
2759
2760         echo "The f2/f4 should contains new data."
2761         cat $DIR/$tdir/a1/f2
2762         $LFS path2fid $DIR/$tdir/a1/f2
2763         $LFS getstripe $DIR/$tdir/a1/f2
2764         cat $DIR/$tdir/a1/f4
2765         $LFS path2fid $DIR/$tdir/a1/f4
2766         $LFS getstripe $DIR/$tdir/a1/f4
2767 }
2768 run_test 18e "Find out orphan OST-object and repair it (5)"
2769
2770 test_18f() {
2771         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
2772
2773         echo "#####"
2774         echo "The target MDT-object is lost. The LFSCK should re-create the"
2775         echo "MDT-object under .lustre/lost+found/MDTxxxx. If some OST fail"
2776         echo "to verify some OST-object(s) during the first stage-scanning,"
2777         echo "the LFSCK should skip orphan OST-objects for such OST. Others"
2778         echo "should not be affected."
2779         echo "#####"
2780
2781         check_mount_and_prep
2782         $LFS mkdir -i 0 $DIR/$tdir/a1
2783         $LFS setstripe -c 1 -i 0 $DIR/$tdir/a1
2784         dd if=/dev/zero of=$DIR/$tdir/a1/guard bs=1M count=2
2785         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2786         $LFS mkdir -i 0 $DIR/$tdir/a2
2787         $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a2
2788         dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2789         $LFS getstripe $DIR/$tdir/a1/f1
2790         $LFS getstripe $DIR/$tdir/a2/f2
2791
2792         if [ $MDSCOUNT -ge 2 ]; then
2793                 $LFS mkdir -i 1 $DIR/$tdir/a3
2794                 $LFS setstripe -c 1 -i 0 $DIR/$tdir/a3
2795                 dd if=/dev/zero of=$DIR/$tdir/a3/guard bs=1M count=2
2796                 dd if=/dev/zero of=$DIR/$tdir/a3/f3 bs=1M count=2
2797                 $LFS mkdir -i 1 $DIR/$tdir/a4
2798                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a4
2799                 dd if=/dev/zero of=$DIR/$tdir/a4/f4 bs=1M count=2
2800                 $LFS getstripe $DIR/$tdir/a3/f3
2801                 $LFS getstripe $DIR/$tdir/a4/f4
2802         fi
2803
2804         cancel_lru_locks osc
2805
2806         echo "Inject failure, to simulate the case of missing the MDT-object"
2807         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2808         do_facet mds1 $LCTL set_param fail_loc=0x1616
2809         rm -f $DIR/$tdir/a1/f1
2810         rm -f $DIR/$tdir/a2/f2
2811
2812         if [ $MDSCOUNT -ge 2 ]; then
2813                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2814                 rm -f $DIR/$tdir/a3/f3
2815                 rm -f $DIR/$tdir/a4/f4
2816         fi
2817
2818         sync
2819         sleep 2
2820
2821         do_facet mds1 $LCTL set_param fail_loc=0
2822         if [ $MDSCOUNT -ge 2 ]; then
2823                 do_facet mds2 $LCTL set_param fail_loc=0
2824         fi
2825
2826         cancel_lru_locks mdc
2827         cancel_lru_locks osc
2828
2829         echo "Inject failure, to simulate the OST0 fail to handle"
2830         echo "MDT0 LFSCK request during the first-stage scanning."
2831         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
2832         do_facet mds1 $LCTL set_param fail_loc=0x161c fail_val=0
2833
2834         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2835         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2836
2837         for k in $(seq $MDSCOUNT); do
2838                 # The LFSCK status query internal is 30 seconds. For the case
2839                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2840                 # time to guarantee the status sync up.
2841                 wait_update_facet mds${k} "$LCTL get_param -n \
2842                         mdd.$(facet_svc mds${k}).lfsck_layout |
2843                         awk '/^status/ { print \\\$2 }'" "partial" $LTIME ||
2844                         error "(2) MDS${k} is not the expected 'partial'"
2845         done
2846
2847         wait_update_facet ost1 "$LCTL get_param -n \
2848                 obdfilter.$(facet_svc ost1).lfsck_layout |
2849                 awk '/^status/ { print \\\$2 }'" "partial" $LTIME || {
2850                 error "(3) OST1 is not the expected 'partial'"
2851         }
2852
2853         wait_update_facet ost2 "$LCTL get_param -n \
2854                 obdfilter.$(facet_svc ost2).lfsck_layout |
2855                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME || {
2856                 error "(4) OST2 is not the expected 'completed'"
2857         }
2858
2859         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2860
2861         local repaired=$(do_facet mds1 $LCTL get_param -n \
2862                          mdd.$(facet_svc mds1).lfsck_layout |
2863                          awk '/^repaired_orphan/ { print $2 }')
2864         [ $repaired -eq 1 ] ||
2865                 error "(5) Expect 1 fixed on mds{1}, but got: $repaired"
2866
2867         if [ $MDSCOUNT -ge 2 ]; then
2868                 repaired=$(do_facet mds2 $LCTL get_param -n \
2869                          mdd.$(facet_svc mds2).lfsck_layout |
2870                          awk '/^repaired_orphan/ { print $2 }')
2871                 [ $repaired -eq 1 ] ||
2872                 error "(6) Expect 1 fixed on mds{2}, but got: $repaired"
2873         fi
2874
2875         echo "Trigger layout LFSCK on all devices again to cleanup"
2876         $START_LAYOUT -r -o || error "(7) Fail to start LFSCK for layout!"
2877
2878         for k in $(seq $MDSCOUNT); do
2879                 # The LFSCK status query internal is 30 seconds. For the case
2880                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2881                 # time to guarantee the status sync up.
2882                 wait_update_facet mds${k} "$LCTL get_param -n \
2883                         mdd.$(facet_svc mds${k}).lfsck_layout |
2884                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2885                         error "(8) MDS${k} is not the expected 'completed'"
2886         done
2887
2888         for k in $(seq $OSTCOUNT); do
2889                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2890                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2891                              awk '/^status/ { print $2 }')
2892                 [ "$cur_status" == "completed" ] ||
2893                 error "(9) OST${k} Expect 'completed', but got '$cur_status'"
2894
2895         done
2896
2897         local repaired=$(do_facet mds1 $LCTL get_param -n \
2898                          mdd.$(facet_svc mds1).lfsck_layout |
2899                          awk '/^repaired_orphan/ { print $2 }')
2900         [ $repaired -eq 2 ] ||
2901                 error "(10) Expect 2 fixed on mds{1}, but got: $repaired"
2902
2903         if [ $MDSCOUNT -ge 2 ]; then
2904                 repaired=$(do_facet mds2 $LCTL get_param -n \
2905                          mdd.$(facet_svc mds2).lfsck_layout |
2906                          awk '/^repaired_orphan/ { print $2 }')
2907                 [ $repaired -eq 2 ] ||
2908                 error "(11) Expect 2 fixed on mds{2}, but got: $repaired"
2909         fi
2910 }
2911 run_test 18f "Skip the failed OST(s) when handle orphan OST-objects"
2912
2913 test_18g() {
2914         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
2915
2916         echo "#####"
2917         echo "The target MDT-object is lost, but related OI mapping is there"
2918         echo "The LFSCK should recreate the lost MDT-object without affected"
2919         echo "by the stale OI mapping."
2920         echo "#####"
2921
2922         check_mount_and_prep
2923         $LFS mkdir -i 0 $DIR/$tdir/a1
2924         $LFS setstripe -c -1 -i 0 -S 1M $DIR/$tdir/a1
2925         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=$OSTCOUNT
2926         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2927         echo ${fid1}
2928         $LFS getstripe $DIR/$tdir/a1/f1
2929         cancel_lru_locks osc
2930
2931         echo "Inject failure to simulate lost MDT-object but keep OI mapping"
2932         #define OBD_FAIL_LFSCK_LOST_MDTOBJ2     0x162e
2933         do_facet mds1 $LCTL set_param fail_loc=0x162e
2934         rm -f $DIR/$tdir/a1/f1
2935
2936         do_facet mds1 $LCTL set_param fail_loc=0
2937         cancel_lru_locks mdc
2938         cancel_lru_locks osc
2939
2940         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2941         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2942
2943         for k in $(seq $MDSCOUNT); do
2944                 # The LFSCK status query internal is 30 seconds. For the case
2945                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2946                 # time to guarantee the status sync up.
2947                 wait_update_facet mds${k} "$LCTL get_param -n \
2948                         mdd.$(facet_svc mds${k}).lfsck_layout |
2949                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2950                         error "(2) MDS${k} is not the expected 'completed'"
2951         done
2952
2953         for k in $(seq $OSTCOUNT); do
2954                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2955                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2956                                 awk '/^status/ { print $2 }')
2957                 [ "$cur_status" == "completed" ] ||
2958                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2959         done
2960
2961         local repaired=$(do_facet mds1 $LCTL get_param -n \
2962                          mdd.$(facet_svc mds1).lfsck_layout |
2963                          awk '/^repaired_orphan/ { print $2 }')
2964         [ $repaired -eq $OSTCOUNT ] ||
2965                 error "(4) Expect $OSTCOUNT fixed, but got: $repaired"
2966
2967         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
2968         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
2969         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2970
2971         $LFS path2fid $DIR/$tdir/a1/f1
2972         $LFS getstripe $DIR/$tdir/a1/f1
2973 }
2974 run_test 18g "Find out orphan OST-object and repair it (7)"
2975
2976 test_18h() {
2977         echo "#####"
2978         echo "The PFL extent crashed. During the first cycle LFSCK scanning,"
2979         echo "the layout LFSCK will keep the bad PFL file(s) there without"
2980         echo "scanning its OST-object(s). Then in the second stage scanning,"
2981         echo "the OST will return related OST-object(s) to the MDT as orphan."
2982         echo "And then the LFSCK on the MDT can rebuild the PFL extent with"
2983         echo "the 'orphan(s)' stripe information."
2984         echo "#####"
2985
2986         check_mount_and_prep
2987
2988         $LFS setstripe -E 2M -S 1M -c 1 -E -1 $DIR/$tdir/f0 ||
2989                 error "(0) Fail to create PFL $DIR/$tdir/f0"
2990
2991         cat $LUSTRE/tests/test-framework.sh > $DIR/$tdir/f0 ||
2992                 error "(1.1) Fail to write $DIR/$tdir/f0"
2993
2994         dd if=$LUSTRE/tests/test-framework.sh of=$DIR/$tdir/f0 bs=1M seek=2 ||
2995                 error "(1.2) Fail to write $DIR/$tdir/f0"
2996
2997         cp $DIR/$tdir/f0 $DIR/$tdir/guard
2998
2999         echo "Inject failure stub to simulate bad PFL extent range"
3000         #define OBD_FAIL_LFSCK_BAD_PFL_RANGE    0x162f
3001         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162f
3002
3003         chown 1.1 $DIR/$tdir/f0
3004
3005         cancel_lru_locks mdc
3006         cancel_lru_locks osc
3007         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3008
3009         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 &&
3010                 error "(2) Write to bad PFL file should fail"
3011
3012         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
3013         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
3014
3015         for k in $(seq $MDSCOUNT); do
3016                 # The LFSCK status query internal is 30 seconds. For the case
3017                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3018                 # time to guarantee the status sync up.
3019                 wait_update_facet mds${k} "$LCTL get_param -n \
3020                         mdd.$(facet_svc mds${k}).lfsck_layout |
3021                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
3022                         error "(4.1) MDS${k} is not the expected 'completed'"
3023         done
3024
3025         for k in $(seq $OSTCOUNT); do
3026                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
3027                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
3028                              awk '/^status/ { print $2 }')
3029                 [ "$cur_status" == "completed" ] ||
3030                 error "(4.2) OST${k} Expect 'completed', but got '$cur_status'"
3031
3032         done
3033
3034         local repaired=$($SHOW_LAYOUT |
3035                          awk '/^repaired_orphan/ { print $2 }')
3036         [ $repaired -eq 2 ] ||
3037                 error "(5) Fail to repair crashed PFL range: $repaired"
3038
3039         echo "Data in $DIR/$tdir/f0 should not be broken"
3040         diff $DIR/$tdir/f0 $DIR/$tdir/guard ||
3041                 error "(6) Data in $DIR/$tdir/f0 is broken"
3042
3043         echo "Write should succeed after LFSCK repairing the bad PFL range"
3044         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1 ||
3045                 error "(7) Write should succeed after LFSCK"
3046 }
3047 run_test 18h "LFSCK can repair crashed PFL extent range"
3048
3049 $LCTL set_param debug=-cache > /dev/null
3050
3051 test_19a() {
3052         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3053                 skip "MDS older than 2.5.55, LU-3951"
3054
3055         check_mount_and_prep
3056         $LFS setstripe -c 1 -i 0 $DIR/$tdir
3057
3058         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3059                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3060
3061         echo "foo1" > $DIR/$tdir/a0
3062         $LFS setstripe -E 512K -S 512K -o 0 -E -1 -S 1M $DIR/$tdir/a1 ||
3063                 error "(0) Fail to create PFL $DIR/$tdir/a1"
3064         echo "foo2" > $DIR/$tdir/a1
3065         echo "guard" > $DIR/$tdir/a2
3066         cancel_lru_locks osc
3067
3068         echo "Inject failure, then client will offer wrong parent FID when read"
3069         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3070                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
3071
3072         #define OBD_FAIL_LFSCK_INVALID_PFID     0x1619
3073         $LCTL set_param fail_loc=0x1619
3074
3075         echo "Read RPC with wrong parent FID should be denied"
3076         cat $DIR/$tdir/a0 && error "(3.1) Read a0 should be denied!"
3077         cat $DIR/$tdir/a1 && error "(3.2) Read a1 should be denied!"
3078         $LCTL set_param fail_loc=0
3079 }
3080 run_test 19a "OST-object inconsistency self detect"
3081
3082 test_19b() {
3083         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3084                 skip "MDS older than 2.5.55, LU-3951"
3085
3086         check_mount_and_prep
3087         $LFS setstripe -c 1 -i 0 $DIR/$tdir
3088
3089         echo "Inject failure stub to make the OST-object to back point to"
3090         echo "non-exist MDT-object"
3091
3092         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3093                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3094
3095         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
3096         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0x1611
3097         echo "foo1" > $DIR/$tdir/f0
3098         $LFS setstripe -E 1M -S 1M -o 0 -E 4M -S 256K $DIR/$tdir/f1 ||
3099                 error "(0) Fail to create PFL $DIR/$tdir/f1"
3100         echo "foo2" > $DIR/$tdir/f1
3101         cancel_lru_locks osc
3102         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
3103
3104         do_facet ost1 $LCTL set_param -n \
3105                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 0
3106         echo "Nothing should be fixed since self detect and repair is disabled"
3107         local repaired=$(do_facet ost1 $LCTL get_param -n \
3108                         obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
3109                         awk '/^repaired/ { print $2 }')
3110         [ $repaired -eq 0 ] ||
3111                 error "(1) Expected 0 repaired, but got $repaired"
3112
3113         echo "Read RPC with right parent FID should be accepted,"
3114         echo "and cause parent FID on OST to be fixed"
3115
3116         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param -n \
3117                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
3118
3119         cat $DIR/$tdir/f0 || error "(2.1) Read f0 should not be denied!"
3120         cat $DIR/$tdir/f1 || error "(2.2) Read f1 should not be denied!"
3121
3122         repaired=$(do_facet ost1 $LCTL get_param -n \
3123                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
3124                 awk '/^repaired/ { print $2 }')
3125         [ $repaired -eq 2 ] ||
3126                 error "(3) Expected 1 repaired, but got $repaired"
3127 }
3128 run_test 19b "OST-object inconsistency self repair"
3129
3130 PATTERN_WITH_HOLE="40000001"
3131 PATTERN_WITHOUT_HOLE="raid0"
3132
3133 test_20a() {
3134         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs" && return
3135         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
3136         (( $MDS1_VERSION > $(version_code 2.5.55) )) ||
3137                 skip "MDS older than 2.5.55, LU-4887"
3138
3139         echo "#####"
3140         echo "The target MDT-object and some of its OST-object are lost."
3141         echo "The LFSCK should find out the left OST-objects and re-create"
3142         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
3143         echo "with the partial OST-objects (LOV EA hole)."
3144
3145         echo "New client can access the file with LOV EA hole via normal"
3146         echo "system tools or commands without crash the system."
3147
3148         echo "For old client, even though it cannot access the file with"
3149         echo "LOV EA hole, it should not cause the system crash."
3150         echo "#####"
3151
3152         check_mount_and_prep
3153         $LFS mkdir -i 0 $DIR/$tdir/a1
3154         if [ $OSTCOUNT -gt 2 ]; then
3155                 $LFS setstripe -c 3 -i 0 -S 1M $DIR/$tdir/a1
3156                 bcount=513
3157         else
3158                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a1
3159                 bcount=257
3160         fi
3161
3162         # 256 blocks on the stripe0.
3163         # 1 block on the stripe1 for 2 OSTs case.
3164         # 256 blocks on the stripe1 for other cases.
3165         # 1 block on the stripe2 if OSTs > 2
3166         dd if=/dev/zero of=$DIR/$tdir/a1/f0 bs=4096 count=$bcount
3167         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=4096 count=$bcount
3168         dd if=/dev/zero of=$DIR/$tdir/a1/f2 bs=4096 count=$bcount
3169
3170         local fid0=$($LFS path2fid $DIR/$tdir/a1/f0)
3171         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
3172         local fid2=$($LFS path2fid $DIR/$tdir/a1/f2)
3173
3174         echo ${fid0}
3175         $LFS getstripe $DIR/$tdir/a1/f0
3176         echo ${fid1}
3177         $LFS getstripe $DIR/$tdir/a1/f1
3178         echo ${fid2}
3179         $LFS getstripe $DIR/$tdir/a1/f2
3180
3181         if [ $OSTCOUNT -gt 2 ]; then
3182                 dd if=/dev/zero of=$DIR/$tdir/a1/f3 bs=4096 count=$bcount
3183                 fid3=$($LFS path2fid $DIR/$tdir/a1/f3)
3184                 echo ${fid3}
3185                 $LFS getstripe $DIR/$tdir/a1/f3
3186         fi
3187
3188         cancel_lru_locks osc
3189
3190         echo "Inject failure..."