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