Whamcloud - gitweb
LU-5075 test: keep LFSCK fail_loc until recovery completed
[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 SAVED_MDSSIZE=${MDSSIZE}
23 SAVED_OSTSIZE=${OSTSIZE}
24 SAVED_OSTCOUNT=${OSTCOUNT}
25 # use small MDS + OST size to speed formatting time
26 # do not use too small MDSSIZE/OSTSIZE, which affect the default journal size
27 MDSSIZE=100000
28 OSTSIZE=100000
29 # no need too much OSTs, to reduce the format/start/stop overhead
30 [ $OSTCOUNT -gt 4 ] && OSTCOUNT=4
31
32 # build up a clean test environment.
33 formatall
34 setupall
35
36 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.3.60) ]] &&
37         skip "Need MDS version at least 2.3.60" && check_and_cleanup_lustre &&
38         exit 0
39
40 [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.4.90) ]] &&
41         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 2c"
42
43 [[ $(lustre_version_code ost1) -lt $(version_code 2.5.55) ]] &&
44         ALWAYS_EXCEPT="$ALWAYS_EXCEPT 11 12 13 14 15 16 17 18 19 20 21"
45
46 build_test_filter
47
48 $LCTL set_param debug=+lfsck > /dev/null || true
49
50 MDT_DEV="${FSNAME}-MDT0000"
51 OST_DEV="${FSNAME}-OST0000"
52 MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
53 START_NAMESPACE="do_facet $SINGLEMDS \
54                 $LCTL lfsck_start -M ${MDT_DEV} -t namespace"
55 START_LAYOUT="do_facet $SINGLEMDS \
56                 $LCTL lfsck_start -M ${MDT_DEV} -t layout"
57 START_LAYOUT_ON_OST="do_facet ost1 $LCTL lfsck_start -M ${OST_DEV} -t layout"
58 STOP_LFSCK="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
59 SHOW_NAMESPACE="do_facet $SINGLEMDS \
60                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace"
61 SHOW_LAYOUT="do_facet $SINGLEMDS \
62                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_layout"
63 SHOW_LAYOUT_ON_OST="do_facet ost1 \
64                 $LCTL get_param -n obdfilter.${OST_DEV}.lfsck_layout"
65 MOUNT_OPTS_SCRUB="-o user_xattr"
66 MOUNT_OPTS_NOSCRUB="-o user_xattr,noscrub"
67
68 lfsck_prep() {
69         local ndirs=$1
70         local nfiles=$2
71         local igif=$3
72
73         check_mount_and_prep
74
75         echo "preparing... $nfiles * $ndirs files will be created $(date)."
76         if [ ! -z $igif ]; then
77                 #define OBD_FAIL_FID_IGIF       0x1504
78                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
79         fi
80
81         cp $LUSTRE/tests/*.sh $DIR/$tdir/
82         if [ $ndirs -gt 0 ]; then
83                 createmany -d $DIR/$tdir/d $ndirs
84                 createmany -m $DIR/$tdir/f $ndirs
85                 if [ $nfiles -gt 0 ]; then
86                         for ((i = 0; i < $ndirs; i++)); do
87                                 createmany -m $DIR/$tdir/d${i}/f $nfiles > \
88                                         /dev/null || error "createmany $nfiles"
89                         done
90                 fi
91                 createmany -d $DIR/$tdir/e $ndirs
92         fi
93
94         if [ ! -z $igif ]; then
95                 touch $DIR/$tdir/dummy
96                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0
97         fi
98
99         echo "prepared $(date)."
100 }
101
102 test_0() {
103         lfsck_prep 3 3
104
105         #define OBD_FAIL_LFSCK_DELAY1           0x1600
106         do_facet $SINGLEMDS $LCTL set_param fail_val=3 fail_loc=0x1600
107         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
108
109         $SHOW_NAMESPACE || error "Fail to monitor LFSCK (3)"
110
111         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
112         [ "$STATUS" == "scanning-phase1" ] ||
113                 error "(4) Expect 'scanning-phase1', but got '$STATUS'"
114
115         $STOP_LFSCK || error "(5) Fail to stop LFSCK!"
116
117         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
118         [ "$STATUS" == "stopped" ] ||
119                 error "(6) Expect 'stopped', but got '$STATUS'"
120
121         $START_NAMESPACE || error "(7) Fail to start LFSCK for namespace!"
122
123         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
124         [ "$STATUS" == "scanning-phase1" ] ||
125                 error "(8) Expect 'scanning-phase1', but got '$STATUS'"
126
127         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
128         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
129                 mdd.${MDT_DEV}.lfsck_namespace |
130                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
131                 $SHOW_NAMESPACE
132                 error "(9) unexpected status"
133         }
134
135         local repaired=$($SHOW_NAMESPACE |
136                          awk '/^updated_phase1/ { print $2 }')
137         [ $repaired -eq 0 ] ||
138                 error "(10) Expect nothing to be repaired, but got: $repaired"
139
140         local scanned1=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
141         $START_NAMESPACE -r || error "(11) Fail to reset LFSCK!"
142         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
143                 mdd.${MDT_DEV}.lfsck_namespace |
144                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
145                 $SHOW_NAMESPACE
146                 error "(12) unexpected status"
147         }
148
149         local scanned2=$($SHOW_NAMESPACE | awk '/^success_count/ { print $2 }')
150         [ $((scanned1 + 1)) -eq $scanned2 ] ||
151                 error "(13) Expect success $((scanned1 + 1)), but got $scanned2"
152
153         echo "stopall, should NOT crash LU-3649"
154         stopall || error "(14) Fail to stopall"
155 }
156 run_test 0 "Control LFSCK manually"
157
158 test_1a() {
159         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
160                 skip "OI Scrub not implemented for ZFS" && return
161
162         lfsck_prep 1 1
163
164         #define OBD_FAIL_FID_INDIR      0x1501
165         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1501
166         touch $DIR/$tdir/dummy
167
168         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
169         umount_client $MOUNT
170         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
171         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
172                 mdd.${MDT_DEV}.lfsck_namespace |
173                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
174                 $SHOW_NAMESPACE
175                 error "(4) unexpected status"
176         }
177
178         local repaired=$($SHOW_NAMESPACE |
179                          awk '/^dirent_repaired/ { print $2 }')
180         # for interop with old server
181         [ -z "$repaired" ] &&
182                 repaired=$($SHOW_NAMESPACE |
183                          awk '/^updated_phase1/ { print $2 }')
184
185         [ $repaired -eq 1 ] ||
186                 error "(5) Fail to repair crashed FID-in-dirent: $repaired"
187
188         mount_client $MOUNT || error "(6) Fail to start client!"
189
190         #define OBD_FAIL_FID_LOOKUP     0x1505
191         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
192         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
193
194         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
195 }
196 run_test 1a "LFSCK can find out and repair crashed FID-in-dirent"
197
198 test_1b()
199 {
200         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
201                 skip "OI Scrub not implemented for ZFS" && return
202
203         lfsck_prep 1 1
204
205         #define OBD_FAIL_FID_INLMA      0x1502
206         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1502
207         touch $DIR/$tdir/dummy
208
209         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
210         umount_client $MOUNT
211         #define OBD_FAIL_FID_NOLMA      0x1506
212         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1506
213         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
214         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
215                 mdd.${MDT_DEV}.lfsck_namespace |
216                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
217                 $SHOW_NAMESPACE
218                 error "(4) unexpected status"
219         }
220
221         local repaired=$($SHOW_NAMESPACE |
222                          awk '/^dirent_repaired/ { print $2 }')
223         # for interop with old server
224         [ -z "$repaired" ] &&
225                 repaired=$($SHOW_NAMESPACE |
226                          awk '/^updated_phase1/ { print $2 }')
227
228         [ $repaired -eq 1 ] ||
229                 error "(5) Fail to repair missed FID-in-LMA: $repaired"
230
231         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
232         mount_client $MOUNT || error "(6) Fail to start client!"
233
234         #define OBD_FAIL_FID_LOOKUP     0x1505
235         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
236         stat $DIR/$tdir/dummy > /dev/null || error "(7) no FID-in-LMA."
237
238         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
239 }
240 run_test 1b "LFSCK can find out and repair missed FID-in-LMA"
241
242 test_2a() {
243         lfsck_prep 1 1
244
245         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
246         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
247         touch $DIR/$tdir/dummy
248
249         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
250         umount_client $MOUNT
251         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
252         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
253                 mdd.${MDT_DEV}.lfsck_namespace |
254                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
255                 $SHOW_NAMESPACE
256                 error "(4) unexpected status"
257         }
258
259         local repaired=$($SHOW_NAMESPACE |
260                          awk '/^linkea_repaired/ { print $2 }')
261         # for interop with old server
262         [ -z "$repaired" ] &&
263                 repaired=$($SHOW_NAMESPACE |
264                          awk '/^updated_phase1/ { print $2 }')
265
266         [ $repaired -eq 1 ] ||
267                 error "(5) Fail to repair crashed linkEA: $repaired"
268
269         mount_client $MOUNT || error "(6) Fail to start client!"
270
271         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
272                 error "(7) Fail to stat $DIR/$tdir/dummy"
273
274         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
275         local dummyname=$($LFS fid2path $DIR $dummyfid)
276         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
277                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
278 }
279 run_test 2a "LFSCK can find out and repair crashed linkEA entry"
280
281 test_2b()
282 {
283         lfsck_prep 1 1
284
285         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
286         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
287         touch $DIR/$tdir/dummy
288
289         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
290         umount_client $MOUNT
291         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
292         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
293                 mdd.${MDT_DEV}.lfsck_namespace |
294                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
295                 $SHOW_NAMESPACE
296                 error "(4) unexpected status"
297         }
298
299         local repaired=$($SHOW_NAMESPACE |
300                          awk '/^updated_phase2/ { print $2 }')
301         [ $repaired -eq 1 ] ||
302                 error "(5) Fail to repair crashed linkEA: $repaired"
303
304         mount_client $MOUNT || error "(6) Fail to start client!"
305
306         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
307                 error "(7) Fail to stat $DIR/$tdir/dummy"
308
309         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
310         local dummyname=$($LFS fid2path $DIR $dummyfid)
311         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
312                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
313 }
314 run_test 2b "LFSCK can find out and remove invalid linkEA entry"
315
316 test_2c()
317 {
318         lfsck_prep 1 1
319
320         #define OBD_FAIL_LFSCK_LINKEA_MORE2     0x1605
321         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1605
322         touch $DIR/$tdir/dummy
323
324         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
325         umount_client $MOUNT
326         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
327         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
328                 mdd.${MDT_DEV}.lfsck_namespace |
329                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
330                 $SHOW_NAMESPACE
331                 error "(4) unexpected status"
332         }
333
334         local repaired=$($SHOW_NAMESPACE |
335                          awk '/^updated_phase2/ { print $2 }')
336         [ $repaired -eq 1 ] ||
337                 error "(5) Fail to repair crashed linkEA: $repaired"
338
339         mount_client $MOUNT || error "(6) Fail to start client!"
340
341         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
342                 error "(7) Fail to stat $DIR/$tdir/dummy"
343
344         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
345         local dummyname=$($LFS fid2path $DIR $dummyfid)
346         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
347                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
348 }
349 run_test 2c "LFSCK can find out and remove repeated linkEA entry"
350
351 test_4()
352 {
353         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
354                 skip "OI Scrub not implemented for ZFS" && return
355
356         lfsck_prep 3 3
357         cleanup_mount $MOUNT || error "(0.1) Fail to stop client!"
358         stop $SINGLEMDS > /dev/null || error "(0.2) Fail to stop MDS!"
359
360         mds_backup_restore $SINGLEMDS || error "(1) Fail to backup/restore!"
361         echo "start $SINGLEMDS with disabling OI scrub"
362         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
363                 error "(2) Fail to start MDS!"
364
365         #define OBD_FAIL_LFSCK_DELAY2           0x1601
366         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
367         $START_NAMESPACE -r || error "(4) Fail to start LFSCK for namespace!"
368         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
369                 mdd.${MDT_DEV}.lfsck_namespace |
370                 awk '/^flags/ { print \\\$2 }'" "inconsistent" 6 || {
371                 $SHOW_NAMESPACE
372                 error "(5) unexpected status"
373         }
374
375         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
376         [ "$STATUS" == "scanning-phase1" ] ||
377                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
378
379         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
380         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
381                 mdd.${MDT_DEV}.lfsck_namespace |
382                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
383                 $SHOW_NAMESPACE
384                 error "(7) unexpected status"
385         }
386
387         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
388         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
389
390         local repaired=$($SHOW_NAMESPACE |
391                          awk '/^dirent_repaired/ { print $2 }')
392         # for interop with old server
393         [ -z "$repaired" ] &&
394                 repaired=$($SHOW_NAMESPACE |
395                          awk '/^updated_phase1/ { print $2 }')
396
397         [ $repaired -ge 9 ] ||
398                 error "(9) Fail to re-generate FID-in-dirent: $repaired"
399
400         mount_client $MOUNT || error "(10) Fail to start client!"
401
402         #define OBD_FAIL_FID_LOOKUP     0x1505
403         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
404         ls $DIR/$tdir/ > /dev/null || error "(11) no FID-in-dirent."
405         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
406 }
407 run_test 4 "FID-in-dirent can be rebuilt after MDT file-level backup/restore"
408
409 test_5()
410 {
411         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
412                 skip "OI Scrub not implemented for ZFS" && return
413
414         lfsck_prep 1 1 1
415         cleanup_mount $MOUNT || error "(0.1) Fail to stop client!"
416         stop $SINGLEMDS > /dev/null || error "(0.2) Fail to stop MDS!"
417
418         mds_backup_restore $SINGLEMDS 1 || error "(1) Fail to backup/restore!"
419         echo "start $SINGLEMDS with disabling OI scrub"
420         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
421                 error "(2) Fail to start MDS!"
422
423         #define OBD_FAIL_LFSCK_DELAY2           0x1601
424         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
425         $START_NAMESPACE -r || error "(4) Fail to start LFSCK for namespace!"
426         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
427                 mdd.${MDT_DEV}.lfsck_namespace |
428                 awk '/^flags/ { print \\\$2 }'" "inconsistent,upgrade" 6 || {
429                 $SHOW_NAMESPACE
430                 error "(5) unexpected status"
431         }
432
433         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
434         [ "$STATUS" == "scanning-phase1" ] ||
435                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
436
437         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
438         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
439                 mdd.${MDT_DEV}.lfsck_namespace |
440                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
441                 $SHOW_NAMESPACE
442                 error "(7) unexpected status"
443         }
444
445         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
446         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
447
448         local repaired=$($SHOW_NAMESPACE |
449                          awk '/^dirent_repaired/ { print $2 }')
450         # for interop with old server
451         [ -z "$repaired" ] &&
452                 repaired=$($SHOW_NAMESPACE |
453                          awk '/^updated_phase1/ { print $2 }')
454
455         [ $repaired -ge 2 ] ||
456                 error "(9) Fail to generate FID-in-dirent for IGIF: $repaired"
457
458         mount_client $MOUNT || error "(10) Fail to start client!"
459
460         #define OBD_FAIL_FID_LOOKUP     0x1505
461         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
462         stat $DIR/$tdir/dummy > /dev/null || error "(11) no FID-in-LMA."
463
464         ls $DIR/$tdir/ > /dev/null || error "(12) no FID-in-dirent."
465
466         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
467         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
468         local dummyname=$($LFS fid2path $DIR $dummyfid)
469         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
470                 error "(13) Fail to generate linkEA: $dummyfid $dummyname"
471 }
472 run_test 5 "LFSCK can handle IGIF object upgrading"
473
474 test_6a() {
475         lfsck_prep 5 5
476
477         #define OBD_FAIL_LFSCK_DELAY1           0x1600
478         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
479         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
480
481         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
482         [ "$STATUS" == "scanning-phase1" ] ||
483                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
484
485         # Sleep 3 sec to guarantee at least one object processed by LFSCK
486         sleep 3
487         # Fail the LFSCK to guarantee there is at least one checkpoint
488         #define OBD_FAIL_LFSCK_FATAL1           0x1608
489         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001608
490         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
491                 mdd.${MDT_DEV}.lfsck_namespace |
492                 awk '/^status/ { print \\\$2 }'" "failed" 6 || {
493                 $SHOW_NAMESPACE
494                 error "(4) unexpected status"
495         }
496
497         local POS0=$($SHOW_NAMESPACE |
498                      awk '/^last_checkpoint_position/ { print $2 }' |
499                      tr -d ',')
500
501         #define OBD_FAIL_LFSCK_DELAY1           0x1600
502         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1600
503         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
504
505         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
506         [ "$STATUS" == "scanning-phase1" ] ||
507                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
508
509         local POS1=$($SHOW_NAMESPACE |
510                      awk '/^latest_start_position/ { print $2 }' |
511                      tr -d ',')
512         [[ $POS0 -lt $POS1 ]] ||
513                 error "(7) Expect larger than: $POS0, but got $POS1"
514
515         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
516         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
517                 mdd.${MDT_DEV}.lfsck_namespace |
518                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
519                 $SHOW_NAMESPACE
520                 error "(8) unexpected status"
521         }
522 }
523 run_test 6a "LFSCK resumes from last checkpoint (1)"
524
525 test_6b() {
526         lfsck_prep 5 5
527
528         #define OBD_FAIL_LFSCK_DELAY2           0x1601
529         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
530         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
531
532         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
533         [ "$STATUS" == "scanning-phase1" ] ||
534                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
535
536         # Sleep 5 sec to guarantee that we are in the directory scanning
537         sleep 5
538         # Fail the LFSCK to guarantee there is at least one checkpoint
539         #define OBD_FAIL_LFSCK_FATAL2           0x1609
540         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
541         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
542                 mdd.${MDT_DEV}.lfsck_namespace |
543                 awk '/^status/ { print \\\$2 }'" "failed" 6 || {
544                 $SHOW_NAMESPACE
545                 error "(4) unexpected status"
546         }
547
548         local O_POS0=$($SHOW_NAMESPACE |
549                        awk '/^last_checkpoint_position/ { print $2 }' |
550                        tr -d ',')
551
552         local D_POS0=$($SHOW_NAMESPACE |
553                        awk '/^last_checkpoint_position/ { print $4 }')
554
555         #define OBD_FAIL_LFSCK_DELAY2           0x1601
556         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
557         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
558
559         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
560         [ "$STATUS" == "scanning-phase1" ] ||
561                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
562
563         local O_POS1=$($SHOW_NAMESPACE |
564                        awk '/^latest_start_position/ { print $2 }' |
565                        tr -d ',')
566         local D_POS1=$($SHOW_NAMESPACE |
567                        awk '/^latest_start_position/ { print $4 }')
568
569         if [ "$D_POS0" == "N/A" -o "$D_POS1" == "N/A" ]; then
570                 [[ $O_POS0 -lt $O_POS1 ]] ||
571                         error "(7.1) $O_POS1 is not larger than $O_POS0"
572         else
573                 [[ $D_POS0 -lt $D_POS1 ]] ||
574                         error "(7.2) $D_POS1 is not larger than $D_POS0"
575         fi
576
577         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
578         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
579                 mdd.${MDT_DEV}.lfsck_namespace |
580                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
581                 $SHOW_NAMESPACE
582                 error "(8) unexpected status"
583         }
584 }
585 run_test 6b "LFSCK resumes from last checkpoint (2)"
586
587 test_7a()
588 {
589         lfsck_prep 5 5
590         umount_client $MOUNT
591
592         #define OBD_FAIL_LFSCK_DELAY2           0x1601
593         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1601
594         $START_NAMESPACE -r || error "(2) Fail to start LFSCK for namespace!"
595
596         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
597         [ "$STATUS" == "scanning-phase1" ] ||
598                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
599
600         # Sleep 3 sec to guarantee at least one object processed by LFSCK
601         sleep 3
602         echo "stop $SINGLEMDS"
603         stop $SINGLEMDS > /dev/null || error "(4) Fail to stop MDS!"
604
605         echo "start $SINGLEMDS"
606         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
607                 error "(5) Fail to start MDS!"
608
609         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
610         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
611                 mdd.${MDT_DEV}.lfsck_namespace |
612                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
613                 $SHOW_NAMESPACE
614                 error "(6) unexpected status"
615         }
616 }
617 run_test 7a "non-stopped LFSCK should auto restarts after MDS remount (1)"
618
619 test_7b()
620 {
621         lfsck_prep 2 2
622
623         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
624         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
625         for ((i = 0; i < 20; i++)); do
626                 touch $DIR/$tdir/dummy${i}
627         done
628
629         #define OBD_FAIL_LFSCK_DELAY3           0x1602
630         do_facet $SINGLEMDS $LCTL set_param fail_val=1 fail_loc=0x1602
631         $START_NAMESPACE -r || error "(3) Fail to start LFSCK for namespace!"
632         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
633                 mdd.${MDT_DEV}.lfsck_namespace |
634                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 6 || {
635                 $SHOW_NAMESPACE
636                 error "(4) unexpected status"
637         }
638
639         echo "stop $SINGLEMDS"
640         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop MDS!"
641
642         echo "start $SINGLEMDS"
643         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
644                 error "(6) Fail to start MDS!"
645
646         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
647         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
648                 mdd.${MDT_DEV}.lfsck_namespace |
649                 awk '/^status/ { print \\\$2 }'" "completed" 30 || {
650                 $SHOW_NAMESPACE
651                 error "(7) unexpected status"
652         }
653 }
654 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
655
656 test_8()
657 {
658         echo "formatall"
659         formatall > /dev/null
660         echo "setupall"
661         setupall > /dev/null
662
663         lfsck_prep 20 20
664
665         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
666         [ "$STATUS" == "init" ] ||
667                 error "(2) Expect 'init', but got '$STATUS'"
668
669         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
670         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
671         mkdir $DIR/$tdir/crashed
672
673         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
674         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
675         for ((i = 0; i < 5; i++)); do
676                 touch $DIR/$tdir/dummy${i}
677         done
678
679         umount_client $MOUNT || error "(3) Fail to stop client!"
680
681         #define OBD_FAIL_LFSCK_DELAY2           0x1601
682         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1601
683         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
684
685         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
686         [ "$STATUS" == "scanning-phase1" ] ||
687                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
688
689         $STOP_LFSCK || error "(6) Fail to stop LFSCK!"
690
691         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
692         [ "$STATUS" == "stopped" ] ||
693                 error "(7) Expect 'stopped', but got '$STATUS'"
694
695         $START_NAMESPACE || error "(8) Fail to start LFSCK for namespace!"
696
697         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
698         [ "$STATUS" == "scanning-phase1" ] ||
699                 error "(9) Expect 'scanning-phase1', but got '$STATUS'"
700
701         #define OBD_FAIL_LFSCK_FATAL2           0x1609
702         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
703         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
704                 mdd.${MDT_DEV}.lfsck_namespace |
705                 awk '/^status/ { print \\\$2 }'" "failed" 6 || {
706                 $SHOW_NAMESPACE
707                 error "(10) unexpected status"
708         }
709
710         #define OBD_FAIL_LFSCK_DELAY1           0x1600
711         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
712         $START_NAMESPACE || error "(11) Fail to start LFSCK for namespace!"
713
714         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
715         [ "$STATUS" == "scanning-phase1" ] ||
716                 error "(12) Expect 'scanning-phase1', but got '$STATUS'"
717
718         #define OBD_FAIL_LFSCK_CRASH            0x160a
719         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
720         sleep 5
721
722         echo "stop $SINGLEMDS"
723         stop $SINGLEMDS > /dev/null || error "(13) Fail to stop MDS!"
724
725         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
726         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
727
728         echo "start $SINGLEMDS"
729         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
730                 error "(14) Fail to start MDS!"
731
732         local timeout=$(max_recovery_time)
733         local timer=0
734
735         while [ $timer -lt $timeout ]; do
736                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
737                         mdt.${MDT_DEV}.recovery_status |
738                         awk '/^status/ { print \\\$2 }'")
739                 [ "$STATUS" != "RECOVERING" ] && break;
740                 sleep 1
741                 timer=$((timer + 1))
742         done
743
744         [ $timer != $timeout ] ||
745                 error "(14.1) recovery timeout"
746
747         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
748         [ "$STATUS" == "crashed" ] ||
749                 error "(15) Expect 'crashed', but got '$STATUS'"
750
751         #define OBD_FAIL_LFSCK_DELAY2           0x1601
752         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
753         $START_NAMESPACE || error "(16) Fail to start LFSCK for namespace!"
754
755         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
756         [ "$STATUS" == "scanning-phase1" ] ||
757                 error "(17) Expect 'scanning-phase1', but got '$STATUS'"
758
759         echo "stop $SINGLEMDS"
760         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop MDS!"
761
762         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
763         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
764
765         echo "start $SINGLEMDS"
766         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
767                 error "(19) Fail to start MDS!"
768
769         timer=0
770         while [ $timer -lt $timeout ]; do
771                 STATUS=$(do_facet $SINGLEMDS "$LCTL get_param -n \
772                         mdt.${MDT_DEV}.recovery_status |
773                         awk '/^status/ { print \\\$2 }'")
774                 [ "$STATUS" != "RECOVERING" ] && break;
775                 sleep 1
776                 timer=$((timer + 1))
777         done
778
779         [ $timer != $timeout ] ||
780                 error "(19.1) recovery timeout"
781
782         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
783         [ "$STATUS" == "paused" ] ||
784                 error "(20) Expect 'paused', but got '$STATUS'"
785
786         #define OBD_FAIL_LFSCK_DELAY3           0x1602
787         do_facet $SINGLEMDS $LCTL set_param fail_val=2 fail_loc=0x1602
788
789         $START_NAMESPACE || error "(21) Fail to start LFSCK for namespace!"
790         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
791                 mdd.${MDT_DEV}.lfsck_namespace |
792                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 6 || {
793                 $SHOW_NAMESPACE
794                 error "(22) unexpected status"
795         }
796
797         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
798         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
799                 error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
800
801         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
802         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
803                 mdd.${MDT_DEV}.lfsck_namespace |
804                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
805                 $SHOW_NAMESPACE
806                 error "(24) unexpected status"
807         }
808
809         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
810         [ -z "$FLAGS" ] || error "(25) Expect empty flags, but got '$FLAGS'"
811 }
812 run_test 8 "LFSCK state machine"
813
814 test_9a() {
815         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
816                 skip "Testing on UP system, the speed may be inaccurate."
817                 return 0
818         fi
819
820         lfsck_prep 70 70
821
822         local BASE_SPEED1=100
823         local RUN_TIME1=10
824         $START_NAMESPACE -r -s $BASE_SPEED1 || error "(3) Fail to start LFSCK!"
825
826         sleep $RUN_TIME1
827         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
828         [ "$STATUS" == "scanning-phase1" ] ||
829                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
830
831         local SPEED=$($SHOW_NAMESPACE |
832                       awk '/^average_speed_phase1/ { print $2 }')
833
834         # There may be time error, normally it should be less than 2 seconds.
835         # We allow another 20% schedule error.
836         local TIME_DIFF=2
837         # MAX_MARGIN = 1.2 = 12 / 10
838         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
839                            RUN_TIME1 * 12 / 10))
840         [ $SPEED -lt $MAX_SPEED ] ||
841                 error "(4) Got speed $SPEED, expected less than $MAX_SPEED"
842
843         # adjust speed limit
844         local BASE_SPEED2=300
845         local RUN_TIME2=10
846         do_facet $SINGLEMDS \
847                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
848         sleep $RUN_TIME2
849
850         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase1/ { print $2 }')
851         # MIN_MARGIN = 0.8 = 8 / 10
852         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
853                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
854                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
855         # Account for slow ZFS performance - LU-4934
856         [ $SPEED -gt $MIN_SPEED ] || [ $(facet_fstype $SINGLEMDS) -eq zfs ] ||
857                 error "(5) Got speed $SPEED, expected more than $MIN_SPEED"
858
859         # MAX_MARGIN = 1.2 = 12 / 10
860         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
861                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
862                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
863         [ $SPEED -lt $MAX_SPEED ] ||
864                 error "(6) Got speed $SPEED, expected less than $MAX_SPEED"
865
866         do_facet $SINGLEMDS \
867                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
868
869         wait_update_facet $SINGLEMDS \
870             "$LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace|\
871             awk '/^status/ { print \\\$2 }'" "completed" 30 ||
872                 error "(7) Failed to get expected 'completed'"
873 }
874 run_test 9a "LFSCK speed control (1)"
875
876 test_9b() {
877         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
878                 skip "Testing on UP system, the speed may be inaccurate."
879                 return 0
880         fi
881
882         lfsck_prep 0 0
883
884         echo "Preparing another 50 * 50 files (with error) at $(date)."
885         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
886         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
887         createmany -d $DIR/$tdir/d 50
888         createmany -m $DIR/$tdir/f 50
889         for ((i = 0; i < 50; i++)); do
890                 createmany -m $DIR/$tdir/d${i}/f 50 > /dev/null
891         done
892
893         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
894         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
895         $START_NAMESPACE -r || error "(4) Fail to start LFSCK!"
896         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
897                 mdd.${MDT_DEV}.lfsck_namespace |
898                 awk '/^status/ { print \\\$2 }'" "stopped" 10 || {
899                 $SHOW_NAMESPACE
900                 error "(5) unexpected status"
901         }
902
903         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
904         echo "Prepared at $(date)."
905
906         local BASE_SPEED1=50
907         local RUN_TIME1=10
908         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
909
910         sleep $RUN_TIME1
911         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
912         [ "$STATUS" == "scanning-phase2" ] ||
913                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
914
915         local SPEED=$($SHOW_NAMESPACE |
916                       awk '/^average_speed_phase2/ { print $2 }')
917         # There may be time error, normally it should be less than 2 seconds.
918         # We allow another 20% schedule error.
919         local TIME_DIFF=2
920         # MAX_MARGIN = 1.2 = 12 / 10
921         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
922                           RUN_TIME1 * 12 / 10))
923         [ $SPEED -lt $MAX_SPEED ] ||
924                 error "(8) Got speed $SPEED, expected less than $MAX_SPEED"
925
926         # adjust speed limit
927         local BASE_SPEED2=150
928         local RUN_TIME2=10
929         do_facet $SINGLEMDS \
930                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
931         sleep $RUN_TIME2
932
933         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
934         # MIN_MARGIN = 0.8 = 8 / 10
935         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
936                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
937                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
938         [ $SPEED -gt $MIN_SPEED ] ||[ $(facet_fstype $SINGLEMDS) -eq zfs ] ||
939                 error "(9) Got speed $SPEED, expected more than $MIN_SPEED"
940
941         # MAX_MARGIN = 1.2 = 12 / 10
942         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
943                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
944                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
945         [ $SPEED -lt $MAX_SPEED ] ||
946                 error "(10) Got speed $SPEED, expected less than $MAX_SPEED"
947
948         do_facet $SINGLEMDS \
949                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
950         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
951                 mdd.${MDT_DEV}.lfsck_namespace |
952                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
953                 $SHOW_NAMESPACE
954                 error "(11) unexpected status"
955         }
956 }
957 run_test 9b "LFSCK speed control (2)"
958
959 test_10()
960 {
961         [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
962                 skip "lookup(..)/linkea on ZFS issue" && return
963
964         lfsck_prep 1 1
965
966         echo "Preparing more files with error at $(date)."
967         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
968         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
969
970         for ((i = 0; i < 1000; i = $((i+2)))); do
971                 mkdir -p $DIR/$tdir/d${i}
972                 touch $DIR/$tdir/f${i}
973                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
974         done
975
976         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
977         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
978
979         for ((i = 1; i < 1000; i = $((i+2)))); do
980                 mkdir -p $DIR/$tdir/d${i}
981                 touch $DIR/$tdir/f${i}
982                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
983         done
984
985         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
986         echo "Prepared at $(date)."
987
988         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
989
990         umount_client $MOUNT
991         mount_client $MOUNT || error "(3) Fail to start client!"
992
993         $START_NAMESPACE -r -s 100 || error "(5) Fail to start LFSCK!"
994
995         sleep 10
996         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
997         [ "$STATUS" == "scanning-phase1" ] ||
998                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
999
1000         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
1001
1002         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
1003
1004         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
1005
1006         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
1007
1008         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
1009
1010         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
1011
1012         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
1013
1014         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
1015                 error "(14) Fail to softlink!"
1016
1017         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
1018         [ "$STATUS" == "scanning-phase1" ] ||
1019                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
1020
1021         do_facet $SINGLEMDS \
1022                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
1023         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1024                 mdd.${MDT_DEV}.lfsck_namespace |
1025                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1026                 $SHOW_NAMESPACE
1027                 error "(16) unexpected status"
1028         }
1029 }
1030 run_test 10 "System is available during LFSCK scanning"
1031
1032 # remove LAST_ID
1033 ost_remove_lastid() {
1034         local ost=$1
1035         local idx=$2
1036         local rcmd="do_facet ost${ost}"
1037
1038         echo "remove LAST_ID on ost${ost}: idx=${idx}"
1039
1040         # step 1: local mount
1041         mount_fstype ost${ost} || return 1
1042         # step 2: remove the specified LAST_ID
1043         ${rcmd} rm -fv $(facet_mntpt ost${ost})/O/${idx}/{LAST_ID,d0/0}
1044         # step 3: umount
1045         unmount_fstype ost${ost} || return 2
1046 }
1047
1048 test_11a() {
1049         check_mount_and_prep
1050         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1051         createmany -o $DIR/$tdir/f 64 || error "(0) Fail to create 64 files."
1052
1053         echo "stopall"
1054         stopall > /dev/null
1055
1056         ost_remove_lastid 1 0 || error "(1) Fail to remove LAST_ID"
1057
1058         start ost1 $(ostdevname 1) $MOUNT_OPTS_NOSCRUB > /dev/null ||
1059                 error "(2) Fail to start ost1"
1060
1061         #define OBD_FAIL_LFSCK_DELAY4           0x160e
1062         do_facet ost1 $LCTL set_param fail_val=3 fail_loc=0x160e
1063
1064         echo "trigger LFSCK for layout on ost1 to rebuild the LAST_ID(s)"
1065         $START_LAYOUT_ON_OST -r || error "(4) Fail to start LFSCK on OST!"
1066
1067         wait_update_facet ost1 "$LCTL get_param -n \
1068                 obdfilter.${OST_DEV}.lfsck_layout |
1069                 awk '/^flags/ { print \\\$2 }'" "crashed_lastid" 60 || {
1070                 $SHOW_LAYOUT_ON_OST
1071                 error "(5) unexpected status"
1072         }
1073
1074         do_facet ost1 $LCTL set_param fail_val=0 fail_loc=0
1075
1076         wait_update_facet ost1 "$LCTL get_param -n \
1077                 obdfilter.${OST_DEV}.lfsck_layout |
1078                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1079                 $SHOW_LAYOUT_ON_OST
1080                 error "(6) unexpected status"
1081         }
1082
1083         echo "the LAST_ID(s) should have been rebuilt"
1084         FLAGS=$($SHOW_LAYOUT_ON_OST | awk '/^flags/ { print $2 }')
1085         [ -z "$FLAGS" ] || error "(7) Expect empty flags, but got '$FLAGS'"
1086 }
1087 run_test 11a "LFSCK can rebuild lost last_id"
1088
1089 test_11b() {
1090         check_mount_and_prep
1091         $SETSTRIPE -c 1 -i 0 $DIR/$tdir
1092
1093         echo "set fail_loc=0x160d to skip the updating LAST_ID on-disk"
1094         #define OBD_FAIL_LFSCK_SKIP_LASTID      0x160d
1095         do_facet ost1 $LCTL set_param fail_loc=0x160d
1096         createmany -o $DIR/$tdir/f 64
1097         local lastid1=$(do_facet ost1 "lctl get_param -n \
1098                 obdfilter.${ost1_svc}.last_id" | grep 0x100000000 |
1099                 awk -F: '{ print $2 }')
1100
1101         umount_client $MOUNT
1102         stop ost1 || error "(1) Fail to stop ost1"
1103
1104         #define OBD_FAIL_OST_ENOSPC              0x215
1105         do_facet ost1 $LCTL set_param fail_loc=0x215
1106
1107         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1108                 error "(2) Fail to start ost1"
1109
1110         for ((i = 0; i < 60; i++)); do
1111                 lastid2=$(do_facet ost1 "lctl get_param -n \
1112                         obdfilter.${ost1_svc}.last_id" | grep 0x100000000 |
1113                         awk -F: '{ print $2 }')
1114                 [ ! -z $lastid2 ] && break;
1115                 sleep 1
1116         done
1117
1118         echo "the on-disk LAST_ID should be smaller than the expected one"
1119         [ $lastid1 -gt $lastid2 ] ||
1120                 error "(4) expect lastid1 [ $lastid1 ] > lastid2 [ $lastid2 ]"
1121
1122         echo "trigger LFSCK for layout on ost1 to rebuild the on-disk LAST_ID"
1123         $START_LAYOUT_ON_OST -r || error "(5) Fail to start LFSCK on OST!"
1124
1125         wait_update_facet ost1 "$LCTL get_param -n \
1126                 obdfilter.${OST_DEV}.lfsck_layout |
1127                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1128                 $SHOW_LAYOUT_ON_OST
1129                 error "(6) unexpected status"
1130         }
1131
1132         stop ost1 || error "(7) Fail to stop ost1"
1133
1134         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS ||
1135                 error "(8) Fail to start ost1"
1136
1137         echo "the on-disk LAST_ID should have been rebuilt"
1138         wait_update_facet ost1 "$LCTL get_param -n \
1139                 obdfilter.${ost1_svc}.last_id | grep 0x100000000 |
1140                 awk -F: '{ print \\\$2 }'" "$lastid1" 60 || {
1141                 $LCTL get_param -n obdfilter.${ost1_svc}.last_id
1142                 error "(9) expect lastid1 0x100000000:$lastid1"
1143         }
1144
1145         do_facet ost1 $LCTL set_param fail_loc=0
1146         stopall || error "(10) Fail to stopall"
1147 }
1148 run_test 11b "LFSCK can rebuild crashed last_id"
1149
1150 test_12() {
1151         [ $MDSCOUNT -lt 2 ] &&
1152                 skip "We need at least 2 MDSes for test_12" && exit 0
1153
1154         check_mount_and_prep
1155         for k in $(seq $MDSCOUNT); do
1156                 $LFS mkdir -i $((k - 1)) $DIR/$tdir/${k}
1157                 createmany -o $DIR/$tdir/${k}/f 100 ||
1158                         error "(0) Fail to create 100 files."
1159         done
1160
1161         echo "Start namespace LFSCK on all targets by single command (-s 1)."
1162         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1163                 -s 1 -r || error "(2) Fail to start LFSCK on all devices!"
1164
1165         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1166         for k in $(seq $MDSCOUNT); do
1167                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1168                                 mdd.$(facet_svc mds${k}).lfsck_namespace |
1169                                 awk '/^status/ { print $2 }')
1170                 [ "$STATUS" == "scanning-phase1" ] ||
1171                 error "(3) MDS${k} Expect 'scanning-phase1', but got '$STATUS'"
1172         done
1173
1174         echo "Stop namespace LFSCK on all targets by single lctl command."
1175         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1176                 error "(4) Fail to stop LFSCK on all devices!"
1177
1178         echo "All the LFSCK targets should be in 'stopped' status."
1179         for k in $(seq $MDSCOUNT); do
1180                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1181                                 mdd.$(facet_svc mds${k}).lfsck_namespace |
1182                                 awk '/^status/ { print $2 }')
1183                 [ "$STATUS" == "stopped" ] ||
1184                         error "(5) MDS${k} Expect 'stopped', but got '$STATUS'"
1185         done
1186
1187         echo "Re-start namespace LFSCK on all targets by single command (-s 0)."
1188         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t namespace -A \
1189                 -s 0 -r || error "(6) Fail to start LFSCK on all devices!"
1190
1191         echo "All the LFSCK targets should be in 'completed' status."
1192         for k in $(seq $MDSCOUNT); do
1193                 wait_update_facet mds${k} "$LCTL get_param -n \
1194                         mdd.$(facet_svc mds${k}).lfsck_namespace |
1195                         awk '/^status/ { print \\\$2 }'" "completed" 8 ||
1196                         error "(7) MDS${k} is not the expected 'completed'"
1197         done
1198
1199         echo "Start layout LFSCK on all targets by single command (-s 1)."
1200         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1201                 -s 1 -r || error "(8) Fail to start LFSCK on all devices!"
1202
1203         echo "All the LFSCK targets should be in 'scanning-phase1' status."
1204         for k in $(seq $MDSCOUNT); do
1205                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1206                                 mdd.$(facet_svc mds${k}).lfsck_layout |
1207                                 awk '/^status/ { print $2 }')
1208                 [ "$STATUS" == "scanning-phase1" ] ||
1209                 error "(9) MDS${k} Expect 'scanning-phase1', but got '$STATUS'"
1210         done
1211
1212         echo "Stop layout LFSCK on all targets by single lctl command."
1213         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 -A ||
1214                 error "(10) Fail to stop LFSCK on all devices!"
1215
1216         echo "All the LFSCK targets should be in 'stopped' status."
1217         for k in $(seq $MDSCOUNT); do
1218                 local STATUS=$(do_facet mds${k} $LCTL get_param -n \
1219                                 mdd.$(facet_svc mds${k}).lfsck_layout |
1220                                 awk '/^status/ { print $2 }')
1221                 [ "$STATUS" == "stopped" ] ||
1222                         error "(11) MDS${k} Expect 'stopped', but got '$STATUS'"
1223         done
1224
1225         for k in $(seq $OSTCOUNT); do
1226                 local STATUS=$(do_facet ost${k} $LCTL get_param -n \
1227                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1228                                 awk '/^status/ { print $2 }')
1229                 [ "$STATUS" == "stopped" ] ||
1230                         error "(12) OST${k} Expect 'stopped', but got '$STATUS'"
1231         done
1232
1233         echo "Re-start layout LFSCK on all targets by single command (-s 0)."
1234         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -t layout -A \
1235                 -s 0 -r || error "(13) Fail to start LFSCK on all devices!"
1236
1237         echo "All the LFSCK targets should be in 'completed' status."
1238         for k in $(seq $MDSCOUNT); do
1239                 # The LFSCK status query internal is 30 seconds. For the case
1240                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1241                 # time to guarantee the status sync up.
1242                 wait_update_facet mds${k} "$LCTL get_param -n \
1243                         mdd.$(facet_svc mds${k}).lfsck_layout |
1244                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
1245                         error "(14) MDS${k} is not the expected 'completed'"
1246         done
1247 }
1248 run_test 12 "single command to trigger LFSCK on all devices"
1249
1250 test_13() {
1251         echo "#####"
1252         echo "The lmm_oi in layout EA should be consistent with the MDT-object"
1253         echo "FID; otherwise, the LFSCK should re-generate the lmm_oi from the"
1254         echo "MDT-object FID."
1255         echo "#####"
1256
1257         check_mount_and_prep
1258
1259         echo "Inject failure stub to simulate bad lmm_oi"
1260         #define OBD_FAIL_LFSCK_BAD_LMMOI        0x160f
1261         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160f
1262         createmany -o $DIR/$tdir/f 32
1263         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1264
1265         echo "Trigger layout LFSCK to find out the bad lmm_oi and fix them"
1266         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1267
1268         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1269                 mdd.${MDT_DEV}.lfsck_layout |
1270                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1271                 $SHOW_LAYOUT
1272                 error "(2) unexpected status"
1273         }
1274
1275         local repaired=$($SHOW_LAYOUT |
1276                          awk '/^repaired_others/ { print $2 }')
1277         [ $repaired -eq 32 ] ||
1278                 error "(3) Fail to repair crashed lmm_oi: $repaired"
1279 }
1280 run_test 13 "LFSCK can repair crashed lmm_oi"
1281
1282 test_14() {
1283         echo "#####"
1284         echo "The OST-object referenced by the MDT-object should be there;"
1285         echo "otherwise, the LFSCK should re-create the missed OST-object."
1286         echo "#####"
1287
1288         check_mount_and_prep
1289         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1290
1291         local count=$(precreated_ost_obj_count 0 0)
1292
1293         echo "Inject failure stub to simulate dangling referenced MDT-object"
1294         #define OBD_FAIL_LFSCK_DANGLING 0x1610
1295         do_facet ost1 $LCTL set_param fail_loc=0x1610
1296         createmany -o $DIR/$tdir/f $((count + 32))
1297         do_facet ost1 $LCTL set_param fail_loc=0
1298
1299         start_full_debug_logging
1300
1301         # exhaust other pre-created dangling cases
1302         count=$(precreated_ost_obj_count 0 0)
1303         createmany -o $DIR/$tdir/a $count ||
1304                 error "(0) Fail to create $count files."
1305
1306         echo "'ls' should fail because of dangling referenced MDT-object"
1307         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(1) ls should fail."
1308
1309         echo "Trigger layout LFSCK to find out dangling reference"
1310         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1311
1312         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1313                 mdd.${MDT_DEV}.lfsck_layout |
1314                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1315                 $SHOW_LAYOUT
1316                 error "(3) unexpected status"
1317         }
1318
1319         local repaired=$($SHOW_LAYOUT |
1320                          awk '/^repaired_dangling/ { print $2 }')
1321         [ $repaired -ge 32 ] ||
1322                 error "(4) Fail to repair dangling reference: $repaired"
1323
1324         echo "'ls' should fail because it will not repair dangling by default"
1325         ls -ail $DIR/$tdir > /dev/null 2>&1 && error "(5) ls should fail."
1326
1327         echo "Trigger layout LFSCK to repair dangling reference"
1328         $START_LAYOUT -r -c || error "(6) Fail to start LFSCK for layout!"
1329
1330         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1331                 mdd.${MDT_DEV}.lfsck_layout |
1332                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1333                 $SHOW_LAYOUT
1334                 error "(7) unexpected status"
1335         }
1336
1337         repaired=$($SHOW_LAYOUT |
1338                          awk '/^repaired_dangling/ { print $2 }')
1339         [ $repaired -ge 32 ] ||
1340                 error "(8) Fail to repair dangling reference: $repaired"
1341
1342         echo "'ls' should success after layout LFSCK repairing"
1343         ls -ail $DIR/$tdir > /dev/null || error "(9) ls should success."
1344         stop_full_debug_logging
1345 }
1346 run_test 14 "LFSCK can repair MDT-object with dangling reference"
1347
1348 test_15a() {
1349         echo "#####"
1350         echo "If the OST-object referenced by the MDT-object back points"
1351         echo "to some non-exist MDT-object, then the LFSCK should repair"
1352         echo "the OST-object to back point to the right MDT-object."
1353         echo "#####"
1354
1355         check_mount_and_prep
1356         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1357
1358         echo "Inject failure stub to make the OST-object to back point to"
1359         echo "non-exist MDT-object."
1360         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
1361
1362         do_facet ost1 $LCTL set_param fail_loc=0x1611
1363         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1364         cancel_lru_locks osc
1365         do_facet ost1 $LCTL set_param fail_loc=0
1366
1367         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1368         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1369
1370         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1371                 mdd.${MDT_DEV}.lfsck_layout |
1372                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1373                 $SHOW_LAYOUT
1374                 error "(2) unexpected status"
1375         }
1376
1377         local repaired=$($SHOW_LAYOUT |
1378                          awk '/^repaired_unmatched_pair/ { print $2 }')
1379         [ $repaired -eq 1 ] ||
1380                 error "(3) Fail to repair unmatched pair: $repaired"
1381 }
1382 run_test 15a "LFSCK can repair unmatched MDT-object/OST-object pairs (1)"
1383
1384 test_15b() {
1385         echo "#####"
1386         echo "If the OST-object referenced by the MDT-object back points"
1387         echo "to other MDT-object that doesn't recognize the OST-object,"
1388         echo "then the LFSCK should repair it to back point to the right"
1389         echo "MDT-object (the first one)."
1390         echo "#####"
1391
1392         check_mount_and_prep
1393         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1394         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
1395         cancel_lru_locks osc
1396
1397         echo "Inject failure stub to make the OST-object to back point to"
1398         echo "other MDT-object"
1399
1400         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR2  0x1612
1401         do_facet ost1 $LCTL set_param fail_loc=0x1612
1402         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1403         cancel_lru_locks osc
1404         do_facet ost1 $LCTL set_param fail_loc=0
1405
1406         echo "Trigger layout LFSCK to find out unmatched pairs and fix them"
1407         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1408
1409         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1410                 mdd.${MDT_DEV}.lfsck_layout |
1411                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1412                 $SHOW_LAYOUT
1413                 error "(2) unexpected status"
1414         }
1415
1416         local repaired=$($SHOW_LAYOUT |
1417                          awk '/^repaired_unmatched_pair/ { print $2 }')
1418         [ $repaired -eq 1 ] ||
1419                 error "(3) Fail to repair unmatched pair: $repaired"
1420 }
1421 run_test 15b "LFSCK can repair unmatched MDT-object/OST-object pairs (2)"
1422
1423 test_16() {
1424         echo "#####"
1425         echo "If the OST-object's owner information does not match the owner"
1426         echo "information stored in the MDT-object, then the LFSCK trust the"
1427         echo "MDT-object and update the OST-object's owner information."
1428         echo "#####"
1429
1430         check_mount_and_prep
1431         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1432         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=1
1433         cancel_lru_locks osc
1434
1435         echo "Inject failure stub to skip OST-object owner changing"
1436         #define OBD_FAIL_LFSCK_BAD_OWNER        0x1613
1437         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1613
1438         chown 1.1 $DIR/$tdir/f0
1439         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1440
1441         echo "Trigger layout LFSCK to find out inconsistent OST-object owner"
1442         echo "and fix them"
1443
1444         $START_LAYOUT -r || error "(1) Fail to start LFSCK for layout!"
1445
1446         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1447                 mdd.${MDT_DEV}.lfsck_layout |
1448                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1449                 $SHOW_LAYOUT
1450                 error "(2) unexpected status"
1451         }
1452
1453         local repaired=$($SHOW_LAYOUT |
1454                          awk '/^repaired_inconsistent_owner/ { print $2 }')
1455         [ $repaired -eq 1 ] ||
1456                 error "(3) Fail to repair inconsistent owner: $repaired"
1457 }
1458 run_test 16 "LFSCK can repair inconsistent MDT-object/OST-object owner"
1459
1460 test_17() {
1461         echo "#####"
1462         echo "If more than one MDT-objects reference the same OST-object,"
1463         echo "and the OST-object only recognizes one MDT-object, then the"
1464         echo "LFSCK should create new OST-objects for such non-recognized"
1465         echo "MDT-objects."
1466         echo "#####"
1467
1468         check_mount_and_prep
1469         $LFS setstripe -c 1 -i 0 $DIR/$tdir
1470
1471         echo "Inject failure stub to make two MDT-objects to refernce"
1472         echo "the OST-object"
1473
1474         #define OBD_FAIL_LFSCK_MULTIPLE_REF     0x1614
1475         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0x1614
1476
1477         dd if=/dev/zero of=$DIR/$tdir/guard bs=1M count=1
1478         cancel_lru_locks osc
1479
1480         createmany -o $DIR/$tdir/f 1
1481
1482         do_facet $SINGLEMDS $LCTL set_param fail_loc=0 fail_val=0
1483
1484         cancel_lru_locks mdc
1485         cancel_lru_locks osc
1486
1487         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard use the same OST-objects"
1488         local size=$(ls -l $DIR/$tdir/f0 | awk '{ print $5 }')
1489         [ $size -eq 1048576 ] ||
1490                 error "(1) f0 (wrong) size should be 1048576, but got $size"
1491
1492         echo "Trigger layout LFSCK to find out multiple refenced MDT-objects"
1493         echo "and fix them"
1494
1495         $START_LAYOUT -r || error "(2) Fail to start LFSCK for layout!"
1496
1497         wait_update_facet $SINGLEMDS "$LCTL get_param -n \
1498                 mdd.${MDT_DEV}.lfsck_layout |
1499                 awk '/^status/ { print \\\$2 }'" "completed" 6 || {
1500                 $SHOW_LAYOUT
1501                 error "(3) unexpected status"
1502         }
1503
1504         local repaired=$($SHOW_LAYOUT |
1505                          awk '/^repaired_multiple_referenced/ { print $2 }')
1506         [ $repaired -eq 1 ] ||
1507                 error "(4) Fail to repair multiple references: $repaired"
1508
1509         echo "$DIR/$tdir/f0 and $DIR/$tdir/guard should use diff OST-objects"
1510         dd if=/dev/zero of=$DIR/$tdir/f0 bs=1M count=2 ||
1511                 error "(5) Fail to write f0."
1512         size=$(ls -l $DIR/$tdir/guard | awk '{ print $5 }')
1513         [ $size -eq 1048576 ] ||
1514                 error "(6) guard size should be 1048576, but got $size"
1515 }
1516 run_test 17 "LFSCK can repair multiple references"
1517
1518 test_18a() {
1519         echo "#####"
1520         echo "The target MDT-object is there, but related stripe information"
1521         echo "is lost or partly lost. The LFSCK should regenerate the missed"
1522         echo "layout EA entries."
1523         echo "#####"
1524
1525         check_mount_and_prep
1526         $LFS mkdir -i 0 $DIR/$tdir/a1
1527         $LFS setstripe -c 1 -i 0 -s 1M $DIR/$tdir/a1
1528         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
1529
1530         local saved_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1531
1532         $LFS path2fid $DIR/$tdir/a1/f1
1533         $LFS getstripe $DIR/$tdir/a1/f1
1534
1535         if [ $MDSCOUNT -ge 2 ]; then
1536                 $LFS mkdir -i 1 $DIR/$tdir/a2
1537                 $LFS setstripe -c 2 -i 1 -s 1M $DIR/$tdir/a2
1538                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
1539                 $LFS path2fid $DIR/$tdir/a2/f2
1540                 $LFS getstripe $DIR/$tdir/a2/f2
1541         fi
1542
1543         cancel_lru_locks osc
1544
1545         echo "Inject failure, to make the MDT-object lost its layout EA"
1546         #define OBD_FAIL_LFSCK_LOST_STRIPE 0x1615
1547         do_facet mds1 $LCTL set_param fail_loc=0x1615
1548         chown 1.1 $DIR/$tdir/a1/f1
1549
1550         if [ $MDSCOUNT -ge 2 ]; then
1551                 do_facet mds2 $LCTL set_param fail_loc=0x1615
1552                 chown 1.1 $DIR/$tdir/a2/f2
1553         fi
1554
1555         sync
1556         sleep 2
1557
1558         do_facet mds1 $LCTL set_param fail_loc=0
1559         if [ $MDSCOUNT -ge 2 ]; then
1560                 do_facet mds2 $LCTL set_param fail_loc=0
1561         fi
1562
1563         cancel_lru_locks mdc
1564         cancel_lru_locks osc
1565
1566         echo "The file size should be incorrect since layout EA is lost"
1567         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1568         [ "$cur_size" != "$saved_size" ] ||
1569                 error "(1) Expect incorrect file1 size"
1570
1571         if [ $MDSCOUNT -ge 2 ]; then
1572                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
1573                 [ "$cur_size" != "$saved_size" ] ||
1574                         error "(2) Expect incorrect file2 size"
1575         fi
1576
1577         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1578         $START_LAYOUT -r -o || error "(3) Fail to start LFSCK for layout!"
1579
1580         for k in $(seq $MDSCOUNT); do
1581                 # The LFSCK status query internal is 30 seconds. For the case
1582                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1583                 # time to guarantee the status sync up.
1584                 wait_update_facet mds${k} "$LCTL get_param -n \
1585                         mdd.$(facet_svc mds${k}).lfsck_layout |
1586                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
1587                         error "(4) MDS${k} is not the expected 'completed'"
1588         done
1589
1590         for k in $(seq $OSTCOUNT); do
1591                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
1592                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1593                                 awk '/^status/ { print $2 }')
1594                 [ "$cur_status" == "completed" ] ||
1595                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
1596         done
1597
1598         local repaired=$(do_facet mds1 $LCTL get_param -n \
1599                          mdd.$(facet_svc mds1).lfsck_layout |
1600                          awk '/^repaired_orphan/ { print $2 }')
1601         [ $repaired -eq 1 ] ||
1602         error "(6.1) Expect 1 fixed on mds1, but got: $repaired"
1603
1604         if [ $MDSCOUNT -ge 2 ]; then
1605                 repaired=$(do_facet mds2 $LCTL get_param -n \
1606                          mdd.$(facet_svc mds2).lfsck_layout |
1607                                  awk '/^repaired_orphan/ { print $2 }')
1608                 [ $repaired -eq 2 ] ||
1609                 error "(6.2) Expect 2 fixed on mds2, but got: $repaired"
1610         fi
1611
1612         $LFS path2fid $DIR/$tdir/a1/f1
1613         $LFS getstripe $DIR/$tdir/a1/f1
1614
1615         if [ $MDSCOUNT -ge 2 ]; then
1616                 $LFS path2fid $DIR/$tdir/a2/f2
1617                 $LFS getstripe $DIR/$tdir/a2/f2
1618         fi
1619
1620         echo "The file size should be correct after layout LFSCK scanning"
1621         cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1622         [ "$cur_size" == "$saved_size" ] ||
1623                 error "(7) Expect file1 size $saved_size, but got $cur_size"
1624
1625         if [ $MDSCOUNT -ge 2 ]; then
1626                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
1627                 [ "$cur_size" == "$saved_size" ] ||
1628                 error "(8) Expect file2 size $saved_size, but got $cur_size"
1629         fi
1630 }
1631 run_test 18a "Find out orphan OST-object and repair it (1)"
1632
1633 test_18b() {
1634         echo "#####"
1635         echo "The target MDT-object is lost. The LFSCK should re-create the"
1636         echo "MDT-object under .lustre/lost+found/MDTxxxx. The admin should"
1637         echo "can move it back to normal namespace manually."
1638         echo "#####"
1639
1640         check_mount_and_prep
1641         $LFS mkdir -i 0 $DIR/$tdir/a1
1642         $LFS setstripe -c 1 -i 0 -s 1M $DIR/$tdir/a1
1643         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
1644         local saved_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1645         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
1646         echo ${fid1}
1647         $LFS getstripe $DIR/$tdir/a1/f1
1648
1649         if [ $MDSCOUNT -ge 2 ]; then
1650                 $LFS mkdir -i 1 $DIR/$tdir/a2
1651                 $LFS setstripe -c 2 -i 1 -s 1M $DIR/$tdir/a2
1652                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
1653                 fid2=$($LFS path2fid $DIR/$tdir/a2/f2)
1654                 echo ${fid2}
1655                 $LFS getstripe $DIR/$tdir/a2/f2
1656         fi
1657
1658         cancel_lru_locks osc
1659
1660         echo "Inject failure, to simulate the case of missing the MDT-object"
1661         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
1662         do_facet mds1 $LCTL set_param fail_loc=0x1616
1663         rm -f $DIR/$tdir/a1/f1
1664
1665         if [ $MDSCOUNT -ge 2 ]; then
1666                 do_facet mds2 $LCTL set_param fail_loc=0x1616
1667                 rm -f $DIR/$tdir/a2/f2
1668         fi
1669
1670         sync
1671         sleep 2
1672
1673         do_facet mds1 $LCTL set_param fail_loc=0
1674         if [ $MDSCOUNT -ge 2 ]; then
1675                 do_facet mds2 $LCTL set_param fail_loc=0
1676         fi
1677
1678         cancel_lru_locks mdc
1679         cancel_lru_locks osc
1680
1681         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1682         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
1683
1684         for k in $(seq $MDSCOUNT); do
1685                 # The LFSCK status query internal is 30 seconds. For the case
1686                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1687                 # time to guarantee the status sync up.
1688                 wait_update_facet mds${k} "$LCTL get_param -n \
1689                         mdd.$(facet_svc mds${k}).lfsck_layout |
1690                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
1691                         error "(2) MDS${k} is not the expected 'completed'"
1692         done
1693
1694         for k in $(seq $OSTCOUNT); do
1695                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
1696                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1697                                 awk '/^status/ { print $2 }')
1698                 [ "$cur_status" == "completed" ] ||
1699                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
1700         done
1701
1702         local repaired=$(do_facet mds1 $LCTL get_param -n \
1703                          mdd.$(facet_svc mds1).lfsck_layout |
1704                          awk '/^repaired_orphan/ { print $2 }')
1705         [ $repaired -eq 1 ] ||
1706         error "(4.1) Expect 1 fixed on mds1, but got: $repaired"
1707
1708         if [ $MDSCOUNT -ge 2 ]; then
1709                 repaired=$(do_facet mds2 $LCTL get_param -n \
1710                          mdd.$(facet_svc mds2).lfsck_layout |
1711                          awk '/^repaired_orphan/ { print $2 }')
1712                 [ $repaired -eq 2 ] ||
1713                 error "(4.2) Expect 2 fixed on mds2, but got: $repaired"
1714         fi
1715
1716         echo "Move the files from ./lustre/lost+found/MDTxxxx to namespace"
1717         mv $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0 $DIR/$tdir/a1/f1 ||
1718         error "(5) Fail to move $MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
1719
1720         if [ $MDSCOUNT -ge 2 ]; then
1721                 local name=$MOUNT/.lustre/lost+found/MDT0001/${fid2}-R-0
1722                 mv $name $DIR/$tdir/a2/f2 || error "(6) Fail to move $name"
1723         fi
1724
1725         $LFS path2fid $DIR/$tdir/a1/f1
1726         $LFS getstripe $DIR/$tdir/a1/f1
1727
1728         if [ $MDSCOUNT -ge 2 ]; then
1729                 $LFS path2fid $DIR/$tdir/a2/f2
1730                 $LFS getstripe $DIR/$tdir/a2/f2
1731         fi
1732
1733         echo "The file size should be correct after layout LFSCK scanning"
1734         local cur_size=$(ls -il $DIR/$tdir/a1/f1 | awk '{ print $6 }')
1735         [ "$cur_size" == "$saved_size" ] ||
1736                 error "(7) Expect file1 size $saved_size, but got $cur_size"
1737
1738         if [ $MDSCOUNT -ge 2 ]; then
1739                 cur_size=$(ls -il $DIR/$tdir/a2/f2 | awk '{ print $6 }')
1740                 [ "$cur_size" == "$saved_size" ] ||
1741                 error "(8) Expect file2 size $saved_size, but got $cur_size"
1742         fi
1743 }
1744 run_test 18b "Find out orphan OST-object and repair it (2)"
1745
1746 test_18c() {
1747         echo "#####"
1748         echo "The target MDT-object is lost, and the OST-object FID is missing."
1749         echo "The LFSCK should re-create the MDT-object with new FID under the "
1750         echo "directory .lustre/lost+found/MDTxxxx."
1751         echo "#####"
1752
1753         check_mount_and_prep
1754         $LFS mkdir -i 0 $DIR/$tdir/a1
1755         $LFS setstripe -c 1 -i 0 -s 1M $DIR/$tdir/a1
1756
1757         echo "Inject failure, to simulate the case of missing parent FID"
1758         #define OBD_FAIL_LFSCK_NOPFID           0x1617
1759         do_facet ost1 $LCTL set_param fail_loc=0x1617
1760
1761         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=1M count=2
1762         $LFS getstripe $DIR/$tdir/a1/f1
1763
1764         if [ $MDSCOUNT -ge 2 ]; then
1765                 $LFS mkdir -i 1 $DIR/$tdir/a2
1766                 $LFS setstripe -c 1 -i 0 -s 1M $DIR/$tdir/a2
1767                 dd if=/dev/zero of=$DIR/$tdir/a2/f2 bs=1M count=2
1768                 $LFS getstripe $DIR/$tdir/a2/f2
1769         fi
1770
1771         cancel_lru_locks osc
1772
1773         echo "Inject failure, to simulate the case of missing the MDT-object"
1774         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
1775         do_facet mds1 $LCTL set_param fail_loc=0x1616
1776         rm -f $DIR/$tdir/a1/f1
1777
1778         if [ $MDSCOUNT -ge 2 ]; then
1779                 do_facet mds2 $LCTL set_param fail_loc=0x1616
1780                 rm -f $DIR/$tdir/a2/f2
1781         fi
1782
1783         sync
1784         sleep 2
1785
1786         do_facet mds1 $LCTL set_param fail_loc=0
1787         if [ $MDSCOUNT -ge 2 ]; then
1788                 do_facet mds2 $LCTL set_param fail_loc=0
1789         fi
1790
1791         cancel_lru_locks mdc
1792         cancel_lru_locks osc
1793
1794         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1795         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
1796
1797         for k in $(seq $MDSCOUNT); do
1798                 # The LFSCK status query internal is 30 seconds. For the case
1799                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1800                 # time to guarantee the status sync up.
1801                 wait_update_facet mds${k} "$LCTL get_param -n \
1802                         mdd.$(facet_svc mds${k}).lfsck_layout |
1803                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
1804                         error "(2) MDS${k} is not the expected 'completed'"
1805         done
1806
1807         for k in $(seq $OSTCOUNT); do
1808                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
1809                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1810                                 awk '/^status/ { print $2 }')
1811                 [ "$cur_status" == "completed" ] ||
1812                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
1813         done
1814
1815         if [ $MDSCOUNT -ge 2 ]; then
1816                 expected=2
1817         else
1818                 expected=1
1819         fi
1820
1821         local repaired=$(do_facet mds1 $LCTL get_param -n \
1822                          mdd.$(facet_svc mds1).lfsck_layout |
1823                          awk '/^repaired_orphan/ { print $2 }')
1824         [ $repaired -eq $expected ] ||
1825                 error "(4) Expect $expected fixed on mds1, but got: $repaired"
1826
1827         if [ $MDSCOUNT -ge 2 ]; then
1828                 repaired=$(do_facet mds2 $LCTL get_param -n \
1829                            mdd.$(facet_svc mds2).lfsck_layout |
1830                            awk '/^repaired_orphan/ { print $2 }')
1831                 [ $repaired -eq 0 ] ||
1832                         error "(5) Expect 0 fixed on mds2, but got: $repaired"
1833         fi
1834
1835         echo "There should NOT be some stub under .lustre/lost+found/MDT0001/"
1836         ls -ail $MOUNT/.lustre/lost+found/MDT0001/*-N-0 &&
1837                 error "(6) .lustre/lost+found/MDT0001/ should be empty"
1838
1839         echo "There should be some stub under .lustre/lost+found/MDT0000/"
1840         ls -ail $MOUNT/.lustre/lost+found/MDT0000/*-N-0 ||
1841                 error "(7) .lustre/lost+found/MDT0000/ should not be empty"
1842 }
1843 run_test 18c "Find out orphan OST-object and repair it (3)"
1844
1845 test_18d() {
1846         echo "#####"
1847         echo "The target MDT-object layout EA slot is occpuied by some new"
1848         echo "created OST-object when repair dangling reference case. Such"
1849         echo "conflict OST-object has never been modified. Then when found"
1850         echo "the orphan OST-object, LFSCK will replace it with the orphan"
1851         echo "OST-object."
1852         echo "#####"
1853
1854         check_mount_and_prep
1855         mkdir $DIR/$tdir/a1
1856         $LFS setstripe -c 1 -i 0 -s 1M $DIR/$tdir/a1
1857         echo "guard" > $DIR/$tdir/a1/f1
1858         echo "foo" > $DIR/$tdir/a1/f2
1859         local saved_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
1860         $LFS path2fid $DIR/$tdir/a1/f1
1861         $LFS getstripe $DIR/$tdir/a1/f1
1862         $LFS path2fid $DIR/$tdir/a1/f2
1863         $LFS getstripe $DIR/$tdir/a1/f2
1864         cancel_lru_locks osc
1865
1866         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
1867         echo "to reference the same OST-object (which is f1's OST-obejct)."
1868         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
1869         echo "dangling reference case, but f2's old OST-object is there."
1870         echo
1871
1872         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
1873         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
1874         chown 1.1 $DIR/$tdir/a1/f2
1875         rm -f $DIR/$tdir/a1/f1
1876         sync
1877         sleep 2
1878         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1879
1880         echo "stopall to cleanup object cache"
1881         stopall > /dev/null
1882         echo "setupall"
1883         setupall > /dev/null
1884
1885         echo "The file size should be incorrect since dangling referenced"
1886         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
1887         [ "$cur_size" != "$saved_size" ] ||
1888                 error "(1) Expect incorrect file2 size"
1889
1890         #define OBD_FAIL_LFSCK_DELAY3           0x1602
1891         do_facet $SINGLEMDS $LCTL set_param fail_val=5 fail_loc=0x1602
1892
1893         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1894         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
1895
1896         wait_update_facet mds1 "$LCTL get_param -n \
1897                 mdd.$(facet_svc mds1).lfsck_layout |
1898                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 6 ||
1899                 error "(3.0) MDS1 is not the expected 'scanning-phase2'"
1900
1901         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
1902
1903         for k in $(seq $MDSCOUNT); do
1904                 # The LFSCK status query internal is 30 seconds. For the case
1905                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
1906                 # time to guarantee the status sync up.
1907                 wait_update_facet mds${k} "$LCTL get_param -n \
1908                         mdd.$(facet_svc mds${k}).lfsck_layout |
1909                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
1910                         error "(3) MDS${k} is not the expected 'completed'"
1911         done
1912
1913         for k in $(seq $OSTCOUNT); do
1914                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
1915                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
1916                                 awk '/^status/ { print $2 }')
1917                 [ "$cur_status" == "completed" ] ||
1918                 error "(4) OST${k} Expect 'completed', but got '$cur_status'"
1919         done
1920
1921         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
1922                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
1923                          awk '/^repaired_orphan/ { print $2 }')
1924         [ $repaired -eq 1 ] ||
1925                 error "(5) Expect 1 orphan has been fixed, but got: $repaired"
1926
1927         echo "The file size should be correct after layout LFSCK scanning"
1928         cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
1929         [ "$cur_size" == "$saved_size" ] ||
1930                 error "(6) Expect file2 size $saved_size, but got $cur_size"
1931
1932         echo "The LFSCK should find back the original data."
1933         cat $DIR/$tdir/a1/f2
1934         $LFS path2fid $DIR/$tdir/a1/f2
1935         $LFS getstripe $DIR/$tdir/a1/f2
1936 }
1937 run_test 18d "Find out orphan OST-object and repair it (4)"
1938
1939 test_18e() {
1940         echo "#####"
1941         echo "The target MDT-object layout EA slot is occpuied by some new"
1942         echo "created OST-object when repair dangling reference case. Such"
1943         echo "conflict OST-object has been modified by others. To keep the"
1944         echo "new data, the LFSCK will create a new file to refernece this"
1945         echo "old orphan OST-object."
1946         echo "#####"
1947
1948         check_mount_and_prep
1949         mkdir $DIR/$tdir/a1
1950         $LFS setstripe -c 1 -i 0 -s 1M $DIR/$tdir/a1
1951         echo "guard" > $DIR/$tdir/a1/f1
1952         echo "foo" > $DIR/$tdir/a1/f2
1953         local saved_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
1954         $LFS path2fid $DIR/$tdir/a1/f1
1955         $LFS getstripe $DIR/$tdir/a1/f1
1956         $LFS path2fid $DIR/$tdir/a1/f2
1957         $LFS getstripe $DIR/$tdir/a1/f2
1958         cancel_lru_locks osc
1959
1960         echo "Inject failure to make $DIR/$tdir/a1/f1 and $DIR/$tdir/a1/f2"
1961         echo "to reference the same OST-object (which is f1's OST-obejct)."
1962         echo "Then drop $DIR/$tdir/a1/f1 and its OST-object, so f2 becomes"
1963         echo "dangling reference case, but f2's old OST-object is there."
1964         echo
1965
1966         #define OBD_FAIL_LFSCK_CHANGE_STRIPE    0x1618
1967         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1618
1968         chown 1.1 $DIR/$tdir/a1/f2
1969         rm -f $DIR/$tdir/a1/f1
1970         sync
1971         sleep 2
1972         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
1973
1974         echo "stopall to cleanup object cache"
1975         stopall > /dev/null
1976         echo "setupall"
1977         setupall > /dev/null
1978
1979         echo "The file size should be incorrect since dangling referenced"
1980         local cur_size=$(ls -il $DIR/$tdir/a1/f2 | awk '{ print $6 }')
1981         [ "$cur_size" != "$saved_size" ] ||
1982                 error "(1) Expect incorrect file2 size"
1983
1984         #define OBD_FAIL_LFSCK_DELAY3           0x1602
1985         do_facet $SINGLEMDS $LCTL set_param fail_val=10 fail_loc=0x1602
1986
1987         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
1988         $START_LAYOUT -r -o -c || error "(2) Fail to start LFSCK for layout!"
1989
1990         wait_update_facet mds1 "$LCTL get_param -n \
1991                 mdd.$(facet_svc mds1).lfsck_layout |
1992                 awk '/^status/ { print \\\$2 }'" "scanning-phase2" 6 ||
1993                 error "(3) MDS1 is not the expected 'scanning-phase2'"
1994
1995         # to guarantee all updates are synced.
1996         sync
1997         sleep 2
1998
1999         echo "Write new data to f2 to modify the new created OST-object."
2000         echo "dummy" >> $DIR/$tdir/a1/f2
2001
2002         do_facet $SINGLEMDS $LCTL set_param fail_val=0 fail_loc=0
2003
2004         for k in $(seq $MDSCOUNT); do
2005                 # The LFSCK status query internal is 30 seconds. For the case
2006                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2007                 # time to guarantee the status sync up.
2008                 wait_update_facet mds${k} "$LCTL get_param -n \
2009                         mdd.$(facet_svc mds${k}).lfsck_layout |
2010                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
2011                         error "(4) MDS${k} is not the expected 'completed'"
2012         done
2013
2014         for k in $(seq $OSTCOUNT); do
2015                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2016                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2017                                 awk '/^status/ { print $2 }')
2018                 [ "$cur_status" == "completed" ] ||
2019                 error "(5) OST${k} Expect 'completed', but got '$cur_status'"
2020         done
2021
2022         local repaired=$(do_facet $SINGLEMDS $LCTL get_param -n \
2023                          mdd.$(facet_svc $SINGLEMDS).lfsck_layout |
2024                          awk '/^repaired_orphan/ { print $2 }')
2025         [ $repaired -eq 1 ] ||
2026                 error "(6) Expect 1 orphan has been fixed, but got: $repaired"
2027
2028         echo "There should be stub file under .lustre/lost+found/MDT0000/"
2029         local cname=$(ls $MOUNT/.lustre/lost+found/MDT0000/*-C-0)
2030         [ ! -z $name ] ||
2031                 error "(7) .lustre/lost+found/MDT0000/ should not be empty"
2032
2033         echo "The stub file should keep the original f2 data"
2034         cur_size=$(ls -il $cname | awk '{ print $6 }')
2035         [ "$cur_size" == "$saved_size" ] ||
2036                 error "(8) Expect file2 size $saved_size, but got $cur_size"
2037
2038         cat $cname
2039         $LFS path2fid $cname
2040         $LFS getstripe $cname
2041
2042         echo "The f2 should contains new data."
2043         cat $DIR/$tdir/a1/f2
2044         $LFS path2fid $DIR/$tdir/a1/f2
2045         $LFS getstripe $DIR/$tdir/a1/f2
2046 }
2047 run_test 18e "Find out orphan OST-object and repair it (5)"
2048
2049 test_19a() {
2050         check_mount_and_prep
2051         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2052
2053         echo "foo" > $DIR/$tdir/a0
2054         echo "guard" > $DIR/$tdir/a1
2055         cancel_lru_locks osc
2056
2057         echo "Inject failure, then client will offer wrong parent FID when read"
2058         do_facet ost1 $LCTL set_param -n \
2059                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2060         #define OBD_FAIL_LFSCK_INVALID_PFID     0x1619
2061         $LCTL set_param fail_loc=0x1619
2062
2063         echo "Read RPC with wrong parent FID should be denied"
2064         cat $DIR/$tdir/a0 && error "(3) Read should be denied!"
2065         $LCTL set_param fail_loc=0
2066 }
2067 run_test 19a "OST-object inconsistency self detect"
2068
2069 test_19b() {
2070         check_mount_and_prep
2071         $LFS setstripe -c 1 -i 0 $DIR/$tdir
2072
2073         echo "Inject failure stub to make the OST-object to back point to"
2074         echo "non-exist MDT-object"
2075
2076         #define OBD_FAIL_LFSCK_UNMATCHED_PAIR1  0x1611
2077         do_facet ost1 $LCTL set_param fail_loc=0x1611
2078         echo "foo" > $DIR/$tdir/f0
2079         cancel_lru_locks osc
2080         do_facet ost1 $LCTL set_param fail_loc=0
2081
2082         echo "Nothing should be fixed since self detect and repair is disabled"
2083         local repaired=$(do_facet ost1 $LCTL get_param -n \
2084                         obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2085                         awk '/^repaired/ { print $2 }')
2086         [ $repaired -eq 0 ] ||
2087                 error "(1) Expected 0 repaired, but got $repaired"
2088
2089         echo "Read RPC with right parent FID should be accepted,"
2090         echo "and cause parent FID on OST to be fixed"
2091
2092         do_facet ost1 $LCTL set_param -n \
2093                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid 1
2094         cat $DIR/$tdir/f0 || error "(2) Read should not be denied!"
2095
2096         repaired=$(do_facet ost1 $LCTL get_param -n \
2097                 obdfilter.${FSNAME}-OST0000.lfsck_verify_pfid |
2098                 awk '/^repaired/ { print $2 }')
2099         [ $repaired -eq 1 ] ||
2100                 error "(3) Expected 1 repaired, but got $repaired"
2101 }
2102 run_test 19b "OST-object inconsistency self repair"
2103
2104 test_20() {
2105         [ $OSTCOUNT -lt 2 ] &&
2106                 skip "The test needs at least 2 OSTs" && return
2107
2108         echo "#####"
2109         echo "The target MDT-object and some of its OST-object are lost."
2110         echo "The LFSCK should find out the left OST-objects and re-create"
2111         echo "the MDT-object under the direcotry .lustre/lost+found/MDTxxxx/"
2112         echo "with the partial OST-objects (LOV EA hole)."
2113
2114         echo "New client can access the file with LOV EA hole via normal"
2115         echo "system tools or commands without crash the system."
2116
2117         echo "For old client, even though it cannot access the file with"
2118         echo "LOV EA hole, it should not cause the system crash."
2119         echo "#####"
2120
2121         check_mount_and_prep
2122         $LFS mkdir -i 0 $DIR/$tdir/a1
2123         if [ $OSTCOUNT -gt 2 ]; then
2124                 $LFS setstripe -c 3 -i 0 -s 1M $DIR/$tdir/a1
2125                 bcount=513
2126         else
2127                 $LFS setstripe -c 2 -i 0 -s 1M $DIR/$tdir/a1
2128                 bcount=257
2129         fi
2130
2131         # 256 blocks on the stripe0.
2132         # 1 block on the stripe1 for 2 OSTs case.
2133         # 256 blocks on the stripe1 for other cases.
2134         # 1 block on the stripe2 if OSTs > 2
2135         dd if=/dev/zero of=$DIR/$tdir/a1/f0 bs=4096 count=$bcount
2136         dd if=/dev/zero of=$DIR/$tdir/a1/f1 bs=4096 count=$bcount
2137         dd if=/dev/zero of=$DIR/$tdir/a1/f2 bs=4096 count=$bcount
2138
2139         local fid0=$($LFS path2fid $DIR/$tdir/a1/f0)
2140         local fid1=$($LFS path2fid $DIR/$tdir/a1/f1)
2141         local fid2=$($LFS path2fid $DIR/$tdir/a1/f2)
2142
2143         echo ${fid0}
2144         $LFS getstripe $DIR/$tdir/a1/f0
2145         echo ${fid1}
2146         $LFS getstripe $DIR/$tdir/a1/f1
2147         echo ${fid2}
2148         $LFS getstripe $DIR/$tdir/a1/f2
2149
2150         if [ $OSTCOUNT -gt 2 ]; then
2151                 dd if=/dev/zero of=$DIR/$tdir/a1/f3 bs=4096 count=$bcount
2152                 fid3=$($LFS path2fid $DIR/$tdir/a1/f3)
2153                 echo ${fid3}
2154                 $LFS getstripe $DIR/$tdir/a1/f3
2155         fi
2156
2157         cancel_lru_locks osc
2158
2159         echo "Inject failure..."
2160         echo "To simulate f0 lost MDT-object"
2161         #define OBD_FAIL_LFSCK_LOST_MDTOBJ      0x1616
2162         do_facet mds1 $LCTL set_param fail_loc=0x1616
2163         rm -f $DIR/$tdir/a1/f0
2164
2165         echo "To simulate f1 lost MDT-object and OST-object0"
2166         #define OBD_FAIL_LFSCK_LOST_SPEOBJ      0x161a
2167         do_facet mds1 $LCTL set_param fail_loc=0x161a
2168         rm -f $DIR/$tdir/a1/f1
2169
2170         echo "To simulate f2 lost MDT-object and OST-object1"
2171         do_facet mds1 $LCTL set_param fail_val=1
2172         rm -f $DIR/$tdir/a1/f2
2173
2174         if [ $OSTCOUNT -gt 2 ]; then
2175                 echo "To simulate f3 lost MDT-object and OST-object2"
2176                 do_facet mds1 $LCTL set_param fail_val=2
2177                 rm -f $DIR/$tdir/a1/f3
2178         fi
2179
2180         umount_client $MOUNT
2181         sync
2182         sleep 2
2183         do_facet mds1 $LCTL set_param fail_loc=0 fail_val=0
2184
2185         echo "Inject failure to slow down the LFSCK on OST0"
2186         #define OBD_FAIL_LFSCK_DELAY5           0x161b
2187         do_facet ost1 $LCTL set_param fail_loc=0x161b
2188
2189         echo "Trigger layout LFSCK on all devices to find out orphan OST-object"
2190         $START_LAYOUT -r -o || error "(1) Fail to start LFSCK for layout!"
2191
2192         sleep 3
2193         do_facet ost1 $LCTL set_param fail_loc=0
2194
2195         for k in $(seq $MDSCOUNT); do
2196                 # The LFSCK status query internal is 30 seconds. For the case
2197                 # of some LFSCK_NOTIFY RPCs failure/lost, we will wait enough
2198                 # time to guarantee the status sync up.
2199                 wait_update_facet mds${k} "$LCTL get_param -n \
2200                         mdd.$(facet_svc mds${k}).lfsck_layout |
2201                         awk '/^status/ { print \\\$2 }'" "completed" 32 ||
2202                         error "(2) MDS${k} is not the expected 'completed'"
2203         done
2204
2205         for k in $(seq $OSTCOUNT); do
2206                 local cur_status=$(do_facet ost${k} $LCTL get_param -n \
2207                                 obdfilter.$(facet_svc ost${k}).lfsck_layout |
2208                                 awk '/^status/ { print $2 }')
2209                 [ "$cur_status" == "completed" ] ||
2210                 error "(3) OST${k} Expect 'completed', but got '$cur_status'"
2211         done
2212
2213         local repaired=$(do_facet mds1 $LCTL get_param -n \
2214                          mdd.$(facet_svc mds1).lfsck_layout |
2215                          awk '/^repaired_orphan/ { print $2 }')
2216         if [ $OSTCOUNT -gt 2 ]; then
2217                 [ $repaired -eq 9 ] ||
2218                         error "(4.1) Expect 9 fixed on mds1, but got: $repaired"
2219         else
2220                 [ $repaired -eq 4 ] ||
2221                         error "(4.2) Expect 4 fixed on mds1, but got: $repaired"
2222         fi
2223
2224         mount_client $MOUNT || error "(5.0) Fail to start client!"
2225
2226         LOV_PATTERN_F_HOLE=0x40000000
2227
2228         #
2229         # ${fid0}-R-0 is the old f0
2230         #
2231         local name="$MOUNT/.lustre/lost+found/MDT0000/${fid0}-R-0"
2232         echo "Check $name, which is the old f0"
2233
2234         $LFS getstripe -v $name || error "(5.1) cannot getstripe on $name"
2235
2236         local pattern=0x$($LFS getstripe -L $name)
2237         [[ $((pattern & LOV_PATTERN_F_HOLE)) -eq 0 ]] ||
2238                 error "(5.2) NOT expect pattern flag hole, but got $pattern"
2239
2240         local stripes=$($LFS getstripe -c $name)
2241         if [ $OSTCOUNT -gt 2 ]; then
2242                 [ $stripes -eq 3 ] ||
2243                 error "(5.3.1) expect the stripe count is 3, but got $stripes"
2244         else
2245                 [ $stripes -eq 2 ] ||
2246                 error "(5.3.2) expect the stripe count is 2, but got $stripes"
2247         fi
2248
2249         local size=$(stat $name | awk '/Size:/ { print $2 }')
2250         [ $size -eq $((4096 * $bcount)) ] ||
2251                 error "(5.4) expect the size $((4096 * $bcount)), but got $size"
2252
2253         cat $name > /dev/null || error "(5.5) cannot read $name"
2254
2255         echo "dummy" >> $name || error "(5.6) cannot write $name"
2256
2257         chown $RUNAS_ID:$RUNAS_GID $name || error "(5.7) cannot chown on $name"
2258
2259         touch $name || error "(5.8) cannot touch $name"
2260
2261         rm -f $name || error "(5.9) cannot unlink $name"
2262
2263         #
2264         # ${fid1}-R-0 contains the old f1's stripe1 (and stripe2 if OSTs > 2)
2265         #
2266         name="$MOUNT/.lustre/lost+found/MDT0000/${fid1}-R-0"
2267         if [ $OSTCOUNT -gt 2 ]; then
2268                 echo "Check $name, it contains the old f1's stripe1 and stripe2"
2269         else
2270                 echo "Check $name, it contains the old f1's stripe1"
2271         fi
2272
2273         $LFS getstripe -v $name || error "(6.1) cannot getstripe on $name"
2274
2275         pattern=0x$($LFS getstripe -L $name)
2276         [[ $((pattern & LOV_PATTERN_F_HOLE)) -ne 0 ]] ||
2277                 error "(6.2) expect pattern flag hole, but got $pattern"
2278
2279         stripes=$($LFS getstripe -c $name)
2280         if [ $OSTCOUNT -gt 2 ]; then
2281                 [ $stripes -eq 3 ] ||
2282                 error "(6.3.1) expect the stripe count is 3, but got $stripes"
2283         else
2284                 [ $stripes -eq 2 ] ||
2285                 error "(6.3.2) expect the stripe count is 2, but got $stripes"
2286         fi
2287
2288         size=$(stat $name | awk '/Size:/ { print $2 }')
2289         [ $size -eq $((4096 * $bcount)) ] ||
2290                 error "(6.4) expect the size $((4096 * $bcount)), but got $size"
2291
2292         cat $name > /dev/null && error "(6.5) normal read $name should fail"
2293
2294         local failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
2295                          bs=4096 2>&1 | grep "Input/output error" | wc -l)
2296
2297         # stripe0 is dummy
2298         [ $failures -eq 256 ] ||
2299                 error "(6.6) expect 256 IO failures, but get $failures"
2300
2301         size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
2302         [ $size -eq $((4096 * $bcount)) ] ||
2303                 error "(6.7) expect the size $((4096 * $bcount)), but got $size"
2304
2305         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 &&
2306                 error "(6.8) write to the LOV EA hole should fail"
2307
2308         dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 seek=300 ||
2309                 error "(6.9) write to normal stripe should NOT fail"
2310
2311         echo "foo" >> $name && error "(6.10) append write $name should fail"
2312
2313         chown $RUNAS_ID:$RUNAS_GID $name || error "(6.11) cannot chown on $name"
2314
2315         touch $name || error "(6.12) cannot touch $name"
2316
2317         rm -f $name || error "(6.13) cannot unlink $name"
2318
2319         #
2320         # ${fid2}-R-0 it contains the old f2's stripe0 (and stripe2 if OSTs > 2)
2321         #
2322         name="$MOUNT/.lustre/lost+found/MDT0000/${fid2}-R-0"
2323         if [ $OSTCOUNT -gt 2 ]; then
2324                 echo "Check $name, it contains the old f2's stripe0 and stripe2"
2325         else
2326                 echo "Check $name, it contains the old f2's stripe0"
2327         fi
2328
2329         $LFS getstripe -v $name || error "(7.1) cannot getstripe on $name"
2330
2331         pattern=0x$($LFS getstripe -L $name)
2332         stripes=$($LFS getstripe -c $name)
2333         size=$(stat $name | awk '/Size:/ { print $2 }')
2334         if [ $OSTCOUNT -gt 2 ]; then
2335                 [[ $((pattern & LOV_PATTERN_F_HOLE)) -ne 0 ]] ||
2336                 error "(7.2.1) expect pattern flag hole, but got $pattern"
2337
2338                 [ $stripes -eq 3 ] ||
2339                 error "(7.3.1) expect the stripe count is 3, but got $stripes"
2340
2341                 [ $size -eq $((4096 * $bcount)) ] ||
2342                 error "(7.4.1) expect size $((4096 * $bcount)), but got $size"
2343
2344                 cat $name > /dev/null &&
2345                         error "(7.5.1) normal read $name should fail"
2346
2347                 failures=$(dd if=$name of=$DIR/$tdir/dump conv=sync,noerror \
2348                            bs=4096 2>&1 | grep "Input/output error" | wc -l)
2349                 # stripe1 is dummy
2350                 [ $failures -eq 256 ] ||
2351                         error "(7.6) expect 256 IO failures, but get $failures"
2352
2353                 size=$(stat $DIR/$tdir/dump | awk '/Size:/ { print $2 }')
2354                 [ $size -eq $((4096 * $bcount)) ] ||
2355                 error "(7.7) expect the size $((4096 * $bcount)), but got $size"
2356
2357                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 \
2358                 seek=300 && error "(7.8.0) write to the LOV EA hole should fail"
2359
2360                 dd if=/dev/zero of=$name conv=sync,notrunc bs=4096 count=1 ||
2361                 error "(7.8.1) write to normal stripe should NOT fail"
2362
2363                 echo "foo" >> $name &&
2364                         error "(7.8.3) append write $name should fail"
2365
2366                 chown $RUNAS_ID:$RUNAS_GID $name ||
2367                         error "(7.9.1) cannot chown on $name"
2368
2369                 touch $name || error "(7.10.1) cannot touch $name"
2370         else
2371                 [[ $((pattern & LOV_PATTERN_F_HOLE)) -eq 0 ]] ||
2372                 error "(7.2.2) NOT expect pattern flag hole, but got $pattern"
2373
2374                 [ $stripes -eq 1 ] ||
2375                 error "(7.3.2) expect the stripe count is 1, but got $stripes"
2376
2377                 # stripe1 is dummy
2378                 [ $size -eq $((4096 * (256 + 0))) ] ||
2379                 error "(7.4.2) expect the size $((4096 * 256)), but got $size"
2380
2381                 cat $name > /dev/null || error "(7.5.2) cannot read $name"
2382
2383                 echo "dummy" >> $name || error "(7.8.2) cannot write $name"
2384
2385                 chown $RUNAS_ID:$RUNAS_GID $name ||
2386                         error "(7.9.2) cannot chown on $name"
2387
2388                 touch $name || error "(7.10.2) cannot touch $name"
2389         fi
2390
2391         rm -f $name || error "(7.11) cannot unlink $name"
2392
2393         [ $OSTCOUNT -le 2 ] && return
2394
2395         #
2396         # ${fid3}-R-0 should contains the old f3's stripe0 and stripe1
2397         #
2398         name="$MOUNT/.lustre/lost+found/MDT0000/${fid3}-R-0"
2399         echo "Check $name, which contains the old f3's stripe0 and stripe1"
2400
2401         $LFS getstripe -v $name || error "(8.1) cannot getstripe on $name"
2402
2403         pattern=0x$($LFS getstripe -L $name)
2404         [[ $((pattern & LOV_PATTERN_F_HOLE)) -eq 0 ]] ||
2405                 error "(8.2) NOT expect pattern flag hole, but got $pattern"
2406
2407         stripes=$($LFS getstripe -c $name)
2408         # LFSCK does not know the old f3 had 3 stripes.
2409         # It only tries to find as much as possible.
2410         # The stripe count depends on the last stripe's offset.
2411         [ $stripes -eq 2 ] ||
2412                 error "(8.3) expect the stripe count is 2, but got $stripes"
2413
2414         size=$(stat $name | awk '/Size:/ { print $2 }')
2415         # stripe2 is lost
2416         [ $size -eq $((4096 * (256 + 256 + 0))) ] ||
2417                 error "(8.4) expect the size $((4096 * 512)), but got $size"
2418
2419         cat $name > /dev/null || error "(8.5) cannot read $name"
2420
2421         echo "dummy" >> $name || error "(8.6) cannot write $name"
2422
2423         chown $RUNAS_ID:$RUNAS_GID $name ||
2424                 error "(8.7) cannot chown on $name"
2425
2426         touch $name || error "(8.8) cannot touch $name"
2427
2428         rm -f $name || error "(8.9) cannot unlink $name"
2429 }
2430 run_test 20 "Handle the orphan with dummy LOV EA slot properly"
2431
2432 test_21() {
2433         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.5.59) ]] &&
2434                 skip "ignore the test if MDS is older than 2.5.59" && exit 0
2435
2436         check_mount_and_prep
2437         createmany -o $DIR/$tdir/f 100 || error "(0) Fail to create 100 files"
2438
2439         echo "Start all LFSCK components by default (-s 1)"
2440         do_facet mds1 $LCTL lfsck_start -M ${FSNAME}-MDT0000 -s 1 -r ||
2441                 error "Fail to start LFSCK"
2442
2443         echo "namespace LFSCK should be in 'scanning-phase1' status"
2444         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
2445         [ "$STATUS" == "scanning-phase1" ] ||
2446                 error "Expect namespace 'scanning-phase1', but got '$STATUS'"
2447
2448         echo "layout LFSCK should be in 'scanning-phase1' status"
2449         STATUS=$($SHOW_LAYOUT | awk '/^status/ { print $2 }')
2450         [ "$STATUS" == "scanning-phase1" ] ||
2451                 error "Expect layout 'scanning-phase1', but got '$STATUS'"
2452
2453         echo "Stop all LFSCK components by default"
2454         do_facet mds1 $LCTL lfsck_stop -M ${FSNAME}-MDT0000 ||
2455                 error "Fail to stop LFSCK"
2456 }
2457 run_test 21 "run all LFSCK components by default"
2458
2459 $LCTL set_param debug=-lfsck > /dev/null || true
2460
2461 # restore MDS/OST size
2462 MDSSIZE=${SAVED_MDSSIZE}
2463 OSTSIZE=${SAVED_OSTSIZE}
2464 OSTCOUNT=${SAVED_OSTCOUNT}
2465
2466 # cleanup the system at last
2467 formatall
2468
2469 complete $SECONDS
2470 exit_status