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