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 ||