Whamcloud - gitweb
e563d038499b052af6b14360b3fef172a1be3020
[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 much 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         echo "start $SINGLEMDS"
724         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
725                 error "(5) Fail to start MDS!"
726
727         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
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         echo "stop $SINGLEMDS"
758         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop MDS!"
759
760         echo "start $SINGLEMDS"
761         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
762                 error "(6) Fail to start MDS!"
763
764         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
765         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
766                 mdd.${MDT_DEV}.lfsck_namespace |
767                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
768                 $SHOW_NAMESPACE
769                 error "(7) unexpected status"
770         }
771 }
772 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
773
774 test_8()
775 {
776         echo "formatall"
777         formatall > /dev/null
778         echo "setupall"
779         setupall > /dev/null
780
781         lfsck_prep 20 20
782
783         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
784         [ "$STATUS" == "init" ] ||
785                 error "(2) Expect 'init', but got '$STATUS'"
786
787         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
788         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
789         mkdir $DIR/$tdir/crashed
790
791         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
792         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
793         for ((i = 0; i < 5; i++)); do
794                 touch $DIR/$tdir/dummy${i}
795         done
796
797         umount_client $MOUNT || error "(3) Fail to stop client!"
798
799         #define OBD_FAIL_LFSCK_DELAY2           0x1601
800         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1601
801         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
802
803         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
804         [ "$STATUS" == "scanning-phase1" ] ||
805                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
806
807         $STOP_LFSCK || error "(6) Fail to stop LFSCK!"
808
809         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
810         [ "$STATUS" == "stopped" ] ||
811                 error "(7) Expect 'stopped', but got '$STATUS'"
812
813         $START_NAMESPACE || error "(8) Fail to start LFSCK for namespace!"
814
815         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
816         [ "$STATUS" == "scanning-phase1" ] ||
817                 error "(9) Expect 'scanning-phase1', but got '$STATUS'"
818
819         #define OBD_FAIL_LFSCK_FATAL2           0x1609
820         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
821         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
822                 mdd.${MDT_DEV}.lfsck_namespace |
823                 awk '/^status/ { print \\\$2 }'" "failed" 32 || {
824                 $SHOW_NAMESPACE
825                 error "(10) unexpected status"
826         }
827
828         #define OBD_FAIL_LFSCK_DELAY1           0x1600
829         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
830         $START_NAMESPACE || error "(11) Fail to start LFSCK for namespace!"
831
832         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
833         [ "$STATUS" == "scanning-phase1" ] ||
834                 error "(12) Expect 'scanning-phase1', but got '$STATUS'"
835
836         #define OBD_FAIL_LFSCK_CRASH            0x160a
837         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
838         sleep 5
839
840         echo "stop $SINGLEMDS"
841         stop $SINGLEMDS > /dev/null || error "(13) Fail to stop MDS!"
842
843         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
844         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
845
846         echo "start $SINGLEMDS"
847         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
848                 error "(14) Fail to start MDS!"
849
850         local timeout=$(max_recovery_time)
851         local timer=0
852
853         while [ $timer -lt $timeout ]; do
854                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
855                         mdt.${MDT_DEV}.recovery_status |
856                         awk '/^status/ { print \\\$2 }'")
857                 [ "$STATUS" != "RECOVERING" ] && break;
858                 sleep 1
859                 timer=$((timer + 1))
860         done
861
862         [ $timer != $timeout ] ||
863                 error "(14.1) recovery timeout"
864
865         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
866         [ "$STATUS" == "crashed" ] ||
867                 error "(15) Expect 'crashed', but got '$STATUS'"
868
869         #define OBD_FAIL_LFSCK_DELAY2           0x1601
870         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
871         $START_NAMESPACE || error "(16) Fail to start LFSCK for namespace!"
872
873         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
874         [ "$STATUS" == "scanning-phase1" ] ||
875                 error "(17) Expect 'scanning-phase1', but got '$STATUS'"
876
877         echo "stop $SINGLEMDS"
878         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop MDS!"
879
880         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
881         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
882
883         echo "start $SINGLEMDS"
884         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
885                 error "(19) Fail to start MDS!"
886
887         timer=0
888         while [ $timer -lt $timeout ]; do
889                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
890                         mdt.${MDT_DEV}.recovery_status |
891                         awk '/^status/ { print \\\$2 }'")
892                 [ "$STATUS" != "RECOVERING" ] && break;
893                 sleep 1
894                 timer=$((timer + 1))
895         done
896
897         [ $timer != $timeout ] ||
898                 error "(19.1) recovery timeout"
899
900         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
901         [ "$STATUS" == "paused" ] ||
902                 error "(20) Expect 'paused', but got '$STATUS'"
903
904         #define OBD_FAIL_LFSCK_DELAY3           0x1602
905         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1602
906
907         $START_NAMESPACE || error "(21) Fail to start LFSCK for namespace!"
908         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
909                 mdd.${MDT_DEV}.lfsck_namespace |
910                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 32 || {
911                 $SHOW_NAMESPACE
912                 error "(22) unexpected status"
913         }
914
915         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
916         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
917                 error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
918
919         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
920         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
921                 mdd.${MDT_DEV}.lfsck_namespace |
922                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
923                 $SHOW_NAMESPACE
924                 error "(24) unexpected status"
925         }
926
927         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
928         [ -z "$FLAGS" ] || error "(25) Expect empty flags, but got '$FLAGS'"
929 }
930 run_test 8 "LFSCK state machine"
931
932 test_9a() {
933         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
934                 skip "Testing on UP system, the speed may be inaccurate."
935                 return 0
936         fi
937
938         lfsck_prep 70 70
939
940         local BASE_SPEED1=100
941         local RUN_TIME1=10
942         $START_NAMESPACE -r -s $BASE_SPEED1 || error "(3) Fail to start LFSCK!"
943
944         sleep $RUN_TIME1
945         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
946         [ "$STATUS" == "scanning-phase1" ] ||
947                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
948
949         local SPEED=$($SHOW_NAMESPACE |
950                       awk '/^average_speed_phase1/ { print $2 }')
951
952         # There may be time error, normally it should be less than 2 seconds.
953         # We allow another 20% schedule error.
954         local TIME_DIFF=2
955         # MAX_MARGIN = 1.2 = 12 / 10
956         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
957                            RUN_TIME1 * 12 / 10))
958         [ $SPEED -lt $MAX_SPEED ] ||
959                 error "(4) Got speed $SPEED, expected less than $MAX_SPEED"
960
961         # adjust speed limit
962         local BASE_SPEED2=300
963         local RUN_TIME2=10
964         do_facet $SINGLEMDS \
965                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
966         sleep $RUN_TIME2
967
968         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase1/ { print $2 }')
969         # MIN_MARGIN = 0.8 = 8 / 10
970         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
971                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
972                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
973         [ $SPEED -gt $MIN_SPEED ] || {
974                 if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
975                         error_ignore LU-5624 \
976                         "(5.1) Got speed $SPEED, expected more than $MIN_SPEED"
977                 else
978                         error \
979                         "(5.2) Got speed $SPEED, expected more than $MIN_SPEED"
980                 fi
981         }
982
983         # MAX_MARGIN = 1.2 = 12 / 10
984         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
985                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
986                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
987         [ $SPEED -lt $MAX_SPEED ] ||
988                 error "(6) Got speed $SPEED, expected less than $MAX_SPEED"
989
990         do_facet $SINGLEMDS \
991                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
992
993         wait_update_facet $SINGLEMDS \
994             "$LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace|\
995             awk '/^status/ { print \\\$2 }'" "completed" 30 ||
996                 error "(7) Failed to get expected 'completed'"
997 }
998 run_test 9a "LFSCK speed control (1)"
999
1000 test_9b() {
1001         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
1002                 skip "Testing on UP system, the speed may be inaccurate."
1003                 return 0
1004         fi
1005
1006         lfsck_prep 0 0
1007
1008         echo "Preparing another 50 * 50 files (with error) at $(date)."
1009         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1010         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1011         createmany -d $DIR/$tdir/d 50
1012         createmany -m $DIR/$tdir/f 50
1013         for ((i = 0; i < 50; i++)); do
1014                 createmany -m $DIR/$tdir/d${i}/f 50 > /dev/null
1015         done
1016
1017         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
1018         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
1019         $START_NAMESPACE -r || error "(4) Fail to start LFSCK!"
1020         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1021                 mdd.${MDT_DEV}.lfsck_namespace |
1022                 awk '/^status/ { print \\\$2 }'" "stopped" 10 || {
1023                 $SHOW_NAMESPACE
1024                 error "(5) unexpected status"
1025         }
1026
1027         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1028         echo "Prepared at $(date)."
1029
1030         local BASE_SPEED1=50
1031         local RUN_TIME1=10
1032         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
1033
1034         sleep $RUN_TIME1
1035         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1036         [ "$STATUS" == "scanning-phase2" ] ||
1037                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
1038
1039         local SPEED=$($SHOW_NAMESPACE |
1040                       awk '/^average_speed_phase2/ { print $2 }')
1041         # There may be time error, normally it should be less than 2 seconds.
1042         # We allow another 20% schedule error.
1043         local TIME_DIFF=2
1044         # MAX_MARGIN = 1.2 = 12 / 10
1045         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
1046                           RUN_TIME1 * 12 / 10))
1047         [ $SPEED -lt $MAX_SPEED ] ||
1048                 error "(8) Got speed $SPEED, expected less than $MAX_SPEED"
1049
1050         # adjust speed limit
1051         local BASE_SPEED2=150
1052         local RUN_TIME2=10
1053         do_facet $SINGLEMDS \
1054                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
1055         sleep $RUN_TIME2
1056
1057         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
1058         # MIN_MARGIN = 0.8 = 8 / 10
1059         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
1060                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
1061                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
1062         [ $SPEED -gt $MIN_SPEED ] || {
1063                 if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
1064                         error_ignore LU-5624 \
1065                         "(9.1) Got speed $SPEED, expected more than $MIN_SPEED"
1066                 else
1067                         error \
1068                         "(9.2) Got speed $SPEED, expected more than $MIN_SPEED"
1069                 fi
1070         }
1071
1072         # MAX_MARGIN = 1.2 = 12 / 10
1073         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
1074                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
1075                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
1076         [ $SPEED -lt $MAX_SPEED ] ||
1077                 error "(10) Got speed $SPEED, expected less than $MAX_SPEED"
1078
1079         do_facet $SINGLEMDS \
1080                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
1081         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1082                 mdd.${MDT_DEV}.lfsck_namespace |
1083                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1084                 $SHOW_NAMESPACE
1085                 error "(11) unexpected status"
1086         }
1087 }
1088 run_test 9b "LFSCK speed control (2)"
1089
1090 test_10()
1091 {
1092         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
1093                 skip "lookup(..)/linkea on ZFS issue" && return
1094
1095         lfsck_prep 1 1
1096
1097         echo "Preparing more files with error at $(date)."
1098         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
1099         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
1100
1101         for ((i = 0; i < 1000; i = $((i+2)))); do
1102                 mkdir -p $DIR/$tdir/d${i}
1103                 touch $DIR/$tdir/f${i}
1104                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1105         done
1106
1107         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
1108         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
1109
1110         for ((i = 1; i < 1000; i = $((i+2)))); do
1111                 mkdir -p $DIR/$tdir/d${i}
1112                 touch $DIR/$tdir/f${i}
1113                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
1114         done
1115
1116         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1117         echo "Prepared at $(date)."
1118
1119         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
1120
1121         umount_client $MOUNT
1122         mount_client $MOUNT || error "(3) Fail to start client!"
1123
1124         $START_NAMESPACE -r -s 100 || error "(5) Fail to start LFSCK!"
1125
1126         sleep 10
1127         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1128         [ "$STATUS" == "scanning-phase1" ] ||
1129                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
1130
1131         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
1132
1133         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
1134
1135         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
1136
1137         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
1138
1139         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
1140
1141         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
1142
1143         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
1144
1145         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
1146                 error "(14) Fail to softlink!"
1147
1148         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1149         [ "$STATUS" == "scanning-phase1" ] ||
1150                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
1151
1152         do_facet $SINGLEMDS \
1153                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
1154         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1155                 mdd.${MDT_DEV}.lfsck_namespace |
1156                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1157                 $SHOW_NAMESPACE
1158                 error "(16) unexpected status"
1159         }
1160 }
1161 run_test 10 "System is available during LFSCK scanning"
1162
1163 # remove LAST_ID
1164 ost_remove_lastid() {
1165         local ost=$1
1166         local idx=$2
1167         local rcmd="do_facet ost${ost}"
1168
1169         echo "remove LAST_ID on ost${ost}: idx=${idx}"
1170
1171         # step 1: local mount
1172         mount_fstype ost${ost} || return 1
1173         # step 2: remove the specified LAST_ID
1174         ${rcmd} rm -fv $(facet_mntpt ost${ost})/O/${idx}/{LAST_ID,d0/0}
1175         # step 3: umount
1176         unmount_fstype ost${ost} || return 2
1177 }
1178
1179 test_11a() {
1180         check_mount_and_prep
1181         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1182         createmany -o $DIR/$tdir/f 64 || error "(0) Fail to create 64 files."
1183
1184         echo "stopall"
1185         stopall > /dev/null
1186
1187         ost_remove_lastid 1 0 || error "(1) Fail to remove LAST_ID"
1188
1189         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
1190                 error "(2) Fail to start ost1"
1191
1192         #define OBD_FAIL_LFSCK_DELAY4           0x160e
1193         do_facet ost1 $LCTL set_param fail_val=3 fail_loc=0x160e
1194
1195         echo "trigger LFSCK for layout on ost1 to rebuild the LAST_ID(s)"
1196         $START_LAYOUT_ON_OST -r || error "(4) Fail to start LFSCK on OST!"
1197
1198         wait_update_facet ost1 "$LCTL get_param -n \
1199                 obdfilter.${OST_DEV}.lfsck_layout |
1200                 awk '/^flags/ { print \\\$2 }'" "crashed_lastid" 60 || {
1201                 $SHOW_LAYOUT_ON_OST
1202                 error "(5) unexpected status"
1203         }
1204
1205         do_facet ost1 $LCTL set_param fail_val=0 fail_loc=0
1206
1207         wait_update_facet ost1 "$LCTL get_param -n \
1208                 obdfilter.${OST_DEV}.lfsck_layout |
1209                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1210                 $SHOW_LAYOUT_ON_OST
1211                 error "(6) unexpected status"
1212         }
1213
1214         echo "the LAST_ID(s) should have been rebuilt"
1215         FLAGS=$($SHOW_LAYOUT_ON_OST | awk '/^flags/ { print $2 }')
1216         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
1217 }
1218 run_test 11a "LFSCK can rebuild lost last_id"
1219
1220 test_11b() {
1221         check_mount_and_prep
1222         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1223
1224         echo "set fail_loc=0x160d to skip the updating LAST_ID on-disk"
1225         #define OBD_FAIL_LFSCK_SKIP_LASTID      0x160d
1226         do_facet ost1 $LCTL set_param fail_loc=0x160d
1227         createmany -o $DIR/$tdir/f 64
1228         local lastid1=$(do_facet ost1 "lctl get_param -n \
1229                 obdfilter.${ost1_svc}.last_id" | grep 0x100000000 |
1230                 awk -F: '{ print $2 }')
1231
1232         umount_client $MOUNT
1233         stop ost1 || error "(1) Fail to stop ost1"
1234
1235         #define OBD_FAIL_OST_ENOSPC              0x215
1236         do_facet ost1 $LCTL set_param fail_loc=0x215
1237
1238         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1239                 error "(2) Fail to start ost1"
1240
1241         for ((i = 0; i < 60; i++)); do
1242                 lastid2=$(do_facet ost1 "lctl get_param -n \
1243                         obdfilter.${ost1_svc}.last_id" | grep 0x100000000 |
1244                         awk -F: '{ print $2 }')
1245                 [ ! -z $lastid2 ] && break;
1246                 sleep 1
1247         done
1248
1249         echo "the on-disk LAST_ID should be smaller than the expected one"
1250         [ $lastid1 -gt $lastid2 ] ||
1251                 error "(4) expect lastid1 [ $lastid1 ] > lastid2 [ $lastid2 ]"
1252
1253         echo "trigger LFSCK for layout on ost1 to rebuild the on-disk LAST_ID"
1254         $START_LAYOUT_ON_OST -r || error "(5) Fail to start LFSCK on OST!"
1255
1256         wait_update_facet ost1 "$LCTL get_param -n \
1257                 obdfilter.${OST_DEV}.lfsck_layout |
1258                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1259                 $SHOW_LAYOUT_ON_OST
1260                 error "(6) unexpected status"
1261         }
1262
1263         stop ost1 || error "(7) Fail to stop ost1"
1264
1265         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1266                 error "(8) Fail to start ost1"
1267
1268         echo "the on-disk LAST_ID should have been rebuilt"
1269         wait_update_facet ost1 "$LCTL get_param -n \
1270                 obdfilter.${ost1_svc}.last_id | grep 0x100000000 |
1271                 awk -F: '{ print \\\$2 }'" "$lastid1" 60 || {
1272                 $LCTL get_param -n obdfilter.${ost1_svc}.last_id
1273                 error "(9) expect lastid1 0x100000000:$lastid1"
1274         }
1275
1276         do_facet ost1 $LCTL set_param fail_loc=0
1277         stopall || error "(10) Fail to stopall"
1278 }
1279 run_test 11b "LFSCK can rebuild crashed last_id"
1280
1281 test_12() {
1282         [ $MDSCOUNT -lt 2 ] &&
1283                 skip "We need at least 2 MDSes for test_12" && return
1284
1285         check_mount_and_prep
1286         for k in $(seq $MDSCOUNT); do
1287                 $LFS mkdir -i $((k - 1)) $DIR/$tdir/${k}
1288                 createmany -o $DIR/$tdir/${k}/f 100 ||
1289                         error "(0) Fail to create 100 files."
1290         done
1291
1292         echo "Start namespace LFSCK on all targets by single command (-s 1)."
1293         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1294                 -s 1 -r || error "(2) Fail to start LFSCK on all devices!"
1295
1296         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1297         for k in $(seq $MDSCOUNT); do
1298                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1299                                 mdd.$(facet_svc mds${k}).lfsck_namespace |
1300                                 awk '/^status/ { print $2 }')
1301                 [ "$STATUS" == "scanning-phase1" ] ||
1302                 error "(3) MDS${k} Expect 'scanning-phase1', but got '$STATUS'"
1303         done
1304
1305         echo "Stop namespace LFSCK on all targets by single lctl command."
1306         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1307                 error "(4) Fail to stop LFSCK on all devices!"
1308
1309         echo "All the LFSCK targets should be in 'stopped' status."
1310         for k in $(seq $MDSCOUNT); do
1311                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1312                                 mdd.$(facet_svc mds${k}).lfsck_namespace |
1313                                 awk '/^status/ { print $2 }')
1314                 [ "$STATUS" == "stopped" ] ||
1315                         error "(5) MDS${k} Expect 'stopped', but got '$STATUS'"
1316         done
1317
1318         echo "Re-start namespace LFSCK on all targets by single command (-s 0)."
1319         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1320                 -s 0 -r || error "(6) Fail to start LFSCK on all devices!"
1321
1322         echo "All the LFSCK targets should be in 'completed' status."
1323         for k in $(seq $MDSCOUNT); do
1324                 wait_update_facet mds${k} "$LCTL get_param -n \
1325                         mdd.$(facet_svc mds${k}).lfsck_namespace |
1326                         awk '/^status/ { print \\\$2 }'" "completed" 8 ||
1327                         error "(7) MDS${k} is not the expected 'completed'"
1328         done
1329
1330         echo "Start layout LFSCK on all targets by single command (-s 1)."
1331         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1332                 -s 1 -r || error "(8) Fail to start LFSCK on all devices!"
1333
1334         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1335         for k in $(seq $MDSCOUNT); do
1336                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1337                                 mdd.$(facet_svc mds${k}).lfsck_layout |
1338                                 awk '/^status/ { print $2 }')
1339                 [ "$STATUS" == "scanning-phase1" ] ||
1340                 error "(9) MDS${k} Expect 'scanning-phase1', but got '$STATUS'"
1341         done
1342
1343         echo "Stop layout LFSCK on all targets by single lctl command."
1344         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1345                 error "(10) Fail to stop LFSCK on all devices!"
1346
1347         echo "All the LFSCK targets should be in 'stopped' status."
1348         for k in $(seq $MDSCOUNT); do
1349                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1350                                 mdd.$(facet_svc mds${k}).lfsck_layout |
1351                                 awk '/^status/ { print $2 }')
1352                 [ "$STATUS" == "stopped" ] ||
1353                         error "(11) MDS${k} Expect 'stopped', but got '$STATUS'"
1354         done
1355
1356         for k in $(seq $OSTCOUNT); do
1357                 local STATUS=$(do_facet ost${k} $LCTL get_param -n \
1358                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1359                                 awk '/^status/ { print $2 }')
1360                 [ "$STATUS" == "stopped" ] ||
1361                         error "(12) OST${k} Expect 'stopped', but got '$STATUS'"
1362         done
1363
1364         echo "Re-start layout LFSCK on all targets by single command (-s 0)."
1365         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1366                 -s 0 -r || error "(13) Fail to start LFSCK on all devices!"
1367
1368         echo "All the LFSCK targets should be in 'completed' status."
1369         for k in $(seq $MDSCOUNT); do
1370                 # The LFSCK status query internal is 30 seconds. For the case
1371                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1372                 # time to guarantee the status sync up.
1373                 wait_update_facet mds${k} "$LCTL get_param -n \
1374                         mdd.$(facet_svc mds${k}).lfsck_layout |
1375                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
1376                         error "(14) MDS${k} is not the expected 'completed'"
1377         done
1378 }
1379 run_test 12 "single command to trigger LFSCK on all devices"
1380
1381 test_13() {
1382         echo "#####"
1383         echo "The lmm_oi in layout EA should be consistent with the MDT-object"
1384         echo "FID; otherwise, the LFSCK should re-generate the lmm_oi from the"
1385         echo "MDT-object FID."
1386         echo "#####"
1387
1388         check_mount_and_prep
1389
1390         echo "Inject failure stub to simulate bad lmm_oi"
1391         #define OBD_FAIL_LFSCK_BAD_LMMOI        0x160f
1392         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160f
1393         createmany -o $DIR/$tdir/f 32
1394         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1395
1396         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
1397         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1398
1399         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1400                 mdd.${MDT_DEV}.lfsck_layout |
1401                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1402                 $SHOW_LAYOUT
1403                 error "(2) unexpected status"
1404         }
1405
1406         local repaired=$($SHOW_LAYOUT |
1407                          awk '/^repaired_others/ { print $2 }')
1408         [ $repaired -eq 32 ] ||
1409                 error "(3) Fail to repair crashed lmm_oi: $repaired"
1410 }
1411 run_test 13 "LFSCK can repair crashed lmm_oi"
1412
1413 test_14() {
1414         echo "#####"
1415         echo "The OST-object referenced by the MDT-object should be there;"
1416         echo "otherwise, the LFSCK should re-create the missing OST-object."
1417         echo "#####"
1418
1419         check_mount_and_prep
1420         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1421
1422         local count=$(precreated_ost_obj_count 0 0)
1423
1424         echo "Inject failure stub to simulate dangling referenced MDT-object"
1425         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1426         do_facet ost1 $LCTL set_param fail_loc=0x1610
1427         createmany -o $DIR/$tdir/f $((count + 31))
1428         touch $DIR/$tdir/guard
1429         do_facet ost1 $LCTL set_param fail_loc=0
1430
1431         start_full_debug_logging
1432
1433         # exhaust other pre-created dangling cases
1434         count=$(precreated_ost_obj_count 0 0)
1435         createmany -o $DIR/$tdir/a $count ||
1436                 error "(0) Fail to create $count files."
1437
1438         echo "'ls' should fail because of dangling referenced MDT-object"
1439         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1440
1441         echo "Trigger layout LFSCK to find out dangling reference"
1442         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1443
1444         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1445                 mdd.${MDT_DEV}.lfsck_layout |
1446                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1447                 $SHOW_LAYOUT
1448                 error "(3) unexpected status"
1449         }
1450
1451         local repaired=$($SHOW_LAYOUT |
1452                          awk '/^repaired_dangling/ { print $2 }')
1453         [ $repaired -ge 32 ] ||
1454                 error "(4) Fail to repair dangling reference: $repaired"
1455
1456         echo "'stat' should fail because of not repair dangling by default"
1457         stat $DIR/$tdir/guard > /dev/null 2>&1 && error "(5) stat should fail"
1458
1459         echo "Trigger layout LFSCK to repair dangling reference"
1460         $START_LAYOUT -r -c || error "(6) Fail to start LFSCK for layout!"
1461
1462         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1463                 mdd.${MDT_DEV}.lfsck_layout |
1464                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1465                 $SHOW_LAYOUT
1466                 error "(7) unexpected status"
1467         }
1468
1469         # There may be some async LFSCK updates in processing, wait for
1470         # a while until the target reparation has been done. LU-4970.
1471
1472         echo "'stat' should success after layout LFSCK repairing"
1473         wait_update_facet client "stat $DIR/$tdir/guard |
1474                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
1475                 stat $DIR/$tdir/guard
1476                 $SHOW_LAYOUT
1477                 error "(8) unexpected size"
1478         }
1479
1480         repaired=$($SHOW_LAYOUT |
1481                          awk '/^repaired_dangling/ { print $2 }')
1482         [ $repaired -ge 32 ] ||
1483                 error "(9) Fail to repair dangling reference: $repaired"
1484
1485         stop_full_debug_logging
1486 }
1487 run_test 14 "LFSCK can repair MDT-object with dangling reference"
1488
1489 test_15a() {
1490         echo "#####"
1491         echo "If the OST-object referenced by the MDT-object back points"
1492         echo "to some non-exist MDT-object, then the LFSCK should repair"
1493         echo "the OST-object to back point to the right MDT-object."
1494         echo "#####"
1495
1496         check_mount_and_prep
1497         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1498
1499         echo "Inject failure stub to make the OST-object to back point to"
1500         echo "non-exist MDT-object."
1501         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
1502
1503         do_facet ost1 $LCTL set_param fail_loc=0x1611
1504         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1505         cancel_lru_locks osc
1506         do_facet ost1 $LCTL set_param fail_loc=0
1507
1508         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1509         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1510
1511         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1512                 mdd.${MDT_DEV}.lfsck_layout |
1513                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1514                 $SHOW_LAYOUT
1515                 error "(2) unexpected status"
1516         }
1517
1518         local repaired=$($SHOW_LAYOUT |
1519                          awk '/^repaired_unmatched_pair/ { print $2 }')
1520         [ $repaired -eq 1 ] ||
1521                 error "(3) Fail to repair unmatched pair: $repaired"
1522 }
1523 run_test 15a "LFSCK can repair unmatched MDT-object/OST-object pairs (1)"
1524
1525 test_15b() {
1526         echo "#####"
1527         echo "If the OST-object referenced by the MDT-object back points"
1528         echo "to other MDT-object that doesn't recognize the OST-object,"
1529         echo "then the LFSCK should repair it to back point to the right"
1530         echo "MDT-object (the first one)."
1531         echo "#####"
1532
1533         check_mount_and_prep
1534         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1535         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
1536         cancel_lru_locks osc
1537
1538         echo "Inject failure stub to make the OST-object to back point to"
1539         echo "other MDT-object"
1540
1541         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR2  0x1612
1542         do_facet ost1 $LCTL set_param fail_loc=0x1612
1543         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1544         cancel_lru_locks osc
1545         do_facet ost1 $LCTL set_param fail_loc=0
1546
1547         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1548         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1549
1550         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1551                 mdd.${MDT_DEV}.lfsck_layout |
1552                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1553                 $SHOW_LAYOUT
1554                 error "(2) unexpected status"
1555         }
1556
1557         local repaired=$($SHOW_LAYOUT |
1558                          awk '/^repaired_unmatched_pair/ { print $2 }')
1559         [ $repaired -eq 1 ] ||
1560                 error "(3) Fail to repair unmatched pair: $repaired"
1561 }
1562 run_test 15b "LFSCK can repair unmatched MDT-object/OST-object pairs (2)"
1563
1564 test_16() {
1565         echo "#####"
1566         echo "If the OST-object's owner information does not match the owner"
1567         echo "information stored in the MDT-object, then the LFSCK trust the"
1568         echo "MDT-object and update the OST-object's owner information."
1569         echo "#####"
1570
1571         check_mount_and_prep
1572         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1573         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1574         cancel_lru_locks osc
1575
1576         echo "Inject failure stub to skip OST-object owner changing"
1577         #define OBD_FAIL_LFSCK_BAD_OWNER        0x1613
1578         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1613
1579         chown 1.1 $DIR/$tdir/f0
1580         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1581
1582         echo "Trigger layout LFSCK to find out inconsistent OST-object owner"
1583         echo "and fix them"
1584
1585         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1586
1587         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1588                 mdd.${MDT_DEV}.lfsck_layout |
1589                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1590                 $SHOW_LAYOUT
1591                 error "(2) unexpected status"
1592         }
1593
1594         local repaired=$($SHOW_LAYOUT |
1595                          awk '/^repaired_inconsistent_owner/ { print $2 }')
1596         [ $repaired -eq 1 ] ||
1597                 error "(3) Fail to repair inconsistent owner: $repaired"
1598 }
1599 run_test 16 "LFSCK can repair inconsistent MDT-object/OST-object owner"
1600
1601 test_17() {
1602         echo "#####"
1603         echo "If more than one MDT-objects reference the same OST-object,"
1604         echo "and the OST-object only recognizes one MDT-object, then the"
1605         echo "LFSCK should create new OST-objects for such non-recognized"
1606         echo "MDT-objects."
1607         echo "#####"
1608
1609         check_mount_and_prep
1610         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1611
1612         echo "Inject failure stub to make two MDT-objects to refernce"
1613         echo "the OST-object"
1614
1615         #define OBD_FAIL_LFSCK_MULTIPLE_REF     0x1614
1616         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0x1614
1617
1618         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
1619         cancel_lru_locks osc
1620
1621         createmany -o $DIR/$tdir/f 1
1622
1623         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1624
1625         cancel_lru_locks mdc
1626         cancel_lru_locks osc
1627
1628         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard use the same OST-objects"
1629         local size=$(ls -l $DIR/$tdir/f0 | awk '{ print $5 }')
1630         [ $size -eq 1048576 ] ||
1631                 error "(1) f0 (wrong) size should be 1048576, but got $size"
1632
1633         echo "Trigger layout LFSCK to find out multiple refenced MDT-objects"
1634         echo "and fix them"
1635
1636         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1637
1638         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1639                 mdd.${MDT_DEV}.lfsck_layout |
1640                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
1641                 $SHOW_LAYOUT
1642                 error "(3) unexpected status"
1643         }
1644
1645         local repaired=$($SHOW_LAYOUT |
1646                          awk '/^repaired_multiple_referenced/ { print $2 }')
1647         [ $repaired -eq 1 ] ||
1648                 error "(4) Fail to repair multiple references: $repaired"
1649
1650         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard should use diff OST-objects"
1651         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=2 ||
1652                 error "(5) Fail to write f0."
1653         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
1654         [ $size -eq 1048576 ] ||
1655                 error "(6) guard size should be 1048576, but got $size"
1656 }
1657 run_test 17 "LFSCK can repair multiple references"
1658
1659 $LCTL set_param debug=+cache > /dev/null
1660
1661 test_18a() {
1662         echo "#####"
1663         echo "The target MDT-object is there, but related stripe information"
1664         echo "is lost or partly lost. The LFSCK should regenerate the missing"
1665         echo "layout EA entries."
1666         echo "#####"
1667
1668         check_mount_and_prep
1669         $LFS mkdir -i 0 $DIR/$tdir/a1
1670         $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a1
1671         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
1672
1673         local saved_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1674
1675         $LFS path2fid $DIR/$tdir/a1/f1
1676         $LFS getstripe $DIR/$tdir/a1/f1
1677
1678         if [ $MDSCOUNT -ge 2 ]; then
1679                 $LFS mkdir -i 1 $DIR/$tdir/a2
1680                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
1681                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
1682                 $LFS path2fid $DIR/$tdir/a2/f2
1683                 $LFS getstripe $DIR/$tdir/a2/f2
1684         fi
1685
1686         cancel_lru_locks osc
1687
1688         echo "Inject failure, to make the MDT-object lost its layout EA"
1689         #define OBD_FAIL_LFSCK_LOST_STRIPE 0x1615
1690         do_facet mds1 $LCTL set_param fail_loc=0x1615
1691         chown 1.1 $DIR/$tdir/a1/f1
1692
1693         if [ $MDSCOUNT -ge 2 ]; then
1694                 do_facet mds2 $LCTL set_param fail_loc=0x1615
1695                 chown 1.1 $DIR/$tdir/a2/f2
1696         fi
1697
1698         sync
1699         sleep 2
1700
1701         do_facet mds1 $LCTL set_param fail_loc=0
1702         if [ $MDSCOUNT -ge 2 ]; then
1703                 do_facet mds2 $LCTL set_param fail_loc=0
1704         fi
1705
1706         cancel_lru_locks mdc
1707         cancel_lru_locks osc
1708
1709         echo "The file size should be incorrect since layout EA is lost"
1710         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1711         [ "$cur_size" != "$saved_size" ] ||
1712                 error "(1) Expect incorrect file1 size"
1713
1714         if [ $MDSCOUNT -ge 2 ]; then
1715                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
1716                 [ "$cur_size" != "$saved_size" ] ||
1717                         error "(2) Expect incorrect file2 size"
1718         fi
1719
1720         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1721         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
1722
1723         for k in $(seq $MDSCOUNT); do
1724                 # The LFSCK status query internal is 30 seconds. For the case
1725                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1726                 # time to guarantee the status sync up.
1727                 wait_update_facet mds${k} "$LCTL get_param -n \
1728                         mdd.$(facet_svc mds${k}).lfsck_layout |
1729                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
1730                         error "(4) MDS${k} is not the expected 'completed'"
1731         done
1732
1733         for k in $(seq $OSTCOUNT); do
1734                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
1735                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1736                                 awk '/^status/ { print $2 }')
1737                 [ "$cur_status" == "completed" ] ||
1738                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
1739         done
1740
1741         local repaired=$(do_facet mds1 $LCTL get_param -n \
1742                          mdd.$(facet_svc mds1).lfsck_layout |
1743                          awk '/^repaired_orphan/ { print $2 }')
1744         [ $repaired -eq 1 ] ||
1745         error "(6.1) Expect 1 fixed on mds1, but got: $repaired"
1746
1747         if [ $MDSCOUNT -ge 2 ]; then
1748                 repaired=$(do_facet mds2 $LCTL get_param -n \
1749                          mdd.$(facet_svc mds2).lfsck_layout |
1750                                  awk '/^repaired_orphan/ { print $2 }')
1751                 [ $repaired -eq 2 ] ||
1752                 error "(6.2) Expect 2 fixed on mds2, but got: $repaired"
1753         fi
1754
1755         $LFS path2fid $DIR/$tdir/a1/f1
1756         $LFS getstripe $DIR/$tdir/a1/f1
1757
1758         if [ $MDSCOUNT -ge 2 ]; then
1759                 $LFS path2fid $DIR/$tdir/a2/f2
1760                 $LFS getstripe $DIR/$tdir/a2/f2
1761         fi
1762
1763         echo "The file size should be correct after layout LFSCK scanning"
1764         cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1765         [ "$cur_size" == "$saved_size" ] ||
1766                 error "(7) Expect file1 size $saved_size, but got $cur_size"
1767
1768         if [ $MDSCOUNT -ge 2 ]; then
1769                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
1770                 [ "$cur_size" == "$saved_size" ] ||
1771                 error "(8) Expect file2 size $saved_size, but got $cur_size"
1772         fi
1773 }
1774 run_test 18a "Find out orphan OST-object and repair it (1)"
1775
1776 test_18b() {
1777         echo "#####"
1778         echo "The target MDT-object is lost. The LFSCK should re-create the"
1779         echo "MDT-object under .lustre/lost+found/MDTxxxx. The admin should"
1780         echo "can move it back to normal namespace manually."
1781         echo "#####"
1782
1783         check_mount_and_prep
1784         $LFS mkdir -i 0 $DIR/$tdir/a1
1785         $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a1
1786         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
1787         local saved_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1788         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
1789         echo ${fid1}
1790         $LFS getstripe $DIR/$tdir/a1/f1
1791
1792         if [ $MDSCOUNT -ge 2 ]; then
1793                 $LFS mkdir -i 1 $DIR/$tdir/a2
1794                 $LFS setstripe -c 2 -i 1 -S 1M $DIR/$tdir/a2
1795                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
1796                 fid2=$($LFS path2fid $DIR/$tdir/a2/f2)
1797                 echo ${fid2}
1798                 $LFS getstripe $DIR/$tdir/a2/f2
1799         fi
1800
1801         cancel_lru_locks osc
1802
1803         echo "Inject failure, to simulate the case of missing the MDT-object"
1804         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
1805         do_facet mds1 $LCTL set_param fail_loc=0x1616
1806         rm -f $DIR/$tdir/a1/f1
1807
1808         if [ $MDSCOUNT -ge 2 ]; then
1809                 do_facet mds2 $LCTL set_param fail_loc=0x1616
1810                 rm -f $DIR/$tdir/a2/f2
1811         fi
1812
1813         sync
1814         sleep 2
1815
1816         do_facet mds1 $LCTL set_param fail_loc=0
1817         if [ $MDSCOUNT -ge 2 ]; then
1818                 do_facet mds2 $LCTL set_param fail_loc=0
1819         fi
1820
1821         cancel_lru_locks mdc
1822         cancel_lru_locks osc
1823
1824         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1825         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
1826
1827         for k in $(seq $MDSCOUNT); do
1828                 # The LFSCK status query internal is 30 seconds. For the case
1829                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1830                 # time to guarantee the status sync up.
1831                 wait_update_facet mds${k} "$LCTL get_param -n \
1832                         mdd.$(facet_svc mds${k}).lfsck_layout |
1833                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
1834                         error "(2) MDS${k} is not the expected 'completed'"
1835         done
1836
1837         for k in $(seq $OSTCOUNT); do
1838                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
1839                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1840                                 awk '/^status/ { print $2 }')
1841                 [ "$cur_status" == "completed" ] ||
1842                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
1843         done
1844
1845         local repaired=$(do_facet mds1 $LCTL get_param -n \
1846                          mdd.$(facet_svc mds1).lfsck_layout |
1847                          awk '/^repaired_orphan/ { print $2 }')
1848         [ $repaired -eq 1 ] ||
1849         error "(4.1) Expect 1 fixed on mds1, but got: $repaired"
1850
1851         if [ $MDSCOUNT -ge 2 ]; then
1852                 repaired=$(do_facet mds2 $LCTL get_param -n \
1853                          mdd.$(facet_svc mds2).lfsck_layout |
1854                          awk '/^repaired_orphan/ { print $2 }')
1855                 [ $repaired -eq 2 ] ||
1856                 error "(4.2) Expect 2 fixed on mds2, but got: $repaired"
1857         fi
1858
1859         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
1860         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
1861         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
1862
1863         if [ $MDSCOUNT -ge 2 ]; then
1864                 local name=$MOUNT/.lustre/lost+found/MDT0001/${fid2}-R-0
1865                 mv $name $DIR/$tdir/a2/f2 || error "(6) Fail to move $name"
1866         fi
1867
1868         $LFS path2fid $DIR/$tdir/a1/f1
1869         $LFS getstripe $DIR/$tdir/a1/f1
1870
1871         if [ $MDSCOUNT -ge 2 ]; then
1872                 $LFS path2fid $DIR/$tdir/a2/f2
1873                 $LFS getstripe $DIR/$tdir/a2/f2
1874         fi
1875
1876         echo "The file size should be correct after layout LFSCK scanning"
1877         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1878         [ "$cur_size" == "$saved_size" ] ||
1879                 error "(7) Expect file1 size $saved_size, but got $cur_size"
1880
1881         if [ $MDSCOUNT -ge 2 ]; then
1882                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
1883                 [ "$cur_size" == "$saved_size" ] ||
1884                 error "(8) Expect file2 size $saved_size, but got $cur_size"
1885         fi
1886 }
1887 run_test 18b "Find out orphan OST-object and repair it (2)"
1888
1889 test_18c() {
1890         echo "#####"
1891         echo "The target MDT-object is lost, and the OST-object FID is missing."
1892         echo "The LFSCK should re-create the MDT-object with new FID under the "
1893         echo "directory .lustre/lost+found/MDTxxxx."
1894         echo "#####"
1895
1896         check_mount_and_prep
1897         $LFS mkdir -i 0 $DIR/$tdir/a1
1898         $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a1
1899
1900         echo "Inject failure, to simulate the case of missing parent FID"
1901         #define OBD_FAIL_LFSCK_NOPFID           0x1617
1902         do_facet ost1 $LCTL set_param fail_loc=0x1617
1903
1904         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
1905         $LFS getstripe $DIR/$tdir/a1/f1
1906
1907         if [ $MDSCOUNT -ge 2 ]; then
1908                 $LFS mkdir -i 1 $DIR/$tdir/a2
1909                 $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a2
1910                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
1911                 $LFS getstripe $DIR/$tdir/a2/f2
1912         fi
1913
1914         cancel_lru_locks osc
1915
1916         echo "Inject failure, to simulate the case of missing the MDT-object"
1917         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
1918         do_facet mds1 $LCTL set_param fail_loc=0x1616
1919         rm -f $DIR/$tdir/a1/f1
1920
1921         if [ $MDSCOUNT -ge 2 ]; then
1922                 do_facet mds2 $LCTL set_param fail_loc=0x1616
1923                 rm -f $DIR/$tdir/a2/f2
1924         fi
1925
1926         sync
1927         sleep 2
1928
1929         do_facet mds1 $LCTL set_param fail_loc=0
1930         if [ $MDSCOUNT -ge 2 ]; then
1931                 do_facet mds2 $LCTL set_param fail_loc=0
1932         fi
1933
1934         cancel_lru_locks mdc
1935         cancel_lru_locks osc
1936
1937         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1938         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
1939
1940         for k in $(seq $MDSCOUNT); do
1941                 # The LFSCK status query internal is 30 seconds. For the case
1942                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1943                 # time to guarantee the status sync up.
1944                 wait_update_facet mds${k} "$LCTL get_param -n \
1945                         mdd.$(facet_svc mds${k}).lfsck_layout |
1946                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
1947                         error "(2) MDS${k} is not the expected 'completed'"
1948         done
1949
1950         for k in $(seq $OSTCOUNT); do
1951                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
1952                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1953                                 awk '/^status/ { print $2 }')
1954                 [ "$cur_status" == "completed" ] ||
1955                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
1956         done
1957
1958         if [ $MDSCOUNT -ge 2 ]; then
1959                 expected=2
1960         else
1961                 expected=1
1962         fi
1963
1964         local repaired=$(do_facet mds1 $LCTL get_param -n \
1965                          mdd.$(facet_svc mds1).lfsck_layout |
1966                          awk '/^repaired_orphan/ { print $2 }')
1967         [ $repaired -eq $expected ] ||
1968                 error "(4) Expect $expected fixed on mds1, but got: $repaired"
1969
1970         if [ $MDSCOUNT -ge 2 ]; then
1971                 repaired=$(do_facet mds2 $LCTL get_param -n \
1972                            mdd.$(facet_svc mds2).lfsck_layout |
1973                            awk '/^repaired_orphan/ { print $2 }')
1974                 [ $repaired -eq 0 ] ||
1975                         error "(5) Expect 0 fixed on mds2, but got: $repaired"
1976         fi
1977
1978         ls -ail $MOUNT/.lustre/lost+found/
1979
1980         echo "There should NOT be some stub under .lustre/lost+found/MDT0001/"
1981         if [ -d $MOUNT/.lustre/lost+found/MDT0001 ]; then
1982                 cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-N-*)
1983                 [ -z "$cname" ] ||
1984                         error "(6) .lustre/lost+found/MDT0001/ should be empty"
1985         fi
1986
1987         echo "There should be some stub under .lustre/lost+found/MDT0000/"
1988         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
1989                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
1990
1991         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-N-*)
1992         [ ! -z "$cname" ] ||
1993                 error "(8) .lustre/lost+found/MDT0000/ should not be empty"
1994 }
1995 run_test 18c "Find out orphan OST-object and repair it (3)"
1996
1997 test_18d() {
1998         echo "#####"
1999         echo "The target MDT-object layout EA slot is occpuied by some new"
2000         echo "created OST-object when repair dangling reference case. Such"
2001         echo "conflict OST-object has never been modified. Then when found"
2002         echo "the orphan OST-object, LFSCK will replace it with the orphan"
2003         echo "OST-object."
2004         echo "#####"
2005
2006         check_mount_and_prep
2007         mkdir $DIR/$tdir/a1
2008         $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a1
2009         echo "guard" > $DIR/$tdir/a1/f1
2010         echo "foo" > $DIR/$tdir/a1/f2
2011         local saved_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2012         $LFS path2fid $DIR/$tdir/a1/f1
2013         $LFS getstripe $DIR/$tdir/a1/f1
2014         $LFS path2fid $DIR/$tdir/a1/f2
2015         $LFS getstripe $DIR/$tdir/a1/f2
2016         cancel_lru_locks osc
2017
2018         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2019         echo "to reference the same OST-object (which is f1's OST-obejct)."
2020         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2021         echo "dangling reference case, but f2's old OST-object is there."
2022         echo
2023
2024         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2025         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2026         chown 1.1 $DIR/$tdir/a1/f2
2027         rm -f $DIR/$tdir/a1/f1
2028         sync
2029         sleep 2
2030         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2031
2032         echo "stopall to cleanup object cache"
2033         stopall > /dev/null
2034         echo "setupall"
2035         setupall > /dev/null
2036
2037         echo "The file size should be incorrect since dangling referenced"
2038         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2039         [ "$cur_size" != "$saved_size" ] ||
2040                 error "(1) Expect incorrect file2 size"
2041
2042         #define OBD_FAIL_LFSCK_DELAY3           0x1602
2043         do_facet $SINGLEMDS $LCTL set_param fail_val=5 fail_loc=0x1602
2044
2045         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2046         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
2047
2048         wait_update_facet mds1 "$LCTL get_param -n \
2049                 mdd.$(facet_svc mds1).lfsck_layout |
2050                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" $LTIME ||
2051                 error "(3.0) MDS1 is not the expected 'scanning-phase2'"
2052
2053         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2054
2055         for k in $(seq $MDSCOUNT); do
2056                 # The LFSCK status query internal is 30 seconds. For the case
2057                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2058                 # time to guarantee the status sync up.
2059                 wait_update_facet mds${k} "$LCTL get_param -n \
2060                         mdd.$(facet_svc mds${k}).lfsck_layout |
2061                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2062                         error "(3) MDS${k} is not the expected 'completed'"
2063         done
2064
2065         for k in $(seq $OSTCOUNT); do
2066                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2067                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2068                                 awk '/^status/ { print $2 }')
2069                 [ "$cur_status" == "completed" ] ||
2070                 error "(4) OST${k} Expect 'completed', but got '$cur_status'"
2071         done
2072
2073         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2074                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2075                          awk '/^repaired_orphan/ { print $2 }')
2076         [ $repaired -eq 1 ] ||
2077                 error "(5) Expect 1 orphan has been fixed, but got: $repaired"
2078
2079         echo "The file size should be correct after layout LFSCK scanning"
2080         cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2081         [ "$cur_size" == "$saved_size" ] ||
2082                 error "(6) Expect file2 size $saved_size, but got $cur_size"
2083
2084         echo "The LFSCK should find back the original data."
2085         cat $DIR/$tdir/a1/f2
2086         $LFS path2fid $DIR/$tdir/a1/f2
2087         $LFS getstripe $DIR/$tdir/a1/f2
2088 }
2089 run_test 18d "Find out orphan OST-object and repair it (4)"
2090
2091 test_18e() {
2092         echo "#####"
2093         echo "The target MDT-object layout EA slot is occpuied by some new"
2094         echo "created OST-object when repair dangling reference case. Such"
2095         echo "conflict OST-object has been modified by others. To keep the"
2096         echo "new data, the LFSCK will create a new file to refernece this"
2097         echo "old orphan OST-object."
2098         echo "#####"
2099
2100         check_mount_and_prep
2101         mkdir $DIR/$tdir/a1
2102         $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a1
2103         echo "guard" > $DIR/$tdir/a1/f1
2104         echo "foo" > $DIR/$tdir/a1/f2
2105         local saved_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2106         $LFS path2fid $DIR/$tdir/a1/f1
2107         $LFS getstripe $DIR/$tdir/a1/f1
2108         $LFS path2fid $DIR/$tdir/a1/f2
2109         $LFS getstripe $DIR/$tdir/a1/f2
2110         cancel_lru_locks osc
2111
2112         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
2113         echo "to reference the same OST-object (which is f1's OST-obejct)."
2114         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
2115         echo "dangling reference case, but f2's old OST-object is there."
2116         echo
2117
2118         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
2119         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
2120         chown 1.1 $DIR/$tdir/a1/f2
2121         rm -f $DIR/$tdir/a1/f1
2122         sync
2123         sleep 2
2124         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2125
2126         echo "stopall to cleanup object cache"
2127         stopall > /dev/null
2128         echo "setupall"
2129         setupall > /dev/null
2130
2131         echo "The file size should be incorrect since dangling referenced"
2132         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
2133         [ "$cur_size" != "$saved_size" ] ||
2134                 error "(1) Expect incorrect file2 size"
2135
2136         #define OBD_FAIL_LFSCK_DELAY3           0x1602
2137         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
2138
2139         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2140         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
2141
2142         wait_update_facet mds1 "$LCTL get_param -n \
2143                 mdd.$(facet_svc mds1).lfsck_layout |
2144                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" $LTIME ||
2145                 error "(3) MDS1 is not the expected 'scanning-phase2'"
2146
2147         # to guarantee all updates are synced.
2148         sync
2149         sleep 2
2150
2151         echo "Write new data to f2 to modify the new created OST-object."
2152         echo "dummy" >> $DIR/$tdir/a1/f2
2153
2154         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2155
2156         for k in $(seq $MDSCOUNT); do
2157                 # The LFSCK status query internal is 30 seconds. For the case
2158                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2159                 # time to guarantee the status sync up.
2160                 wait_update_facet mds${k} "$LCTL get_param -n \
2161                         mdd.$(facet_svc mds${k}).lfsck_layout |
2162                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2163                         error "(4) MDS${k} is not the expected 'completed'"
2164         done
2165
2166         for k in $(seq $OSTCOUNT); do
2167                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2168                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2169                                 awk '/^status/ { print $2 }')
2170                 [ "$cur_status" == "completed" ] ||
2171                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2172         done
2173
2174         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2175                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2176                          awk '/^repaired_orphan/ { print $2 }')
2177         [ $repaired -eq 1 ] ||
2178                 error "(6) Expect 1 orphan has been fixed, but got: $repaired"
2179
2180         echo "There should be stub file under .lustre/lost+found/MDT0000/"
2181         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
2182                 error "(7) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
2183
2184         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-C-*)
2185         [ ! -z "$cname" ] ||
2186                 error "(8) .lustre/lost+found/MDT0000/ should not be empty"
2187
2188         echo "The stub file should keep the original f2 data"
2189         cur_size=$(ls -il $cname | awk '{ print $6 }')
2190         [ "$cur_size" == "$saved_size" ] ||
2191                 error "(9) Expect file2 size $saved_size, but got $cur_size"
2192
2193         cat $cname
2194         $LFS path2fid $cname
2195         $LFS getstripe $cname
2196
2197         echo "The f2 should contains new data."
2198         cat $DIR/$tdir/a1/f2
2199         $LFS path2fid $DIR/$tdir/a1/f2
2200         $LFS getstripe $DIR/$tdir/a1/f2
2201 }
2202 run_test 18e "Find out orphan OST-object and repair it (5)"
2203
2204 test_18f() {
2205         [ $OSTCOUNT -lt 2 ] &&
2206                 skip "The test needs at least 2 OSTs" && return
2207
2208         echo "#####"
2209         echo "The target MDT-object is lost. The LFSCK should re-create the"
2210         echo "MDT-object under .lustre/lost+found/MDTxxxx. If some OST fail"
2211         echo "to verify some OST-object(s) during the first stage-scanning,"
2212         echo "the LFSCK should skip orphan OST-objects for such OST. Others"
2213         echo "should not be affected."
2214         echo "#####"
2215
2216         check_mount_and_prep
2217         $LFS mkdir -i 0 $DIR/$tdir/a1
2218         $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a1
2219         dd if=/dev/zero of=$DIR/$tdir/a1/guard bs=1M count=2
2220         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
2221         $LFS mkdir -i 0 $DIR/$tdir/a2
2222         $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a2
2223         dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
2224         $LFS getstripe $DIR/$tdir/a1/f1
2225         $LFS getstripe $DIR/$tdir/a2/f2
2226
2227         if [ $MDSCOUNT -ge 2 ]; then
2228                 $LFS mkdir -i 1 $DIR/$tdir/a3
2229                 $LFS setstripe -c 1 -i 0 -S 1M $DIR/$tdir/a3
2230                 dd if=/dev/zero of=$DIR/$tdir/a3/guard bs=1M count=2
2231                 dd if=/dev/zero of=$DIR/$tdir/a3/f3 bs=1M count=2
2232                 $LFS mkdir -i 1 $DIR/$tdir/a4
2233                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a4
2234                 dd if=/dev/zero of=$DIR/$tdir/a4/f4 bs=1M count=2
2235                 $LFS getstripe $DIR/$tdir/a3/f3
2236                 $LFS getstripe $DIR/$tdir/a4/f4
2237         fi
2238
2239         cancel_lru_locks osc
2240
2241         echo "Inject failure, to simulate the case of missing the MDT-object"
2242         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2243         do_facet mds1 $LCTL set_param fail_loc=0x1616
2244         rm -f $DIR/$tdir/a1/f1
2245         rm -f $DIR/$tdir/a2/f2
2246
2247         if [ $MDSCOUNT -ge 2 ]; then
2248                 do_facet mds2 $LCTL set_param fail_loc=0x1616
2249                 rm -f $DIR/$tdir/a3/f3
2250                 rm -f $DIR/$tdir/a4/f4
2251         fi
2252
2253         sync
2254         sleep 2
2255
2256         do_facet mds1 $LCTL set_param fail_loc=0
2257         if [ $MDSCOUNT -ge 2 ]; then
2258                 do_facet mds2 $LCTL set_param fail_loc=0
2259         fi
2260
2261         cancel_lru_locks mdc
2262         cancel_lru_locks osc
2263
2264         echo "Inject failure, to simulate the OST0 fail to handle"
2265         echo "MDT0 LFSCK request during the first-stage scanning."
2266         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
2267         do_facet mds1 $LCTL set_param fail_loc=0x161c fail_val=0
2268
2269         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2270         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2271
2272         for k in $(seq $MDSCOUNT); do
2273                 # The LFSCK status query internal is 30 seconds. For the case
2274                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2275                 # time to guarantee the status sync up.
2276                 wait_update_facet mds${k} "$LCTL get_param -n \
2277                         mdd.$(facet_svc mds${k}).lfsck_layout |
2278                         awk '/^status/ { print \\\$2 }'" "partial" $LTIME ||
2279                         error "(2) MDS${k} is not the expected 'partial'"
2280         done
2281
2282         wait_update_facet ost1 "$LCTL get_param -n \
2283                 obdfilter.$(facet_svc ost1).lfsck_layout |
2284                 awk '/^status/ { print \\\$2 }'" "partial" $LTIME || {
2285                 error "(3) OST1 is not the expected 'partial'"
2286         }
2287
2288         wait_update_facet ost2 "$LCTL get_param -n \
2289                 obdfilter.$(facet_svc ost2).lfsck_layout |
2290                 awk '/^status/ { print \\\$2 }'" "completed" $LTIME || {
2291                 error "(4) OST2 is not the expected 'completed'"
2292         }
2293
2294         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2295
2296         local repaired=$(do_facet mds1 $LCTL get_param -n \
2297                          mdd.$(facet_svc mds1).lfsck_layout |
2298                          awk '/^repaired_orphan/ { print $2 }')
2299         [ $repaired -eq 1 ] ||
2300                 error "(5) Expect 1 fixed on mds{1}, but got: $repaired"
2301
2302         if [ $MDSCOUNT -ge 2 ]; then
2303                 repaired=$(do_facet mds2 $LCTL get_param -n \
2304                          mdd.$(facet_svc mds2).lfsck_layout |
2305                          awk '/^repaired_orphan/ { print $2 }')
2306                 [ $repaired -eq 1 ] ||
2307                 error "(6) Expect 1 fixed on mds{2}, but got: $repaired"
2308         fi
2309
2310         echo "Trigger layout LFSCK on all devices again to cleanup"
2311         $START_LAYOUT -r -o || error "(7) Fail to start LFSCK for layout!"
2312
2313         for k in $(seq $MDSCOUNT); do
2314                 # The LFSCK status query internal is 30 seconds. For the case
2315                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2316                 # time to guarantee the status sync up.
2317                 wait_update_facet mds${k} "$LCTL get_param -n \
2318                         mdd.$(facet_svc mds${k}).lfsck_layout |
2319                         awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
2320                         error "(8) MDS${k} is not the expected 'completed'"
2321         done
2322
2323         for k in $(seq $OSTCOUNT); do
2324                 cur_status=$(do_facet ost${k} $LCTL get_param -n \
2325                              obdfilter.$(facet_svc ost${k}).lfsck_layout |
2326                              awk '/^status/ { print $2 }')
2327                 [ "$cur_status" == "completed" ] ||
2328                 error "(9) OST${k} Expect 'completed', but got '$cur_status'"
2329
2330         done
2331
2332         local repaired=$(do_facet mds1 $LCTL get_param -n \
2333                          mdd.$(facet_svc mds1).lfsck_layout |
2334                          awk '/^repaired_orphan/ { print $2 }')
2335         [ $repaired -eq 2 ] ||
2336                 error "(10) Expect 2 fixed on mds{1}, but got: $repaired"
2337
2338         if [ $MDSCOUNT -ge 2 ]; then
2339                 repaired=$(do_facet mds2 $LCTL get_param -n \
2340                          mdd.$(facet_svc mds2).lfsck_layout |
2341                          awk '/^repaired_orphan/ { print $2 }')
2342                 [ $repaired -eq 2 ] ||
2343                 error "(11) Expect 2 fixed on mds{2}, but got: $repaired"
2344         fi
2345 }
2346 run_test 18f "Skip the failed OST(s) when handle orphan OST-objects"
2347
2348 $LCTL set_param debug=-cache > /dev/null
2349
2350 test_19a() {
2351         check_mount_and_prep
2352         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2353
2354         echo "foo" > $DIR/$tdir/a0
2355         echo "guard" > $DIR/$tdir/a1
2356         cancel_lru_locks osc
2357
2358         echo "Inject failure, then client will offer wrong parent FID when read"
2359         do_facet ost1 $LCTL set_param -n \
2360                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2361         #define OBD_FAIL_LFSCK_INVALID_PFID     0x1619
2362         $LCTL set_param fail_loc=0x1619
2363
2364         echo "Read RPC with wrong parent FID should be denied"
2365         cat $DIR/$tdir/a0 && error "(3) Read should be denied!"
2366         $LCTL set_param fail_loc=0
2367 }
2368 run_test 19a "OST-object inconsistency self detect"
2369
2370 test_19b() {
2371         check_mount_and_prep
2372         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2373
2374         echo "Inject failure stub to make the OST-object to back point to"
2375         echo "non-exist MDT-object"
2376
2377         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
2378         do_facet ost1 $LCTL set_param fail_loc=0x1611
2379         echo "foo" > $DIR/$tdir/f0
2380         cancel_lru_locks osc
2381         do_facet ost1 $LCTL set_param fail_loc=0
2382
2383         echo "Nothing should be fixed since self detect and repair is disabled"
2384         local repaired=$(do_facet ost1 $LCTL get_param -n \
2385                         obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2386                         awk '/^repaired/ { print $2 }')
2387         [ $repaired -eq 0 ] ||
2388                 error "(1) Expected 0 repaired, but got $repaired"
2389
2390         echo "Read RPC with right parent FID should be accepted,"
2391         echo "and cause parent FID on OST to be fixed"
2392
2393         do_facet ost1 $LCTL set_param -n \
2394                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2395         cat $DIR/$tdir/f0 || error "(2) Read should not be denied!"
2396
2397         repaired=$(do_facet ost1 $LCTL get_param -n \
2398                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2399                 awk '/^repaired/ { print $2 }')
2400         [ $repaired -eq 1 ] ||
2401                 error "(3) Expected 1 repaired, but got $repaired"
2402 }
2403 run_test 19b "OST-object inconsistency self repair"
2404
2405 test_20() {
2406         [ $OSTCOUNT -lt 2 ] &&
2407                 skip "The test needs at least 2 OSTs" && return
2408
2409         echo "#####"
2410         echo "The target MDT-object and some of its OST-object are lost."
2411         echo "The LFSCK should find out the left OST-objects and re-create"
2412         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
2413         echo "with the partial OST-objects (LOV EA hole)."
2414
2415         echo "New client can access the file with LOV EA hole via normal"
2416         echo "system tools or commands without crash the system."
2417
2418         echo "For old client, even though it cannot access the file with"
2419         echo "LOV EA hole, it should not cause the system crash."
2420         echo "#####"
2421
2422         check_mount_and_prep
2423         $LFS mkdir -i 0 $DIR/$tdir/a1
2424         if [ $OSTCOUNT -gt 2 ]; then
2425                 $LFS setstripe -c 3 -i 0 -S 1M $DIR/$tdir/a1
2426                 bcount=513
2427         else
2428                 $LFS setstripe -c 2 -i 0 -S 1M $DIR/$tdir/a1
2429                 bcount=257
2430         fi
2431
2432         # 256 blocks on the stripe0.
2433         # 1 block on the stripe1 for 2 OSTs case.
2434         # 256 blocks on the stripe1 for other cases.
2435         # 1 block on the stripe2 if OSTs > 2
2436         dd if=/dev/zero of=$DIR/$tdir/a1/f0 bs=4096 count=$bcount
2437         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=4096 count=$bcount
2438         dd if=/dev/zero of=$DIR/$tdir/a1/f2 bs=4096 count=$bcount
2439
2440         local fid0=$($LFS path2fid $DIR/$tdir/a1/f0)
2441         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2442         local fid2=$($LFS path2fid $DIR/$tdir/a1/f2)
2443
2444         echo ${fid0}
2445         $LFS getstripe $DIR/$tdir/a1/f0
2446         echo ${fid1}
2447         $LFS getstripe $DIR/$tdir/a1/f1
2448         echo ${fid2}
2449         $LFS getstripe $DIR/$tdir/a1/f2
2450
2451         if [ $OSTCOUNT -gt 2 ]; then
2452                 dd if=/dev/zero of=$DIR/$tdir/a1/f3 bs=4096 count=$bcount
2453                 fid3=$($LFS path2fid $DIR/$tdir/a1/f3)
2454                 echo ${fid3}
2455                 $LFS getstripe $DIR/$tdir/a1/f3
2456         fi
2457
2458         cancel_lru_locks osc
2459
2460         echo "Inject failure..."
2461         echo "To simulate f0 lost MDT-object"
2462         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2463         do_facet mds1 $LCTL set_param fail_loc=0x1616
2464         rm -f $DIR/$tdir/a1/f0
2465
2466         echo "To simulate f1 lost MDT-object and OST-object0"
2467         #define OBD_FAIL_LFSCK_LOST_SPEOBJ      0x161a
2468         do_facet mds1 $LCTL set_param fail_loc=0x161a
2469         rm -f $DIR/$tdir/a1/f1
2470
2471         echo "To simulate f2 lost MDT-object and OST-object1"
2472         do_facet mds1 $LCTL set_param fail_val=1
2473         rm -f $DIR/$tdir/a1/f2
2474
2475         if [ $OSTCOUNT -gt 2 ]; then
2476                 echo "To simulate f3 lost MDT-object and OST-object2"
2477                 do_facet mds1 $LCTL set_param fail_val=2
2478                 rm -f $DIR/$tdir/a1/f3
2479         fi
2480
2481         umount_client $MOUNT
2482         sync
2483         sleep 2
2484         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2485
2486         echo "Inject failure to slow down the LFSCK on OST0"
2487         #define OBD_FAIL_LFSCK_DELAY5           0x161b
2488         do_facet ost1 $LCTL set_param fail_loc=0x161b
2489
2490         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2491         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2492
2493         sleep 3
2494         do_facet ost1 $LCTL set_param fail_loc=0
2495
2496         for k in $(seq $MDSCOUNT); do
2497                 # The LFSCK status query internal is 30 seconds. For the case
2498                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2499                 # time to guarantee the status sync up.
2500                 wait_update_facet mds${k} "$LCTL get_param -n \
2501                         mdd.$(facet_svc mds${k}).lfsck_layout |
2502                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
2503                         error "(2) MDS${k} is not the expected 'completed'"
2504         done
2505
2506         for k in $(seq $OSTCOUNT); do
2507                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2508                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2509                                 awk '/^status/ { print $2 }')
2510                 [ "$cur_status" == "completed" ] ||
2511                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2512         done
2513
2514         local repaired=$(do_facet mds1 $LCTL get_param -n \
2515                          mdd.$(facet_svc mds1).lfsck_layout |
2516                          awk '/^repaired_orphan/ { print $2 }')
2517         if [ $OSTCOUNT -gt 2 ]; then
2518                 [ $repaired -eq 9 ] ||
2519                         error "(4.1) Expect 9 fixed on mds1, but got: $repaired"
2520         else
2521                 [ $repaired -eq 4 ] ||
2522                         error "(4.2) Expect 4 fixed on mds1, but got: $repaired"
2523         fi
2524
2525         mount_client $MOUNT || error "(5.0) Fail to start client!"
2526
2527         LOV_PATTERN_F_HOLE=0x40000000
2528
2529         #
2530         # ${fid0}-R-0 is the old f0
2531         #
2532         local name="$MOUNT/.lustre/lost+found/MDT0000/${fid0}-R-0"
2533         echo "Check $name, which is the old f0"
2534
2535         $LFS getstripe -v $name || error "(5.1) cannot getstripe on $name"
2536
2537         local pattern=0x$($LFS getstripe -L $name)
2538         [[ $((pattern & LOV_PATTERN_F_HOLE)) -eq 0 ]] ||
2539                 error "(5.2) NOT expect pattern flag hole, but got $pattern"
2540
2541         local stripes=$($LFS getstripe -c $name)
2542         if [ $OSTCOUNT -gt 2 ]; then
2543                 [ $stripes -eq 3 ] ||
2544                 error "(5.3.1) expect the stripe count is 3, but got $stripes"
2545         else
2546                 [ $stripes -eq 2 ] ||
2547                 error "(5.3.2) expect the stripe count is 2, but got $stripes"
2548         fi
2549
2550         local size=$(stat $name | awk '/Size:/ { print $2 }')
2551         [ $size -eq $((4096 * $bcount)) ] ||
2552                 error "(5.4) expect the size $((4096 * $bcount)), but got $size"
2553
2554         cat $name > /dev/null || error "(5.5) cannot read $name"
2555
2556         echo "dummy" >> $name || error "(5.6) cannot write $name"
2557
2558         chown $RUNAS_ID:$RUNAS_GID $name || error "(5.7) cannot chown on $name"
2559
2560         touch $name || error "(5.8) cannot touch $name"
2561
2562         rm -f $name || error "(5.9) cannot unlink $name"
2563
2564         #
2565         # ${fid1}-R-0 contains the old f1's stripe1 (and stripe2 if OSTs > 2)
2566         #
2567         name="$MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2568         if [ $OSTCOUNT -gt 2 ]; then
2569                 echo "Check $name, it contains the old f1's stripe1 and stripe2"
2570         else
2571                 echo "Check $name, it contains the old f1's stripe1"
2572         fi
2573
2574         $LFS getstripe -v $name || error "(6.1) cannot getstripe on $name"
2575
2576         pattern=0x$($LFS getstripe -L $name)
2577         [[ $((pattern & LOV_PATTERN_F_HOLE)) -ne 0 ]] ||
2578                 error "(6.2) expect pattern flag hole, but got $pattern"
2579
2580         stripes=$($LFS getstripe -c $name)
2581         if [ $OSTCOUNT -gt 2 ]; then
2582                 [ $stripes -eq 3 ] ||
2583                 error "(6.3.1) expect the stripe count is 3, but got $stripes"
2584         else
2585                 [ $stripes -eq 2 ] ||
2586                 error "(6.3.2) expect the stripe count is 2, but got $stripes"
2587         fi
2588
2589         size=$(stat $name | awk '/Size:/ { print $2 }')
2590         [ $size -eq $((4096 * $bcount)) ] ||
2591                 error "(6.4) expect the size $((4096 * $bcount)), but got $size"
2592
2593         cat $name > /dev/null && error "(6.5) normal read $name should fail"
2594
2595         local failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
2596                          bs=4096 2>&1 | grep "Input/output error" | wc -l)
2597
2598         # stripe0 is dummy
2599         [ $failures -eq 256 ] ||
2600                 error "(6.6) expect 256 IO failures, but get $failures"
2601
2602         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
2603         [ $size -eq $((4096 * $bcount)) ] ||
2604                 error "(6.7) expect the size $((4096 * $bcount)), but got $size"
2605
2606         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 &&
2607                 error "(6.8) write to the LOV EA hole should fail"
2608
2609         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 seek=300 ||
2610                 error "(6.9) write to normal stripe should NOT fail"
2611
2612         echo "foo" >> $name && error "(6.10) append write $name should fail"
2613
2614         chown $RUNAS_ID:$RUNAS_GID $name || error "(6.11) cannot chown on $name"
2615
2616         touch $name || error "(6.12) cannot touch $name"
2617
2618         rm -f $name || error "(6.13) cannot unlink $name"
2619
2620         #
2621         # ${fid2}-R-0 it contains the old f2's stripe0 (and stripe2 if OSTs > 2)
2622         #
2623         name="$MOUNT/.lustre/lost+found/MDT0000/${fid2}-R-0"
2624         if [ $OSTCOUNT -gt 2 ]; then
2625                 echo "Check $name, it contains the old f2's stripe0 and stripe2"
2626         else
2627                 echo "Check $name, it contains the old f2's stripe0"
2628         fi
2629
2630         $LFS getstripe -v $name || error "(7.1) cannot getstripe on $name"
2631
2632         pattern=0x$($LFS getstripe -L $name)
2633         stripes=$($LFS getstripe -c $name)
2634         size=$(stat $name | awk '/Size:/ { print $2 }')
2635         if [ $OSTCOUNT -gt 2 ]; then
2636                 [[ $((pattern & LOV_PATTERN_F_HOLE)) -ne 0 ]] ||
2637                 error "(7.2.1) expect pattern flag hole, but got $pattern"
2638
2639                 [ $stripes -eq 3 ] ||
2640                 error "(7.3.1) expect the stripe count is 3, but got $stripes"
2641
2642                 [ $size -eq $((4096 * $bcount)) ] ||
2643                 error "(7.4.1) expect size $((4096 * $bcount)), but got $size"
2644
2645                 cat $name > /dev/null &&
2646                         error "(7.5.1) normal read $name should fail"
2647
2648                 failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
2649                            bs=4096 2>&1 | grep "Input/output error" | wc -l)
2650                 # stripe1 is dummy
2651                 [ $failures -eq 256 ] ||
2652                         error "(7.6) expect 256 IO failures, but get $failures"
2653
2654                 size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
2655                 [ $size -eq $((4096 * $bcount)) ] ||
2656                 error "(7.7) expect the size $((4096 * $bcount)), but got $size"
2657
2658                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
2659                 seek=300 && error "(7.8.0) write to the LOV EA hole should fail"
2660
2661                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 ||
2662                 error "(7.8.1) write to normal stripe should NOT fail"
2663
2664                 echo "foo" >> $name &&
2665                         error "(7.8.3) append write $name should fail"
2666
2667                 chown $RUNAS_ID:$RUNAS_GID $name ||
2668                         error "(7.9.1) cannot chown on $name"
2669
2670                 touch $name || error "(7.10.1) cannot touch $name"
2671         else
2672                 [[ $((pattern & LOV_PATTERN_F_HOLE)) -eq 0 ]] ||
2673                 error "(7.2.2) NOT expect pattern flag hole, but got $pattern"
2674
2675                 [ $stripes -eq 1 ] ||
2676                 error "(7.3.2) expect the stripe count is 1, but got $stripes"
2677
2678                 # stripe1 is dummy
2679                 [ $size -eq $((4096 * (256 + 0))) ] ||
2680                 error "(7.4.2) expect the size $((4096 * 256)), but got $size"
2681
2682                 cat $name > /dev/null || error "(7.5.2) cannot read $name"
2683
2684                 echo "dummy" >> $name || error "(7.8.2) cannot write $name"
2685
2686                 chown $RUNAS_ID:$RUNAS_GID $name ||
2687                         error "(7.9.2) cannot chown on $name"
2688
2689                 touch $name || error "(7.10.2) cannot touch $name"
2690         fi
2691
2692         rm -f $name || error "(7.11) cannot unlink $name"
2693
2694         [ $OSTCOUNT -le 2 ] && return
2695
2696         #
2697         # ${fid3}-R-0 should contains the old f3's stripe0 and stripe1
2698         #
2699         name="$MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
2700         echo "Check $name, which contains the old f3's stripe0 and stripe1"
2701
2702         $LFS getstripe -v $name || error "(8.1) cannot getstripe on $name"
2703
2704         pattern=0x$($LFS getstripe -L $name)
2705         [[ $((pattern & LOV_PATTERN_F_HOLE)) -eq 0 ]] ||
2706                 error "(8.2) NOT expect pattern flag hole, but got $pattern"
2707
2708         stripes=$($LFS getstripe -c $name)
2709         # LFSCK does not know the old f3 had 3 stripes.
2710         # It only tries to find as much as possible.
2711         # The stripe count depends on the last stripe's offset.
2712         [ $stripes -eq 2 ] ||
2713                 error "(8.3) expect the stripe count is 2, but got $stripes"
2714
2715         size=$(stat $name | awk '/Size:/ { print $2 }')
2716         # stripe2 is lost
2717         [ $size -eq $((4096 * (256 + 256 + 0))) ] ||
2718                 error "(8.4) expect the size $((4096 * 512)), but got $size"
2719
2720         cat $name > /dev/null || error "(8.5) cannot read $name"
2721
2722         echo "dummy" >> $name || error "(8.6) cannot write $name"
2723
2724         chown $RUNAS_ID:$RUNAS_GID $name ||
2725                 error "(8.7) cannot chown on $name"
2726
2727         touch $name || error "(8.8) cannot touch $name"
2728
2729         rm -f $name || error "(8.9) cannot unlink $name"
2730 }
2731 run_test 20 "Handle the orphan with dummy LOV EA slot properly"
2732
2733 test_21() {
2734         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.5.59) ]] &&
2735                 skip "ignore the test if MDS is older than 2.5.59" && return
2736
2737         check_mount_and_prep
2738         createmany -o $DIR/$tdir/f 100 || error "(0) Fail to create 100 files"
2739
2740         echo "Start all LFSCK components by default (-s 1)"
2741         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -s 1 -r ||
2742                 error "Fail to start LFSCK"
2743
2744         echo "namespace LFSCK should be in 'scanning-phase1' status"
2745         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
2746         [ "$STATUS" == "scanning-phase1" ] ||
2747                 error "Expect namespace 'scanning-phase1', but got '$STATUS'"
2748
2749         echo "layout LFSCK should be in 'scanning-phase1' status"
2750         STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
2751         [ "$STATUS" == "scanning-phase1" ] ||
2752                 error "Expect layout 'scanning-phase1', but got '$STATUS'"
2753
2754         echo "Stop all LFSCK components by default"
2755         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 ||
2756                 error "Fail to stop LFSCK"
2757 }
2758 run_test 21 "run all LFSCK components by default"
2759
2760 test_22a() {
2761         [ $MDSCOUNT -lt 2 ] &&
2762                 skip "We need at least 2 MDSes for this test" && return
2763
2764         echo "#####"
2765         echo "The parent_A references the child directory via some name entry,"
2766         echo "but the child directory back references another parent_B via its"
2767         echo "".." name entry. The parent_B does not exist. Then the namesapce"
2768         echo "LFSCK will repair the child directory's ".." name entry."
2769         echo "#####"
2770
2771         check_mount_and_prep
2772
2773         $LFS mkdir -i 1 $DIR/$tdir/guard || error "(1) Fail to mkdir on MDT1"
2774         $LFS mkdir -i 1 $DIR/$tdir/foo || error "(2) Fail to mkdir on MDT1"
2775
2776         echo "Inject failure stub on MDT0 to simulate bad dotdot name entry"
2777         echo "The dummy's dotdot name entry references the guard."
2778         #define OBD_FAIL_LFSCK_BAD_PARENT       0x161e
2779         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161e
2780         $LFS mkdir -i 0 $DIR/$tdir/foo/dummy ||
2781                 error "(3) Fail to mkdir on MDT0"
2782         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2783
2784         rmdir $DIR/$tdir/guard || error "(4) Fail to rmdir $DIR/$tdir/guard"
2785
2786         echo "Trigger namespace LFSCK to repair unmatched pairs"
2787         $START_NAMESPACE -A -r ||
2788                 error "(5) Fail to start LFSCK for namespace"
2789
2790         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2791                 mdd.${MDT_DEV}.lfsck_namespace |
2792                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2793                 $SHOW_NAMESPACE
2794                 error "(6) unexpected status"
2795         }
2796
2797         local repaired=$($SHOW_NAMESPACE |
2798                          awk '/^unmatched_pairs_repaired/ { print $2 }')
2799         [ $repaired -eq 1 ] ||
2800                 error "(7) Fail to repair unmatched pairs: $repaired"
2801
2802         echo "'ls' should success after namespace LFSCK repairing"
2803         ls -ail $DIR/$tdir/foo/dummy > /dev/null ||
2804                 error "(8) ls should success."
2805 }
2806 run_test 22a "LFSCK can repair unmatched pairs (1)"
2807
2808 test_22b() {
2809         [ $MDSCOUNT -lt 2 ] &&
2810                 skip "We need at least 2 MDSes for this test" && return
2811
2812         echo "#####"
2813         echo "The parent_A references the child directory via the name entry_B,"
2814         echo "but the child directory back references another parent_C via its"
2815         echo "".." name entry. The parent_C exists, but there is no the name"
2816         echo "entry_B under the parent_C. Then the namesapce LFSCK will repair"
2817         echo "the child directory's ".." name entry and its linkEA."
2818         echo "#####"
2819
2820         check_mount_and_prep
2821
2822         $LFS mkdir -i 1 $DIR/$tdir/guard || error "(1) Fail to mkdir on MDT1"
2823         $LFS mkdir -i 1 $DIR/$tdir/foo || error "(2) Fail to mkdir on MDT1"
2824
2825         echo "Inject failure stub on MDT0 to simulate bad dotdot name entry"
2826         echo "and bad linkEA. The dummy's dotdot name entry references the"
2827         echo "guard. The dummy's linkEA references n non-exist name entry."
2828         #define OBD_FAIL_LFSCK_BAD_PARENT       0x161e
2829         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161e
2830         $LFS mkdir -i 0 $DIR/$tdir/foo/dummy ||
2831                 error "(3) Fail to mkdir on MDT0"
2832         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2833
2834         local dummyfid=$($LFS path2fid $DIR/$tdir/foo/dummy)
2835         echo "fid2path should NOT work on the dummy's FID $dummyfid"
2836         local dummyname=$($LFS fid2path $DIR $dummyfid)
2837         [ "$dummyname" != "$DIR/$tdir/foo/dummy" ] ||
2838                 error "(4) fid2path works unexpectedly."
2839
2840         echo "Trigger namespace LFSCK to repair unmatched pairs"
2841         $START_NAMESPACE -A -r ||
2842                 error "(5) Fail to start LFSCK for namespace"
2843
2844         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2845                 mdd.${MDT_DEV}.lfsck_namespace |
2846                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2847                 $SHOW_NAMESPACE
2848                 error "(6) unexpected status"
2849         }
2850
2851         local repaired=$($SHOW_NAMESPACE |
2852                          awk '/^unmatched_pairs_repaired/ { print $2 }')
2853         [ $repaired -eq 1 ] ||
2854                 error "(7) Fail to repair unmatched pairs: $repaired"
2855
2856         echo "fid2path should work on the dummy's FID $dummyfid after LFSCK"
2857         local dummyname=$($LFS fid2path $DIR $dummyfid)
2858         [ "$dummyname" == "$DIR/$tdir/foo/dummy" ] ||
2859                 error "(8) fid2path does not work"
2860 }
2861 run_test 22b "LFSCK can repair unmatched pairs (2)"
2862
2863 test_23a() {
2864         [ $MDSCOUNT -lt 2 ] &&
2865                 skip "We need at least 2 MDSes for this test" && return
2866
2867         echo "#####"
2868         echo "The name entry is there, but the MDT-object for such name "
2869         echo "entry does not exist. The namespace LFSCK should find out "
2870         echo "and repair the inconsistency as required."
2871         echo "#####"
2872
2873         check_mount_and_prep
2874
2875         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT0"
2876         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 || error "(2) Fail to mkdir d1 on MDT1"
2877
2878         echo "Inject failure stub on MDT1 to simulate dangling name entry"
2879         #define OBD_FAIL_LFSCK_DANGLING2        0x1620
2880         do_facet mds2 $LCTL set_param fail_loc=0x1620
2881         rmdir $DIR/$tdir/d0/d1 || error "(3) Fail to rmdir d1"
2882         do_facet mds2 $LCTL set_param fail_loc=0
2883
2884         echo "'ls' should fail because of dangling name entry"
2885         ls -ail $DIR/$tdir/d0/d1 > /dev/null 2>&1 && error "(4) ls should fail."
2886
2887         echo "Trigger namespace LFSCK to find out dangling name entry"
2888         $START_NAMESPACE -A -r ||
2889                 error "(5) Fail to start LFSCK for namespace"
2890
2891         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2892                 mdd.${MDT_DEV}.lfsck_namespace |
2893                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2894                 $SHOW_NAMESPACE
2895                 error "(6) unexpected status"
2896         }
2897
2898         local repaired=$($SHOW_NAMESPACE |
2899                          awk '/^dangling_repaired/ { print $2 }')
2900         [ $repaired -eq 1 ] ||
2901                 error "(7) Fail to repair dangling name entry: $repaired"
2902
2903         echo "'ls' should fail because not re-create MDT-object by default"
2904         ls -ail $DIR/$tdir/d0/d1 > /dev/null 2>&1 && error "(8) ls should fail."
2905
2906         echo "Trigger namespace LFSCK again to repair dangling name entry"
2907         $START_NAMESPACE -A -r -C ||
2908                 error "(9) Fail to start LFSCK for namespace"
2909
2910         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2911                 mdd.${MDT_DEV}.lfsck_namespace |
2912                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2913                 $SHOW_NAMESPACE
2914                 error "(10) unexpected status"
2915         }
2916
2917         repaired=$($SHOW_NAMESPACE |
2918                    awk '/^dangling_repaired/ { print $2 }')
2919         [ $repaired -eq 1 ] ||
2920                 error "(11) Fail to repair dangling name entry: $repaired"
2921
2922         echo "'ls' should success after namespace LFSCK repairing"
2923         ls -ail $DIR/$tdir/d0/d1 > /dev/null || error "(12) ls should success."
2924 }
2925 run_test 23a "LFSCK can repair dangling name entry (1)"
2926
2927 test_23b() {
2928         echo "#####"
2929         echo "The objectA has multiple hard links, one of them corresponding"
2930         echo "to the name entry_B. But there is something wrong for the name"
2931         echo "entry_B and cause entry_B to references non-exist object_C."
2932         echo "In the first-stage scanning, the LFSCK will think the entry_B"
2933         echo "as dangling, and re-create the lost object_C. When the LFSCK"
2934         echo "comes to the second-stage scanning, it will find that the"
2935         echo "former re-creating object_C is not proper, and will try to"
2936         echo "replace the object_C with the real object_A."
2937         echo "#####"
2938
2939         check_mount_and_prep
2940
2941         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT0"
2942         echo "dummy" > $DIR/$tdir/d0/f0 || error "(2) Fail to touch on MDT0"
2943         echo "dead" > $DIR/$tdir/d0/f1 || error "(3) Fail to touch on MDT0"
2944
2945         echo "Inject failure stub on MDT0 to simulate dangling name entry"
2946         #define OBD_FAIL_LFSCK_DANGLING3        0x1621
2947         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1621
2948         ln $DIR/$tdir/d0/f0 $DIR/$tdir/d0/foo || error "(4) Fail to hard link"
2949         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
2950
2951         rm -f $DIR/$tdir/d0/f1 || error "(5) Fail to unlink $DIR/$tdir/d0/f1"
2952
2953         echo "'ls' should fail because of dangling name entry"
2954         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 &&
2955                 error "(6) ls should fail."
2956
2957         echo "Trigger namespace LFSCK to find out dangling name entry"
2958         $START_NAMESPACE -r -C ||
2959                 error "(7) Fail to start LFSCK for namespace"
2960
2961         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
2962                 mdd.${MDT_DEV}.lfsck_namespace |
2963                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
2964                 $SHOW_NAMESPACE
2965                 error "(8) unexpected status"
2966         }
2967
2968         local repaired=$($SHOW_NAMESPACE |
2969                          awk '/^dangling_repaired/ { print $2 }')
2970         [ $repaired -eq 1 ] ||
2971                 error "(9) Fail to repair dangling name entry: $repaired"
2972
2973         repaired=$($SHOW_NAMESPACE |
2974                    awk '/^multiple_linked_repaired/ { print $2 }')
2975         [ $repaired -eq 1 ] ||
2976                 error "(10) Fail to drop the former created object: $repaired"
2977
2978         local data=$(cat $DIR/$tdir/d0/foo)
2979         [ "$data" == "dummy" ] ||
2980                 error "(11) The $DIR/$tdir/d0/foo is not recovered: $data"
2981 }
2982 run_test 23b "LFSCK can repair dangling name entry (2)"
2983
2984 test_23c() {
2985         echo "#####"
2986         echo "The objectA has multiple hard links, one of them corresponding"
2987         echo "to the name entry_B. But there is something wrong for the name"
2988         echo "entry_B and cause entry_B to references non-exist object_C."
2989         echo "In the first-stage scanning, the LFSCK will think the entry_B"
2990         echo "as dangling, and re-create the lost object_C. And then others"
2991         echo "modified the re-created object_C. When the LFSCK comes to the"
2992         echo "second-stage scanning, it will find that the former re-creating"
2993         echo "object_C maybe wrong and try to replace the object_C with the"
2994         echo "real object_A. But because object_C has been modified, so the"
2995         echo "LFSCK cannot replace it."
2996         echo "#####"
2997
2998         check_mount_and_prep
2999
3000         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0 on MDT0"
3001         echo "dummy" > $DIR/$tdir/d0/f0 || error "(2) Fail to touch on MDT0"
3002         echo "dead" > $DIR/$tdir/d0/f1 || error "(3) Fail to touch on MDT0"
3003
3004         echo "Inject failure stub on MDT0 to simulate dangling name entry"
3005         #define OBD_FAIL_LFSCK_DANGLING3        0x1621
3006         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1621
3007         ln $DIR/$tdir/d0/f0 $DIR/$tdir/d0/foo || error "(4) Fail to hard link"
3008         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3009
3010         rm -f $DIR/$tdir/d0/f1 || error "(5) Fail to unlink $DIR/$tdir/d0/f1"
3011
3012         echo "'ls' should fail because of dangling name entry"
3013         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 &&
3014                 error "(6) ls should fail."
3015
3016         #define OBD_FAIL_LFSCK_DELAY3           0x1602
3017         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
3018
3019         echo "Trigger namespace LFSCK to find out dangling name entry"
3020         $START_NAMESPACE -r -C ||
3021                 error "(7) Fail to start LFSCK for namespace"
3022
3023         wait_update_facet client "stat $DIR/$tdir/d0/foo |
3024                 awk '/Size/ { print \\\$2 }'" "0" 32 || {
3025                 stat $DIR/$tdir/guard
3026                 $SHOW_NAMESPACE
3027                 error "(8) unexpected size"
3028         }
3029
3030         echo "data" >> $DIR/$tdir/d0/foo || error "(9) Fail to write"
3031         cancel_lru_locks osc
3032
3033         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
3034         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3035                 mdd.${MDT_DEV}.lfsck_namespace |
3036                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3037                 $SHOW_NAMESPACE
3038                 error "(10) unexpected status"
3039         }
3040
3041         local repaired=$($SHOW_NAMESPACE |
3042                          awk '/^dangling_repaired/ { print $2 }')
3043         [ $repaired -eq 1 ] ||
3044                 error "(11) Fail to repair dangling name entry: $repaired"
3045
3046         local data=$(cat $DIR/$tdir/d0/foo)
3047         [ "$data" != "dummy" ] ||
3048                 error "(12) The $DIR/$tdir/d0/foo should not be recovered"
3049 }
3050 run_test 23c "LFSCK can repair dangling name entry (3)"
3051
3052 test_24() {
3053         [ $MDSCOUNT -lt 2 ] &&
3054                 skip "We need at least 2 MDSes for this test" && return
3055
3056         echo "#####"
3057         echo "Two MDT-objects back reference the same name entry via their"
3058         echo "each own linkEA entry, but the name entry only references one"
3059         echo "MDT-object. The namespace LFSCK will remove the linkEA entry"
3060         echo "for the MDT-object that is not recognized. If such MDT-object"
3061         echo "has no other linkEA entry after the removing, then the LFSCK"
3062         echo "will add it as orphan under the .lustre/lost+found/MDTxxxx/."
3063         echo "#####"
3064
3065         check_mount_and_prep
3066
3067         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3068
3069         mkdir $DIR/$tdir/d0/guard || error "(1) Fail to mkdir guard"
3070         $LFS path2fid $DIR/$tdir/d0/guard
3071
3072         mkdir $DIR/$tdir/d0/dummy || error "(2) Fail to mkdir dummy"
3073         $LFS path2fid $DIR/$tdir/d0/dummy
3074
3075         local pfid
3076         if [ $(facet_fstype $SINGLEMDS) != ldiskfs ]; then
3077                 pfid=$($LFS path2fid $DIR/$tdir/d0/guard)
3078         else
3079                 pfid=$($LFS path2fid $DIR/$tdir/d0/dummy)
3080         fi
3081
3082         touch $DIR/$tdir/d0/guard/foo ||
3083                 error "(3) Fail to touch $DIR/$tdir/d0/guard/foo"
3084
3085         echo "Inject failure stub on MDT0 to simulate the case that"
3086         echo "the $DIR/$tdir/d0/dummy/foo has the 'bad' linkEA entry"
3087         echo "that references $DIR/$tdir/d0/guard/foo."
3088         echo "Then remove the name entry $DIR/$tdir/d0/dummy/foo."
3089         echo "So the MDT-object $DIR/$tdir/d0/dummy/foo will be left"
3090         echo "there with the same linkEA entry as another MDT-object"
3091         echo "$DIR/$tdir/d0/guard/foo has"
3092
3093         #define OBD_FAIL_LFSCK_MUL_REF          0x1622
3094         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1622
3095         $LFS mkdir -i 0 $DIR/$tdir/d0/dummy/foo ||
3096                 error "(4) Fail to mkdir $DIR/$tdir/d0/dummy/foo"
3097         $LFS path2fid $DIR/$tdir/d0/dummy/foo
3098         local cfid=$($LFS path2fid $DIR/$tdir/d0/dummy/foo)
3099         rmdir $DIR/$tdir/d0/dummy/foo ||
3100                 error "(5) Fail to remove $DIR/$tdir/d0/dummy/foo name entry"
3101         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3102
3103         echo "stat $DIR/$tdir/d0/dummy/foo should fail"
3104         stat $DIR/$tdir/d0/dummy/foo > /dev/null 2>&1 &&
3105                 error "(6) stat successfully unexpectedly"
3106
3107         echo "Trigger namespace LFSCK to repair multiple-referenced name entry"
3108         $START_NAMESPACE -A -r ||
3109                 error "(7) Fail to start LFSCK for namespace"
3110
3111         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3112                 mdd.${MDT_DEV}.lfsck_namespace |
3113                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3114                 $SHOW_NAMESPACE
3115                 error "(8) unexpected status"
3116         }
3117
3118         local repaired=$($SHOW_NAMESPACE |
3119                          awk '/^multiple_referenced_repaired/ { print $2 }')
3120         [ $repaired -eq 1 ] ||
3121         error "(9) Fail to repair multiple referenced name entry: $repaired"
3122
3123         echo "There should be an orphan under .lustre/lost+found/MDT0000/"
3124         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
3125                 error "(10) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
3126
3127         local cname="$cfid-$pfid-D-0"
3128         ls -ail $MOUNT/.lustre/lost+found/MDT0000/$cname ||
3129                 error "(11) .lustre/lost+found/MDT0000/ should not be empty"
3130 }
3131 run_test 24 "LFSCK can repair multiple-referenced name entry"
3132
3133 test_25() {
3134         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
3135                 skip "Only support to inject failure on ldiskfs" && return
3136
3137         echo "#####"
3138         echo "The file type in the name entry does not match the file type"
3139         echo "claimed by the referenced object. Then the LFSCK will update"
3140         echo "the file type in the name entry."
3141         echo "#####"
3142
3143         check_mount_and_prep
3144
3145         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3146
3147         echo "Inject failure stub on MDT0 to simulate the case that"
3148         echo "the file type stored in the name entry is wrong."
3149
3150         #define OBD_FAIL_LFSCK_BAD_TYPE         0x1623
3151         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1623
3152         touch $DIR/$tdir/d0/foo || error "(2) Fail to touch $DIR/$tdir/d0/foo"
3153         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3154
3155         echo "Trigger namespace LFSCK to repair bad file type in the name entry"
3156         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace"
3157
3158         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3159                 mdd.${MDT_DEV}.lfsck_namespace |
3160                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3161                 $SHOW_NAMESPACE
3162                 error "(4) unexpected status"
3163         }
3164
3165         local repaired=$($SHOW_NAMESPACE |
3166                          awk '/^bad_file_type_repaired/ { print $2 }')
3167         [ $repaired -eq 1 ] ||
3168         error "(5) Fail to repair bad file type in name entry: $repaired"
3169
3170         ls -ail $DIR/$tdir/d0 || error "(6) Fail to 'ls' the $DIR/$tdir/d0"
3171 }
3172 run_test 25 "LFSCK can repair bad file type in the name entry"
3173
3174 test_26a() {
3175         echo "#####"
3176         echo "The local name entry back referenced by the MDT-object is lost."
3177         echo "The namespace LFSCK will add the missing local name entry back"
3178         echo "to the normal namespace."
3179         echo "#####"
3180
3181         check_mount_and_prep
3182
3183         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3184         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
3185         local foofid=$($LFS path2fid $DIR/$tdir/d0/foo)
3186
3187         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/dummy ||
3188                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
3189
3190         echo "Inject failure stub on MDT0 to simulate the case that"
3191         echo "foo's name entry will be removed, but the foo's object"
3192         echo "and its linkEA are kept in the system."
3193
3194         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
3195         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
3196         rm -f $DIR/$tdir/d0/foo || error "(4) Fail to unlink $DIR/$tdir/d0/foo"
3197         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3198
3199         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 && "(5) 'ls' should fail"
3200
3201         echo "Trigger namespace LFSCK to repair the missing remote name entry"
3202         $START_NAMESPACE -r -A ||
3203                 error "(6) Fail to start LFSCK for namespace"
3204
3205         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3206                 mdd.${MDT_DEV}.lfsck_namespace |
3207                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3208                 $SHOW_NAMESPACE
3209                 error "(7) unexpected status"
3210         }
3211
3212         local repaired=$($SHOW_NAMESPACE |
3213                          awk '/^lost_dirent_repaired/ { print $2 }')
3214         [ $repaired -eq 1 ] ||
3215                 error "(8) Fail to repair lost dirent: $repaired"
3216
3217         ls -ail $DIR/$tdir/d0/foo ||
3218                 error "(9) Fail to 'ls' $DIR/$tdir/d0/foo"
3219
3220         local foofid2=$($LFS path2fid $DIR/$tdir/d0/foo)
3221         [ "$foofid" == "$foofid2" ] ||
3222                 error "(10) foo's FID changed: $foofid, $foofid2"
3223 }
3224 run_test 26a "LFSCK can add the missing local name entry back to the namespace"
3225
3226 test_26b() {
3227         [ $MDSCOUNT -lt 2 ] &&
3228                 skip "We need at least 2 MDSes for this test" && return
3229
3230         echo "#####"
3231         echo "The remote name entry back referenced by the MDT-object is lost."
3232         echo "The namespace LFSCK will add the missing remote name entry back"
3233         echo "to the normal namespace."
3234         echo "#####"
3235
3236         check_mount_and_prep
3237
3238         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3239         $LFS mkdir -i 0 $DIR/$tdir/d0/foo || error "(2) Fail to mkdir foo"
3240         local foofid=$($LFS path2fid $DIR/$tdir/d0/foo)
3241
3242         echo "Inject failure stub on MDT0 to simulate the case that"
3243         echo "foo's name entry will be removed, but the foo's object"
3244         echo "and its linkEA are kept in the system."
3245
3246         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
3247         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
3248         rmdir $DIR/$tdir/d0/foo || error "(3) Fail to rmdir $DIR/$tdir/d0/foo"
3249         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3250
3251         ls -ail $DIR/$tdir/d0/foo > /dev/null 2>&1 && "(4) 'ls' should fail"
3252
3253         echo "Trigger namespace LFSCK to repair the missing remote name entry"
3254         $START_NAMESPACE -r -A ||
3255                 error "(5) Fail to start LFSCK for namespace"
3256
3257         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3258                 mdd.${MDT_DEV}.lfsck_namespace |
3259                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3260                 $SHOW_NAMESPACE
3261                 error "(6) unexpected status"
3262         }
3263
3264         local repaired=$($SHOW_NAMESPACE |
3265                          awk '/^lost_dirent_repaired/ { print $2 }')
3266         [ $repaired -eq 1 ] ||
3267                 error "(7) Fail to repair lost dirent: $repaired"
3268
3269         ls -ail $DIR/$tdir/d0/foo ||
3270                 error "(8) Fail to 'ls' $DIR/$tdir/d0/foo"
3271
3272         local foofid2=$($LFS path2fid $DIR/$tdir/d0/foo)
3273         [ "$foofid" == "$foofid2" ] ||
3274                 error "(9) foo's FID changed: $foofid, $foofid2"
3275 }
3276 run_test 26b "LFSCK can add the missing remote name entry back to the namespace"
3277
3278 test_27a() {
3279         echo "#####"
3280         echo "The local parent referenced by the MDT-object linkEA is lost."
3281         echo "The namespace LFSCK will re-create the lost parent as orphan."
3282         echo "#####"
3283
3284         check_mount_and_prep
3285
3286         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3287         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
3288         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/dummy ||
3289                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
3290
3291         echo "Inject failure stub on MDT0 to simulate the case that"
3292         echo "foo's name entry will be removed, but the foo's object"
3293         echo "and its linkEA are kept in the system. And then remove"
3294         echo "another hard link and the parent directory."
3295
3296         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
3297         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
3298         rm -f $DIR/$tdir/d0/foo ||
3299                 error "(4) Fail to unlink $DIR/$tdir/d0/foo"
3300         rm -f $DIR/$tdir/d0/dummy ||
3301                 error "(5) Fail to unlink $DIR/$tdir/d0/dummy"
3302         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3303
3304         rm -rf $DIR/$tdir/d0 || error "(5) Fail to unlink the dir d0"
3305         ls -ail $DIR/$tdir/d0 > /dev/null 2>&1 && "(6) 'ls' should fail"
3306
3307         echo "Trigger namespace LFSCK to repair the lost parent"
3308         $START_NAMESPACE -r -A ||
3309                 error "(6) Fail to start LFSCK for namespace"
3310
3311         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3312                 mdd.${MDT_DEV}.lfsck_namespace |
3313                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3314                 $SHOW_NAMESPACE
3315                 error "(7) unexpected status"
3316         }
3317
3318         local repaired=$($SHOW_NAMESPACE |
3319                          awk '/^lost_dirent_repaired/ { print $2 }')
3320         [ $repaired -eq 1 ] ||
3321                 error "(8) Fail to repair lost dirent: $repaired"
3322
3323         echo "There should be an orphan under .lustre/lost+found/MDT0000/"
3324         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
3325                 error "(9) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
3326
3327         ls -ail $MOUNT/.lustre/lost+found/MDT0000/
3328
3329         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-P-*)
3330         [ ! -z "$cname" ] ||
3331                 error "(10) .lustre/lost+found/MDT0000/ should not be empty"
3332 }
3333 run_test 27a "LFSCK can recreate the lost local parent directory as orphan"
3334
3335 test_27b() {
3336         [ $MDSCOUNT -lt 2 ] &&
3337                 skip "We need at least 2 MDSes for this test" && return
3338
3339         echo "#####"
3340         echo "The remote parent referenced by the MDT-object linkEA is lost."
3341         echo "The namespace LFSCK will re-create the lost parent as orphan."
3342         echo "#####"
3343
3344         check_mount_and_prep
3345
3346         $LFS mkdir -i 1 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3347         $LFS mkdir -i 0 $DIR/$tdir/d0/foo || error "(2) Fail to mkdir foo"
3348
3349         $LFS path2fid $DIR/$tdir/d0
3350
3351         echo "Inject failure stub on MDT0 to simulate the case that"
3352         echo "foo's name entry will be removed, but the foo's object"
3353         echo "and its linkEA are kept in the system. And then remove"
3354         echo "the parent directory."
3355
3356         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
3357         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
3358         rmdir $DIR/$tdir/d0/foo || error "(3) Fail to rmdir $DIR/$tdir/d0/foo"
3359         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3360
3361         rmdir $DIR/$tdir/d0 || error "(4) Fail to unlink the dir d0"
3362         ls -ail $DIR/$tdir/d0 > /dev/null 2>&1 && "(5) 'ls' should fail"
3363
3364         echo "Trigger namespace LFSCK to repair the missing remote name entry"
3365         $START_NAMESPACE -r -A ||
3366                 error "(6) Fail to start LFSCK for namespace"
3367
3368         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3369                 mdd.${MDT_DEV}.lfsck_namespace |
3370                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3371                 $SHOW_NAMESPACE
3372                 error "(7) unexpected status"
3373         }
3374
3375         local repaired=$($SHOW_NAMESPACE |
3376                          awk '/^lost_dirent_repaired/ { print $2 }')
3377         [ $repaired -eq 1 ] ||
3378                 error "(8) Fail to repair lost dirent: $repaired"
3379
3380         ls -ail $MOUNT/.lustre/lost+found/
3381
3382         echo "There should be an orphan under .lustre/lost+found/MDT0001/"
3383         [ -d $MOUNT/.lustre/lost+found/MDT0001 ] ||
3384                 error "(9) $MOUNT/.lustre/lost+found/MDT0001/ should be there"
3385
3386         ls -ail $MOUNT/.lustre/lost+found/MDT0001/
3387
3388         cname=$(find $MOUNT/.lustre/lost+found/MDT0001/ -name *-P-*)
3389         [ ! -z "$cname" ] ||
3390                 error "(10) .lustre/lost+found/MDT0001/ should not be empty"
3391 }
3392 run_test 27b "LFSCK can recreate the lost remote parent directory as orphan"
3393
3394 test_28() {
3395         [ $MDSCOUNT -lt 2 ] &&
3396                 skip "The test needs at least 2 MDTs" && return
3397
3398         echo "#####"
3399         echo "The target name entry is lost. The LFSCK should insert the"
3400         echo "orphan MDT-object under .lustre/lost+found/MDTxxxx. But if"
3401         echo "the MDT (on which the orphan MDT-object resides) has ever"
3402         echo "failed to respond some name entry verification during the"
3403         echo "first stage-scanning, then the LFSCK should skip to handle"
3404         echo "orphan MDT-object on this MDT. But other MDTs should not"
3405         echo "be affected."
3406         echo "#####"
3407
3408         check_mount_and_prep
3409         $LFS mkdir -i 0 $DIR/$tdir/d1
3410         $LFS mkdir -i 1 $DIR/$tdir/d1/a1
3411         $LFS mkdir -i 1 $DIR/$tdir/d1/a2
3412
3413         $LFS mkdir -i 1 $DIR/$tdir/d2
3414         $LFS mkdir -i 0 $DIR/$tdir/d2/a1
3415         $LFS mkdir -i 0 $DIR/$tdir/d2/a2
3416
3417         echo "Inject failure stub on MDT0 to simulate the case that"
3418         echo "d1/a1's name entry will be removed, but the d1/a1's object"
3419         echo "and its linkEA are kept in the system. And the case that"
3420         echo "d2/a2's name entry will be removed, but the d2/a2's object"
3421         echo "and its linkEA are kept in the system."
3422
3423         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
3424         do_facet mds1 $LCTL set_param fail_loc=0x1624
3425         do_facet mds2 $LCTL set_param fail_loc=0x1624
3426         rmdir $DIR/$tdir/d1/a1 || error "(1) Fail to rmdir $DIR/$tdir/d1/a1"
3427         rmdir $DIR/$tdir/d2/a2 || error "(2) Fail to rmdir $DIR/$tdir/d2/a2"
3428         do_facet mds1 $LCTL set_param fail_loc=0
3429         do_facet mds2 $LCTL set_param fail_loc=0
3430
3431         cancel_lru_locks mdc
3432         cancel_lru_locks osc
3433
3434         echo "Inject failure, to simulate the MDT0 fail to handle"
3435         echo "MDT1 LFSCK request during the first-stage scanning."
3436         #define OBD_FAIL_LFSCK_BAD_NETWORK      0x161c
3437         do_facet mds2 $LCTL set_param fail_loc=0x161c fail_val=0
3438
3439         echo "Trigger namespace LFSCK on all devices to find out orphan object"
3440         $START_NAMESPACE -r -A ||
3441                 error "(3) Fail to start LFSCK for namespace"
3442
3443         wait_update_facet mds1 "$LCTL get_param -n \
3444                 mdd.$(facet_svc mds1).lfsck_namespace |
3445                 awk '/^status/ { print \\\$2 }'" "partial" 32 || {
3446                 error "(4) mds1 is not the expected 'partial'"
3447         }
3448
3449         wait_update_facet mds2 "$LCTL get_param -n \
3450                 mdd.$(facet_svc mds2).lfsck_namespace |
3451                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3452                 error "(5) mds2 is not the expected 'completed'"
3453         }
3454
3455         do_facet mds2 $LCTL set_param fail_loc=0 fail_val=0
3456
3457         local repaired=$(do_facet mds1 $LCTL get_param -n \
3458                          mdd.$(facet_svc mds1).lfsck_namespace |
3459                          awk '/^lost_dirent_repaired/ { print $2 }')
3460         [ $repaired -eq 0 ] ||
3461                 error "(6) Expect 0 fixed on mds1, but got: $repaired"
3462
3463         repaired=$(do_facet mds2 $LCTL get_param -n \
3464                    mdd.$(facet_svc mds2).lfsck_namespace |
3465                    awk '/^lost_dirent_repaired/ { print $2 }')
3466         [ $repaired -eq 1 ] ||
3467                 error "(7) Expect 1 fixed on mds2, but got: $repaired"
3468
3469         echo "Trigger namespace LFSCK on all devices again to cleanup"
3470         $START_NAMESPACE -r -A ||
3471                 error "(8) Fail to start LFSCK for namespace"
3472
3473         for k in $(seq $MDSCOUNT); do
3474                 # The LFSCK status query internal is 30 seconds. For the case
3475                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
3476                 # time to guarantee the status sync up.
3477                 wait_update_facet mds${k} "$LCTL get_param -n \
3478                         mdd.$(facet_svc mds${k}).lfsck_namespace |
3479                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
3480                         error "(9) MDS${k} is not the expected 'completed'"
3481         done
3482
3483         local repaired=$(do_facet mds1 $LCTL get_param -n \
3484                          mdd.$(facet_svc mds1).lfsck_namespace |
3485                          awk '/^lost_dirent_repaired/ { print $2 }')
3486         [ $repaired -eq 1 ] ||
3487                 error "(10) Expect 1 fixed on mds1, but got: $repaired"
3488
3489         repaired=$(do_facet mds2 $LCTL get_param -n \
3490                    mdd.$(facet_svc mds2).lfsck_namespace |
3491                    awk '/^lost_dirent_repaired/ { print $2 }')
3492         [ $repaired -eq 0 ] ||
3493                 error "(11) Expect 0 fixed on mds2, but got: $repaired"
3494 }
3495 run_test 28 "Skip the failed MDT(s) when handle orphan MDT-objects"
3496
3497 test_29a() {
3498         echo "#####"
3499         echo "The object's nlink attribute is larger than the object's known"
3500         echo "name entries count. The LFSCK will repair the object's nlink"
3501         echo "attribute to match the known name entries count"
3502         echo "#####"
3503
3504         check_mount_and_prep
3505
3506         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3507         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
3508
3509         echo "Inject failure stub on MDT0 to simulate the case that foo's"
3510         echo "nlink attribute is larger than its name entries count."
3511
3512         #define OBD_FAIL_LFSCK_MORE_NLINK       0x1625
3513         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1625
3514         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/h1 ||
3515                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
3516         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3517
3518         cancel_lru_locks mdc
3519         local count=$(stat --format=%h $DIR/$tdir/d0/foo)
3520         [ $count -eq 3 ] || error "(4) Cannot inject error: $count"
3521
3522         echo "Trigger namespace LFSCK to repair the nlink count"
3523         $START_NAMESPACE -r -A ||
3524                 error "(5) Fail to start LFSCK for namespace"
3525
3526         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3527                 mdd.${MDT_DEV}.lfsck_namespace |
3528                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3529                 $SHOW_NAMESPACE
3530                 error "(6) unexpected status"
3531         }
3532
3533         local repaired=$($SHOW_NAMESPACE |
3534                          awk '/^nlinks_repaired/ { print $2 }')
3535         [ $repaired -eq 1 ] ||
3536                 error "(7) Fail to repair nlink count: $repaired"
3537
3538         cancel_lru_locks mdc
3539         count=$(stat --format=%h $DIR/$tdir/d0/foo)
3540         [ $count -eq 2 ] || error "(8) Fail to repair nlink count: $count"
3541 }
3542 run_test 29a "LFSCK can repair bad nlink count (1)"
3543
3544 test_29b() {
3545         echo "#####"
3546         echo "The object's nlink attribute is smaller than the object's known"
3547         echo "name entries count. The LFSCK will repair the object's nlink"
3548         echo "attribute to match the known name entries count"
3549         echo "#####"
3550
3551         check_mount_and_prep
3552
3553         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3554         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
3555
3556         echo "Inject failure stub on MDT0 to simulate the case that foo's"
3557         echo "nlink attribute is smaller than its name entries count."
3558
3559         #define OBD_FAIL_LFSCK_LESS_NLINK       0x1626
3560         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1626
3561         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/h1 ||
3562                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
3563         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3564
3565         cancel_lru_locks mdc
3566         local count=$(stat --format=%h $DIR/$tdir/d0/foo)
3567         [ $count -eq 1 ] || error "(4) Cannot inject error: $count"
3568
3569         echo "Trigger namespace LFSCK to repair the nlink count"
3570         $START_NAMESPACE -r -A ||
3571                 error "(5) Fail to start LFSCK for namespace"
3572
3573         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3574                 mdd.${MDT_DEV}.lfsck_namespace |
3575                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3576                 $SHOW_NAMESPACE
3577                 error "(6) unexpected status"
3578         }
3579
3580         local repaired=$($SHOW_NAMESPACE |
3581                          awk '/^nlinks_repaired/ { print $2 }')
3582         [ $repaired -eq 1 ] ||
3583                 error "(7) Fail to repair nlink count: $repaired"
3584
3585         cancel_lru_locks mdc
3586         count=$(stat --format=%h $DIR/$tdir/d0/foo)
3587         [ $count -eq 2 ] || error "(8) Fail to repair nlink count: $count"
3588 }
3589 run_test 29b "LFSCK can repair bad nlink count (2)"
3590
3591 test_29c() {
3592         echo "#####"
3593         echo "There are too much hard links to the object, and exceeds the
3594         echo object's linkEA limitation, as to NOT all the known name entries"
3595         echo "will be recorded in the linkEA. Under such case, LFSCK should"
3596         echo "skip the nlink verification for this object."
3597         echo "#####"
3598
3599         check_mount_and_prep
3600
3601         $LFS mkdir -i 0 $DIR/$tdir/d0 || error "(1) Fail to mkdir d0"
3602         touch $DIR/$tdir/d0/foo || error "(2) Fail to create foo"
3603         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/h1 ||
3604                 error "(3) Fail to hard link to $DIR/$tdir/d0/foo"
3605
3606         echo "Inject failure stub on MDT0 to simulate the case that"
3607         echo "foo's hard links exceed the object's linkEA limitation."
3608
3609         #define OBD_FAIL_LFSCK_LINKEA_OVERFLOW  0x1627
3610         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1627
3611         ln $DIR/$tdir/d0/foo $DIR/$tdir/d0/h2 ||
3612                 error "(4) Fail to hard link to $DIR/$tdir/d0/foo"
3613
3614         cancel_lru_locks mdc
3615
3616         local count1=$(stat --format=%h $DIR/$tdir/d0/foo)
3617         [ $count1 -eq 3 ] || error "(5) Stat failure: $count1"
3618
3619         local foofid=$($LFS path2fid $DIR/$tdir/d0/foo)
3620         $LFS fid2path $DIR $foofid
3621         local count2=$($LFS fid2path $DIR $foofid | wc -l)
3622         [ $count2 -eq 2 ] || "(6) Fail to inject error: $count2"
3623
3624         echo "Trigger namespace LFSCK to repair the nlink count"
3625         $START_NAMESPACE -r -A ||
3626                 error "(7) Fail to start LFSCK for namespace"
3627
3628         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3629                 mdd.${MDT_DEV}.lfsck_namespace |
3630                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3631                 $SHOW_NAMESPACE
3632                 error "(8) unexpected status"
3633         }
3634
3635         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3636         local repaired=$($SHOW_NAMESPACE |
3637                          awk '/^nlinks_repaired/ { print $2 }')
3638         [ $repaired -eq 0 ] ||
3639                 error "(9) Repair nlink count unexpcetedly: $repaired"
3640
3641         cancel_lru_locks mdc
3642
3643         count1=$(stat --format=%h $DIR/$tdir/d0/foo)
3644         [ $count1 -eq 3 ] || error "(10) Stat failure: $count1"
3645
3646         count2=$($LFS fid2path $DIR $foofid | wc -l)
3647         [ $count2 -eq 2 ] ||
3648                 error "(11) Repaired something unexpectedly: $count2"
3649 }
3650 run_test 29c "Not verify nlink attr if hark links exceed linkEA limitation"
3651
3652 test_30() {
3653         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
3654                 skip "Only support backend /lost+found for ldiskfs" && return
3655
3656         echo "#####"
3657         echo "The namespace LFSCK will move the orphans from backend"
3658         echo "/lost+found directory to normal client visible namespace"
3659         echo "or to global visible ./lustre/lost+found/MDTxxxx/ directory"
3660         echo "#####"
3661
3662         check_mount_and_prep
3663
3664         $LFS mkdir -i 0 $DIR/$tdir/foo || error "(1) Fail to mkdir foo"
3665         touch $DIR/$tdir/foo/f0 || error "(2) Fail to touch f1"
3666
3667         echo "Inject failure stub on MDT0 to simulate the case that"
3668         echo "directory d0 has no linkEA entry, then the LFSCK will"
3669         echo "move it into .lustre/lost+found/MDTxxxx/ later."
3670
3671         #define OBD_FAIL_LFSCK_NO_LINKEA        0x161d
3672         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x161d
3673         mkdir $DIR/$tdir/foo/d0 || error "(3) Fail to mkdir d0"
3674         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3675
3676         touch $DIR/$tdir/foo/d0/f1 || error "(4) Fail to touch f1"
3677         mkdir $DIR/$tdir/foo/d0/d1 || error "(5) Fail to mkdir d1"
3678
3679         echo "Inject failure stub on MDT0 to simulate the case that the"
3680         echo "object's name entry will be removed, but not destroy the"
3681         echo "object. Then backend e2fsck will handle it as orphan and"
3682         echo "add them into the backend /lost+found directory."
3683
3684         #define OBD_FAIL_LFSCK_NO_NAMEENTRY     0x1624
3685         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1624
3686         rmdir $DIR/$tdir/foo/d0/d1 || error "(6) Fail to rmdir d1"
3687         rm -f $DIR/$tdir/foo/d0/f1 || error "(7) Fail to unlink f1"
3688         rmdir $DIR/$tdir/foo/d0 || error "(8) Fail to rmdir d0"
3689         rm -f $DIR/$tdir/foo/f0 || error "(9) Fail to unlink f0"
3690         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3691
3692         umount_client $MOUNT || error "(10) Fail to stop client!"
3693
3694         stop $SINGLEMDS || error "(11) Fail to stop MDT0"
3695
3696         echo "run e2fsck"
3697         run_e2fsck $(facet_host $SINGLEMDS) $MDT_DEVNAME "-y" ||
3698                 error "(12) Fail to run e2fsck"
3699
3700         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
3701                 error "(13) Fail to start MDT0"
3702
3703         echo "Trigger namespace LFSCK to recover backend orphans"
3704         $START_NAMESPACE -r -A ||
3705                 error "(14) Fail to start LFSCK for namespace"
3706
3707         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3708                 mdd.${MDT_DEV}.lfsck_namespace |
3709                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3710                 $SHOW_NAMESPACE
3711                 error "(15) unexpected status"
3712         }
3713
3714         local repaired=$($SHOW_NAMESPACE |
3715                          awk '/^local_lost_found_moved/ { print $2 }')
3716         [ $repaired -ge 4 ] ||
3717                 error "(16) Fail to recover backend orphans: $repaired"
3718
3719         mount_client $MOUNT || error "(17) Fail to start client!"
3720
3721         stat $DIR/$tdir/foo/f0 || "(18) f0 is not recovered"
3722
3723         ls -ail $MOUNT/.lustre/lost+found/
3724
3725         echo "d0 should become orphan under .lustre/lost+found/MDT0000/"
3726         [ -d $MOUNT/.lustre/lost+found/MDT0000 ] ||
3727                 error "(19) $MOUNT/.lustre/lost+found/MDT0000/ should be there"
3728
3729         ls -ail $MOUNT/.lustre/lost+found/MDT0000/
3730
3731         cname=$(find $MOUNT/.lustre/lost+found/MDT0000/ -name *-*-D-*)
3732         [ ! -z "$cname" ] || error "(20) d0 is not recovered"
3733
3734         stat ${cname}/d1 || error "(21) d0 is not recovered"
3735         stat ${cname}/f1 || error "(22) f1 is not recovered"
3736 }
3737 run_test 30 "LFSCK can recover the orphans from backend /lost+found"
3738
3739 test_31a() {
3740         [ $MDSCOUNT -lt 2 ] &&
3741                 skip "The test needs at least 2 MDTs" && return
3742
3743         echo "#####"
3744         echo "For the name entry under a striped directory, if the name"
3745         echo "hash does not match the shard, then the LFSCK will repair"
3746         echo "the bad name entry"
3747         echo "#####"
3748
3749         check_mount_and_prep
3750
3751         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
3752                 error "(1) Fail to create striped directory"
3753
3754         echo "Inject failure stub on client to simulate the case that"
3755         echo "some name entry should be inserted into other non-first"
3756         echo "shard, but inserted into the first shard by wrong"
3757
3758         #define OBD_FAIL_LFSCK_BAD_NAME_HASH    0x1628
3759         $LCTL set_param fail_loc=0x1628 fail_val=0
3760         createmany -d $DIR/$tdir/striped_dir/d $MDSCOUNT ||
3761                 error "(2) Fail to create file under striped directory"
3762         $LCTL set_param fail_loc=0 fail_val=0
3763
3764         echo "Trigger namespace LFSCK to repair bad name hash"
3765         $START_NAMESPACE -r -A ||
3766                 error "(3) Fail to start LFSCK for namespace"
3767
3768         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3769                 mdd.${MDT_DEV}.lfsck_namespace |
3770                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3771                 $SHOW_NAMESPACE
3772                 error "(4) unexpected status"
3773         }
3774
3775         local repaired=$($SHOW_NAMESPACE |
3776                          awk '/^name_hash_repaired/ { print $2 }')
3777         [ $repaired -ge 1 ] ||
3778                 error "(5) Fail to repair bad name hash: $repaired"
3779
3780         umount_client $MOUNT || error "(6) umount failed"
3781         mount_client $MOUNT || error "(7) mount failed"
3782
3783         for ((i = 0; i < $MDSCOUNT; i++)); do
3784                 stat $DIR/$tdir/striped_dir/d$i ||
3785                         error "(8) Fail to stat d$i after LFSCK"
3786                 rmdir $DIR/$tdir/striped_dir/d$i ||
3787                         error "(9) Fail to unlink d$i after LFSCK"
3788         done
3789
3790         rmdir $DIR/$tdir/striped_dir ||
3791                 error "(10) Fail to remove the striped directory after LFSCK"
3792 }
3793 run_test 31a "The LFSCK can find/repair the name entry with bad name hash (1)"
3794
3795 test_31b() {
3796         [ $MDSCOUNT -lt 2 ] &&
3797                 skip "The test needs at least 2 MDTs" && return
3798
3799         echo "#####"
3800         echo "For the name entry under a striped directory, if the name"
3801         echo "hash does not match the shard, then the LFSCK will repair"
3802         echo "the bad name entry"
3803         echo "#####"
3804
3805         check_mount_and_prep
3806
3807         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
3808                 error "(1) Fail to create striped directory"
3809
3810         echo "Inject failure stub on client to simulate the case that"
3811         echo "some name entry should be inserted into other non-second"
3812         echo "shard, but inserted into the secod shard by wrong"
3813
3814         #define OBD_FAIL_LFSCK_BAD_NAME_HASH    0x1628
3815         $LCTL set_param fail_loc=0x1628 fail_val=1
3816         createmany -d $DIR/$tdir/striped_dir/d $MDSCOUNT ||
3817                 error "(2) Fail to create file under striped directory"
3818         $LCTL set_param fail_loc=0 fail_val=0
3819
3820         echo "Trigger namespace LFSCK to repair bad name hash"
3821         $START_NAMESPACE -r -A ||
3822                 error "(3) Fail to start LFSCK for namespace"
3823
3824         wait_update_facet mds2 "$LCTL get_param -n \
3825                 mdd.$(facet_svc mds2).lfsck_namespace |
3826                 awk '/^status/ { print \\\$2 }'" "completed" 32 ||
3827                 error "(4) unexpected status"
3828
3829         local repaired=$(do_facet mds2 $LCTL get_param -n \
3830                          mdd.$(facet_svc mds2).lfsck_namespace |
3831                          awk '/^name_hash_repaired/ { print $2 }')
3832         [ $repaired -ge 1 ] ||
3833                 error "(5) Fail to repair bad name hash: $repaired"
3834
3835         umount_client $MOUNT || error "(6) umount failed"
3836         mount_client $MOUNT || error "(7) mount failed"
3837
3838         for ((i = 0; i < $MDSCOUNT; i++)); do
3839                 stat $DIR/$tdir/striped_dir/d$i ||
3840                         error "(8) Fail to stat d$i after LFSCK"
3841                 rmdir $DIR/$tdir/striped_dir/d$i ||
3842                         error "(9) Fail to unlink d$i after LFSCK"
3843         done
3844
3845         rmdir $DIR/$tdir/striped_dir ||
3846                 error "(10) Fail to remove the striped directory after LFSCK"
3847 }
3848 run_test 31b "The LFSCK can find/repair the name entry with bad name hash (2)"
3849
3850 test_31c() {
3851         [ $MDSCOUNT -lt 2 ] &&
3852                 skip "The test needs at least 2 MDTs" && return
3853
3854         echo "#####"
3855         echo "For some reason, the master MDT-object of the striped directory"
3856         echo "may lost its master LMV EA. If nobody created files under the"
3857         echo "master directly after the master LMV EA lost, then the LFSCK"
3858         echo "should re-generate the master LMV EA."
3859         echo "#####"
3860
3861         check_mount_and_prep
3862
3863         echo "Inject failure stub on MDT0 to simulate the case that the"
3864         echo "master MDT-object of the striped directory lost the LMV EA."
3865
3866         #define OBD_FAIL_LFSCK_LOST_MASTER_LMV  0x1629
3867         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1629
3868         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
3869                 error "(1) Fail to create striped directory"
3870         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
3871
3872         echo "Trigger namespace LFSCK to re-generate master LMV EA"
3873         $START_NAMESPACE -r -A ||
3874                 error "(2) Fail to start LFSCK for namespace"
3875
3876         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3877                 mdd.${MDT_DEV}.lfsck_namespace |
3878                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3879                 $SHOW_NAMESPACE
3880                 error "(3) unexpected status"
3881         }
3882
3883         local repaired=$($SHOW_NAMESPACE |
3884                          awk '/^striped_dirs_repaired/ { print $2 }')
3885         [ $repaired -eq 1 ] ||
3886                 error "(4) Fail to re-generate master LMV EA: $repaired"
3887
3888         umount_client $MOUNT || error "(5) umount failed"
3889         mount_client $MOUNT || error "(6) mount failed"
3890
3891         local empty=$(ls $DIR/$tdir/striped_dir/)
3892         [ -z "$empty" ] || error "(7) The master LMV EA is not repaired: $empty"
3893
3894         rmdir $DIR/$tdir/striped_dir ||
3895                 error "(8) Fail to remove the striped directory after LFSCK"
3896 }
3897 run_test 31c "Re-generate the lost master LMV EA for striped directory"
3898
3899 test_31d() {
3900         [ $MDSCOUNT -lt 2 ] &&
3901                 skip "The test needs at least 2 MDTs" && return
3902
3903         echo "#####"
3904         echo "For some reason, the master MDT-object of the striped directory"
3905         echo "may lost its master LMV EA. If somebody created files under the"
3906         echo "master directly after the master LMV EA lost, then the LFSCK"
3907         echo "should NOT re-generate the master LMV EA, instead, it should"
3908         echo "change the broken striped dirctory as read-only to prevent"
3909         echo "further damage"
3910         echo "#####"
3911
3912         check_mount_and_prep
3913
3914         echo "Inject failure stub on MDT0 to simulate the case that the"
3915         echo "master MDT-object of the striped directory lost the LMV EA."
3916
3917         #define OBD_FAIL_LFSCK_LOST_MASTER_LMV  0x1629
3918         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1629
3919         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
3920                 error "(1) Fail to create striped directory"
3921         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0
3922
3923         umount_client $MOUNT || error "(2) umount failed"
3924         mount_client $MOUNT || error "(3) mount failed"
3925
3926         touch $DIR/$tdir/striped_dir/dummy ||
3927                 error "(4) Fail to touch under broken striped directory"
3928
3929         echo "Trigger namespace LFSCK to find out the inconsistency"
3930         $START_NAMESPACE -r -A ||
3931                 error "(5) Fail to start LFSCK for namespace"
3932
3933         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3934                 mdd.${MDT_DEV}.lfsck_namespace |
3935                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3936                 $SHOW_NAMESPACE
3937                 error "(6) unexpected status"
3938         }
3939
3940         local repaired=$($SHOW_NAMESPACE |
3941                          awk '/^striped_dirs_repaired/ { print $2 }')
3942         [ $repaired -eq 0 ] ||
3943                 error "(7) Re-generate master LMV EA unexpected: $repaired"
3944
3945         stat $DIR/$tdir/striped_dir/dummy ||
3946                 error "(8) Fail to stat $DIR/$tdir/striped_dir/dummy"
3947
3948         touch $DIR/$tdir/striped_dir/foo &&
3949                 error "(9) The broken striped directory should be read-only"
3950
3951         chattr -i $DIR/$tdir/striped_dir ||
3952                 error "(10) Fail to chattr on the broken striped directory"
3953
3954         rmdir $DIR/$tdir/striped_dir ||
3955                 error "(11) Fail to remove the striped directory after LFSCK"
3956 }
3957 run_test 31d "Set broken striped directory (modified after broken) as read-only"
3958
3959 test_31e() {
3960         [ $MDSCOUNT -lt 2 ] &&
3961                 skip "The test needs at least 2 MDTs" && return
3962
3963         echo "#####"
3964         echo "For some reason, the slave MDT-object of the striped directory"
3965         echo "may lost its slave LMV EA. The LFSCK should re-generate the"
3966         echo "slave LMV EA."
3967         echo "#####"
3968
3969         check_mount_and_prep
3970
3971         echo "Inject failure stub on MDT0 to simulate the case that the"
3972         echo "slave MDT-object (that resides on the same MDT as the master"
3973         echo "MDT-object resides on) lost the LMV EA."
3974
3975         #define OBD_FAIL_LFSCK_LOST_SLAVE_LMV   0x162a
3976         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162a fail_val=0
3977         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
3978                 error "(1) Fail to create striped directory"
3979         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
3980
3981         echo "Trigger namespace LFSCK to re-generate slave LMV EA"
3982         $START_NAMESPACE -r -A ||
3983                 error "(2) Fail to start LFSCK for namespace"
3984
3985         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
3986                 mdd.${MDT_DEV}.lfsck_namespace |
3987                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
3988                 $SHOW_NAMESPACE
3989                 error "(3) unexpected status"
3990         }
3991
3992         local repaired=$($SHOW_NAMESPACE |
3993                          awk '/^striped_shards_repaired/ { print $2 }')
3994         [ $repaired -eq 1 ] ||
3995                 error "(4) Fail to re-generate slave LMV EA: $repaired"
3996
3997         rmdir $DIR/$tdir/striped_dir ||
3998                 error "(5) Fail to remove the striped directory after LFSCK"
3999 }
4000 run_test 31e "Re-generate the lost slave LMV EA for striped directory (1)"
4001
4002 test_31f() {
4003         [ $MDSCOUNT -lt 2 ] &&
4004                 skip "The test needs at least 2 MDTs" && return
4005
4006         echo "#####"
4007         echo "For some reason, the slave MDT-object of the striped directory"
4008         echo "may lost its slave LMV EA. The LFSCK should re-generate the"
4009         echo "slave LMV EA."
4010         echo "#####"
4011
4012         check_mount_and_prep
4013
4014         echo "Inject failure stub on MDT0 to simulate the case that the"
4015         echo "slave MDT-object (that resides on differnt MDT as the master"
4016         echo "MDT-object resides on) lost the LMV EA."
4017
4018         #define OBD_FAIL_LFSCK_LOST_SLAVE_LMV   0x162a
4019         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162a fail_val=1
4020         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4021                 error "(1) Fail to create striped directory"
4022         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
4023
4024         echo "Trigger namespace LFSCK to re-generate slave LMV EA"
4025         $START_NAMESPACE -r -A ||
4026                 error "(2) Fail to start LFSCK for namespace"
4027
4028         wait_update_facet mds2 "$LCTL get_param -n \
4029                 mdd.$(facet_svc mds2).lfsck_namespace |
4030                 awk '/^status/ { print \\\$2 }'" "completed" 32 ||
4031                 error "(3) unexpected status"
4032
4033         local repaired=$(do_facet mds2 $LCTL get_param -n \
4034                          mdd.$(facet_svc mds2).lfsck_namespace |
4035                          awk '/^striped_shards_repaired/ { print $2 }')
4036         [ $repaired -eq 1 ] ||
4037                 error "(4) Fail to re-generate slave LMV EA: $repaired"
4038
4039         rmdir $DIR/$tdir/striped_dir ||
4040                 error "(5) Fail to remove the striped directory after LFSCK"
4041 }
4042 run_test 31f "Re-generate the lost slave LMV EA for striped directory (2)"
4043
4044 test_31g() {
4045         [ $MDSCOUNT -lt 2 ] &&
4046                 skip "The test needs at least 2 MDTs" && return
4047
4048         echo "#####"
4049         echo "For some reason, the stripe index in the slave LMV EA is"
4050         echo "corrupted. The LFSCK should repair the slave LMV EA."
4051         echo "#####"
4052
4053         check_mount_and_prep
4054
4055         echo "Inject failure stub on MDT0 to simulate the case that the"
4056         echo "slave LMV EA on the first shard of the striped directory"
4057         echo "claims the same index as the second shard claims"
4058
4059         #define OBD_FAIL_LFSCK_BAD_SLAVE_LMV    0x162b
4060         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162b fail_val=0
4061         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4062                 error "(1) Fail to create striped directory"
4063         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
4064
4065         echo "Trigger namespace LFSCK to repair the slave LMV EA"
4066         $START_NAMESPACE -r -A ||
4067                 error "(2) Fail to start LFSCK for namespace"
4068
4069         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
4070                 mdd.${MDT_DEV}.lfsck_namespace |
4071                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
4072                 $SHOW_NAMESPACE
4073                 error "(3) unexpected status"
4074         }
4075
4076         local repaired=$($SHOW_NAMESPACE |
4077                          awk '/^striped_shards_repaired/ { print $2 }')
4078         [ $repaired -eq 1 ] ||
4079                 error "(4) Fail to repair slave LMV EA: $repaired"
4080
4081         umount_client $MOUNT || error "(5) umount failed"
4082         mount_client $MOUNT || error "(6) mount failed"
4083
4084         touch $DIR/$tdir/striped_dir/foo ||
4085                 error "(7) Fail to touch file after the LFSCK"
4086
4087         rm -f $DIR/$tdir/striped_dir/foo ||
4088                 error "(8) Fail to unlink file after the LFSCK"
4089
4090         rmdir $DIR/$tdir/striped_dir ||
4091                 error "(9) Fail to remove the striped directory after LFSCK"
4092 }
4093 run_test 31g "Repair the corrupted slave LMV EA"
4094
4095 test_31h() {
4096         [ $MDSCOUNT -lt 2 ] &&
4097                 skip "The test needs at least 2 MDTs" && return
4098
4099         echo "#####"
4100         echo "For some reason, the shard's name entry in the striped"
4101         echo "directory may be corrupted. The LFSCK should repair the"
4102         echo "bad shard's name entry."
4103         echo "#####"
4104
4105         check_mount_and_prep
4106
4107         echo "Inject failure stub on MDT0 to simulate the case that the"
4108         echo "first shard's name entry in the striped directory claims"
4109         echo "the same index as the second shard's name entry claims."
4110
4111         #define OBD_FAIL_LFSCK_BAD_SLAVE_NAME   0x162c
4112         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162c fail_val=0
4113         $LFS setdirstripe -i 0 -c $MDSCOUNT $DIR/$tdir/striped_dir ||
4114                 error "(1) Fail to create striped directory"
4115         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x0 fail_val=0
4116
4117         echo "Trigger namespace LFSCK to repair the shard's name entry"
4118         $START_NAMESPACE -r -A ||
4119                 error "(2) Fail to start LFSCK for namespace"
4120
4121         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
4122                 mdd.${MDT_DEV}.lfsck_namespace |
4123                 awk '/^status/ { print \\\$2 }'" "completed" 32 || {
4124                 $SHOW_NAMESPACE
4125                 error "(3) unexpected status"
4126         }
4127
4128         local repaired=$($SHOW_NAMESPACE |
4129                          awk '/^dirent_repaired/ { print $2 }')
4130         [ $repaired -eq 1 ] ||
4131                 error "(4) Fail to repair shard's name entry: $repaired"
4132
4133         umount_client $MOUNT || error "(5) umount failed"
4134         mount_client $MOUNT || error "(6) mount failed"
4135
4136         touch $DIR/$tdir/striped_dir/foo ||
4137                 error "(7) Fail to touch file after the LFSCK"
4138
4139         rm -f $DIR/$tdir/striped_dir/foo ||
4140                 error "(8) Fail to unlink file after the LFSCK"
4141
4142         rmdir $DIR/$tdir/striped_dir ||
4143                 error "(9) Fail to remove the striped directory after LFSCK"
4144 }
4145 run_test 31h "Repair the corrupted shard's name entry"
4146
4147 # restore MDS/OST size
4148 MDSSIZE=${SAVED_MDSSIZE}
4149 OSTSIZE=${SAVED_OSTSIZE}
4150 OSTCOUNT=${SAVED_OSTCOUNT}
4151
4152 # cleanup the system at last
4153 formatall
4154
4155 complete $SECONDS
4156 exit_status