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