Whamcloud - gitweb
LU-2914 lfsck: split LFSCK code from mdd to lfsck
[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 [ $(facet_fstype $SINGLEMDS) != ldiskfs ] &&
21         skip "test LFSCK only for ldiskfs" && exit 0
22 require_dsh_mds || exit 0
23
24 MCREATE=${MCREATE:-mcreate}
25 SAVED_MDSSIZE=${MDSSIZE}
26 SAVED_OSTSIZE=${OSTSIZE}
27 # use small MDS + OST size to speed formatting time
28 # do not use too small MDSSIZE/OSTSIZE, which affect the default journal size
29 MDSSIZE=100000
30 OSTSIZE=100000
31
32 check_and_setup_lustre
33
34 [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.2.90) ]] &&
35         skip "Need MDS version at least 2.2.90" && check_and_cleanup_lustre &&
36         exit 0
37
38 build_test_filter
39
40 $LCTL set_param debug=+lfsck > /dev/null || true
41
42 MDT_DEV="${FSNAME}-MDT0000"
43 MDT_DEVNAME=$(mdsdevname ${SINGLEMDS//mds/})
44 START_NAMESPACE="do_facet $SINGLEMDS \
45                 $LCTL lfsck_start -M ${MDT_DEV} -t namespace"
46 STOP_LFSCK="do_facet $SINGLEMDS $LCTL lfsck_stop -M ${MDT_DEV}"
47 SHOW_NAMESPACE="do_facet $SINGLEMDS \
48                 $LCTL get_param -n mdd.${MDT_DEV}.lfsck_namespace"
49 MOUNT_OPTS_SCRUB="-o user_xattr"
50 MOUNT_OPTS_NOSCRUB="-o user_xattr,noscrub"
51
52 lfsck_prep() {
53         local ndirs=$1
54         local nfiles=$2
55         local igif=$3
56
57         echo "formatall"
58         formatall > /dev/null
59
60         echo "setupall"
61         setupall > /dev/null
62
63         if [ ! -z $igif ]; then
64                 #define OBD_FAIL_FID_IGIF       0x1504
65                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
66         fi
67
68         echo "preparing... ${nfiles} * ${ndirs} files will be created."
69         mkdir -p $DIR/$tdir
70         cp $LUSTRE/tests/*.sh $DIR/
71         for ((i = 0; i < ${ndirs}; i++)); do
72                 mkdir $DIR/$tdir/d${i}
73                 touch $DIR/$tdir/f${i}
74                 for ((j = 0; j < ${nfiles}; j++)); do
75                         touch $DIR/$tdir/d${i}/f${j}
76                 done
77                 mkdir $DIR/$tdir/e${i}
78         done
79
80         if [ ! -z $igif ]; then
81                 touch $DIR/$tdir/dummy
82                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0
83         fi
84
85         echo "prepared."
86         cleanup_mount $MOUNT > /dev/null || error "Fail to stop client!"
87         echo "stop $SINGLEMDS"
88         stop $SINGLEMDS > /dev/null || error "Fail to stop MDS!"
89 }
90
91 test_0() {
92         lfsck_prep 10 10
93         echo "start $SINGLEMDS"
94         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
95                 error "(1) Fail to start MDS!"
96
97         #define OBD_FAIL_LFSCK_DELAY1           0x1600
98         do_facet $SINGLEMDS $LCTL set_param fail_val=3
99         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
100         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
101
102         $SHOW_NAMESPACE || error "Fail to monitor LFSCK (3)"
103
104         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
105         [ "$STATUS" == "scanning-phase1" ] ||
106                 error "(4) Expect 'scanning-phase1', but got '$STATUS'"
107
108         $STOP_LFSCK || error "(5) Fail to stop LFSCK!"
109
110         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
111         [ "$STATUS" == "stopped" ] ||
112                 error "(6) Expect 'stopped', but got '$STATUS'"
113
114         $START_NAMESPACE || error "(7) Fail to start LFSCK for namespace!"
115
116         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
117         [ "$STATUS" == "scanning-phase1" ] ||
118                 error "(8) Expect 'scanning-phase1', but got '$STATUS'"
119
120         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
121         do_facet $SINGLEMDS $LCTL set_param fail_val=0
122         sleep 3
123         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
124         [ "$STATUS" == "completed" ] ||
125                 error "(9) Expect 'completed', but got '$STATUS'"
126
127         local repaired=$($SHOW_NAMESPACE |
128                          awk '/^updated_phase1/ { print $2 }')
129         [ $repaired -eq 0 ] ||
130                 error "(10) Expect nothing to be repaired, but got: $repaired"
131 }
132 run_test 0 "Control LFSCK manually"
133
134 test_1a() {
135         lfsck_prep 1 1
136         echo "start $SINGLEMDS"
137         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
138                 error "(1) Fail to start MDS!"
139
140         mount_client $MOUNT || error "(2) Fail to start client!"
141
142         #define OBD_FAIL_FID_INDIR      0x1501
143         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1501
144         touch $DIR/$tdir/dummy
145
146         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
147         umount_client $MOUNT
148         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
149
150         sleep 3
151         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
152         [ "$STATUS" == "completed" ] ||
153                 error "(4) Expect 'completed', but got '$STATUS'"
154
155         local repaired=$($SHOW_NAMESPACE |
156                          awk '/^updated_phase1/ { print $2 }')
157         [ $repaired -eq 1 ] ||
158                 error "(5) Fail to repair crashed FID-in-dirent: $repaired"
159
160         mount_client $MOUNT || error "(6) Fail to start client!"
161
162         #define OBD_FAIL_FID_LOOKUP     0x1505
163         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
164         ls $DIR/$tdir/ > /dev/null || error "(7) no FID-in-dirent."
165
166         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
167 }
168 run_test 1a "LFSCK can find out and repair crashed FID-in-dirent"
169
170 test_1b()
171 {
172         lfsck_prep 1 1
173         echo "start $SINGLEMDS"
174         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
175                 error "(1) Fail to start MDS!"
176
177         mount_client $MOUNT || error "(2) Fail to start client!"
178
179         #define OBD_FAIL_FID_INLMA      0x1502
180         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1502
181         touch $DIR/$tdir/dummy
182
183         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
184         umount_client $MOUNT
185         #define OBD_FAIL_FID_NOLMA      0x1506
186         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1506
187         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
188
189         sleep 3
190         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
191         [ "$STATUS" == "completed" ] ||
192                 error "(4) Expect 'completed', but got '$STATUS'"
193
194         local repaired=$($SHOW_NAMESPACE |
195                          awk '/^updated_phase1/ { print $2 }')
196         [ $repaired -eq 1 ] ||
197                 error "(5) Fail to repair missed FID-in-LMA: $repaired"
198
199         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
200         mount_client $MOUNT || error "(6) Fail to start client!"
201
202         #define OBD_FAIL_FID_LOOKUP     0x1505
203         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
204         stat $DIR/$tdir/dummy > /dev/null || error "(7) no FID-in-LMA."
205
206         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
207 }
208 run_test 1b "LFSCK can find out and repair missed FID-in-LMA"
209
210 test_2a() {
211         lfsck_prep 1 1
212         echo "start $SINGLEMDS"
213         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
214                 error "(1) Fail to start MDS!"
215
216         mount_client $MOUNT || error "(2) Fail to start client!"
217
218         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
219         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
220         touch $DIR/$tdir/dummy
221
222         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
223         umount_client $MOUNT
224         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
225
226         sleep 3
227         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
228         [ "$STATUS" == "completed" ] ||
229                 error "(4) Expect 'completed', but got '$STATUS'"
230
231         local repaired=$($SHOW_NAMESPACE |
232                          awk '/^updated_phase1/ { print $2 }')
233         [ $repaired -eq 1 ] ||
234                 error "(5) Fail to repair crashed linkEA: $repaired"
235
236         mount_client $MOUNT || error "(6) Fail to start client!"
237
238         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
239                 error "(7) Fail to stat $DIR/$tdir/dummy"
240
241         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
242         local dummyname=$($LFS fid2path $DIR $dummyfid)
243         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
244                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
245 }
246 run_test 2a "LFSCK can find out and repair crashed linkEA entry"
247
248 test_2b()
249 {
250         lfsck_prep 1 1
251         echo "start $SINGLEMDS"
252         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
253                 error "(1) Fail to start MDS!"
254
255         mount_client $MOUNT || error "(2) Fail to start client!"
256
257         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
258         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
259         touch $DIR/$tdir/dummy
260
261         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
262         umount_client $MOUNT
263         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
264
265         sleep 3
266         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
267         [ "$STATUS" == "completed" ] ||
268                 error "(4) Expect 'completed', but got '$STATUS'"
269
270         local repaired=$($SHOW_NAMESPACE |
271                          awk '/^updated_phase2/ { print $2 }')
272         [ $repaired -eq 1 ] ||
273                 error "(5) Fail to repair crashed linkEA: $repaired"
274
275         mount_client $MOUNT || error "(6) Fail to start client!"
276
277         stat $DIR/$tdir/dummy | grep "Links: 1" > /dev/null ||
278                 error "(7) Fail to stat $DIR/$tdir/dummy"
279
280         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
281         local dummyname=$($LFS fid2path $DIR $dummyfid)
282         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
283                 error "(8) Fail to repair linkEA: $dummyfid $dummyname"
284 }
285 run_test 2b "LFSCK can find out and remove invalid linkEA entry"
286
287 test_4()
288 {
289         lfsck_prep 3 3
290         mds_backup_restore || error "(1) Fail to backup/restore!"
291         echo "start $SINGLEMDS with disabling OI scrub"
292         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
293                 error "(2) Fail to start MDS!"
294
295         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
296         [ "$STATUS" == "init" ] ||
297                 error "(3) Expect 'init', but got '$STATUS'"
298
299         #define OBD_FAIL_LFSCK_DELAY2           0x1601
300         do_facet $SINGLEMDS $LCTL set_param fail_val=1
301         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
302         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
303
304         sleep 5
305         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
306         [ "$STATUS" == "scanning-phase1" ] ||
307                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
308
309         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
310         [ "$FLAGS" == "inconsistent" ] ||
311                 error "(6) Expect 'inconsistent', but got '$FLAGS'"
312
313         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
314         do_facet $SINGLEMDS $LCTL set_param fail_val=0
315         sleep 3
316         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
317         [ "$STATUS" == "completed" ] ||
318                 error "(7) Expect 'completed', but got '$STATUS'"
319
320         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
321         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
322
323         local repaired=$($SHOW_NAMESPACE |
324                          awk '/^updated_phase1/ { print $2 }')
325         [ $repaired -ge 9 ] ||
326                 error "(9) Fail to repair crashed linkEA: $repaired"
327
328         mount_client $MOUNT || error "(10) Fail to start client!"
329
330         #define OBD_FAIL_FID_LOOKUP     0x1505
331         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
332         ls $DIR/$tdir/ > /dev/null || error "(11) no FID-in-dirent."
333
334         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
335 }
336 run_test 4 "FID-in-dirent can be rebuilt after MDT file-level backup/restore"
337
338 test_5()
339 {
340         lfsck_prep 1 1 1
341         mds_backup_restore 1 || error "(1) Fail to backup/restore!"
342         echo "start $SINGLEMDS with disabling OI scrub"
343         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_NOSCRUB > /dev/null ||
344                 error "(2) Fail to start MDS!"
345
346         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
347         [ "$STATUS" == "init" ] ||
348                 error "(3) Expect 'init', but got '$STATUS'"
349
350         #define OBD_FAIL_LFSCK_DELAY2           0x1601
351         do_facet $SINGLEMDS $LCTL set_param fail_val=1
352         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
353         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
354
355         sleep 5
356         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
357         [ "$STATUS" == "scanning-phase1" ] ||
358                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
359
360         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
361         [ "$FLAGS" == "inconsistent,upgrade" ] ||
362                 error "(6) Expect 'inconsistent,upgrade', but got '$FLAGS'"
363
364         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
365         do_facet $SINGLEMDS $LCTL set_param fail_val=0
366         sleep 3
367         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
368         [ "$STATUS" == "completed" ] ||
369                 error "(7) Expect 'completed', but got '$STATUS'"
370
371         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
372         [ -z "$FLAGS" ] || error "(8) Expect empty flags, but got '$FLAGS'"
373
374         local repaired=$($SHOW_NAMESPACE |
375                          awk '/^updated_phase1/ { print $2 }')
376         [ $repaired -ge 2 ] ||
377                 error "(9) Fail to repair crashed linkEA: $repaired"
378
379         mount_client $MOUNT || error "(10) Fail to start client!"
380
381         #define OBD_FAIL_FID_LOOKUP     0x1505
382         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1505
383         stat $DIR/$tdir/dummy > /dev/null || error "(11) no FID-in-LMA."
384
385         ls $DIR/$tdir/ > /dev/null || error "(12) no FID-in-dirent."
386
387         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
388         local dummyfid=$($LFS path2fid $DIR/$tdir/dummy)
389         local dummyname=$($LFS fid2path $DIR $dummyfid)
390         [ "$dummyname" == "$DIR/$tdir/dummy" ] ||
391                 error "(13) Fail to generate linkEA: $dummyfid $dummyname"
392 }
393 run_test 5 "LFSCK can handle IFIG object upgrading"
394
395 test_6a() {
396         lfsck_prep 10 10
397         echo "start $SINGLEMDS"
398         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
399                 error "(1) Fail to start MDS!"
400
401         #define OBD_FAIL_LFSCK_DELAY1           0x1600
402         do_facet $SINGLEMDS $LCTL set_param fail_val=1
403         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
404         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
405
406         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
407         [ "$STATUS" == "scanning-phase1" ] ||
408                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
409
410         # Sleep 3 sec to guarantee at least one object processed by LFSCK
411         sleep 3
412         # Fail the LFSCK to guarantee there is at least one checkpoint
413         #define OBD_FAIL_LFSCK_FATAL1           0x1608
414         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001608
415         sleep 3
416         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
417         [ "$STATUS" == "failed" ] ||
418                 error "(4) Expect 'failed', but got '$STATUS'"
419
420         local POSITION0=$($SHOW_NAMESPACE |
421                           awk '/^last_checkpoint_position/ { print $2 }' |
422                           tr -d ',')
423
424         #define OBD_FAIL_LFSCK_DELAY1           0x1600
425         do_facet $SINGLEMDS $LCTL set_param fail_val=1
426         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
427         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
428
429         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
430         [ "$STATUS" == "scanning-phase1" ] ||
431                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
432
433         local POSITION1=$($SHOW_NAMESPACE |
434                           awk '/^latest_start_position/ { print $2 }' |
435                           tr -d ',')
436         [ $POSITION0 -lt $POSITION1 ] ||
437                 error "(7) Expect larger than: $POSITION0, but got $POSITION1"
438
439         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
440         do_facet $SINGLEMDS $LCTL set_param fail_val=0
441         sleep 3
442         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
443         [ "$STATUS" == "completed" ] ||
444                 error "(8) Expect 'completed', but got '$STATUS'"
445 }
446 run_test 6a "LFSCK resumes from last checkpoint (1)"
447
448 test_6b() {
449         lfsck_prep 10 10
450         echo "start $SINGLEMDS"
451         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
452                 error "(1) Fail to start MDS!"
453
454         #define OBD_FAIL_LFSCK_DELAY2           0x1601
455         do_facet $SINGLEMDS $LCTL set_param fail_val=1
456         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
457         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
458
459         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
460         [ "$STATUS" == "scanning-phase1" ] ||
461                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
462
463         # Sleep 3 sec to guarantee at least one object processed by LFSCK
464         sleep 3
465         # Fail the LFSCK to guarantee there is at least one checkpoint
466         #define OBD_FAIL_LFSCK_FATAL2           0x1609
467         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
468         sleep 3
469         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
470         [ "$STATUS" == "failed" ] ||
471                 error "(4) Expect 'failed', but got '$STATUS'"
472
473         local POSITION0=$($SHOW_NAMESPACE |
474                           awk '/^last_checkpoint_position/ { print $4 }')
475
476         #define OBD_FAIL_LFSCK_DELAY2           0x1601
477         do_facet $SINGLEMDS $LCTL set_param fail_val=1
478         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
479         $START_NAMESPACE || error "(5) Fail to start LFSCK for namespace!"
480
481         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
482         [ "$STATUS" == "scanning-phase1" ] ||
483                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
484
485         local POSITION1=$($SHOW_NAMESPACE |
486                           awk '/^latest_start_position/ { print $4 }')
487         if [ $POSITION0 -gt $POSITION1 ]; then
488                 [ $POSITION1 -eq 0 -a $POSITION0 -eq $((POSITION1 + 1)) ] ||
489                 error "(7) Expect larger than: $POSITION0, but got $POSITION1"
490         fi
491
492         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
493         do_facet $SINGLEMDS $LCTL set_param fail_val=0
494         sleep 3
495         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
496         [ "$STATUS" == "completed" ] ||
497                 error "(8) Expect 'completed', but got '$STATUS'"
498 }
499 run_test 6b "LFSCK resumes from last checkpoint (2)"
500
501 test_7a()
502 {
503         lfsck_prep 10 10
504         echo "start $SINGLEMDS"
505         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
506                 error "(1) Fail to start MDS!"
507
508         #define OBD_FAIL_LFSCK_DELAY2           0x1601
509         do_facet $SINGLEMDS $LCTL set_param fail_val=1
510         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
511         $START_NAMESPACE || error "(2) Fail to start LFSCK for namespace!"
512
513         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
514         [ "$STATUS" == "scanning-phase1" ] ||
515                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
516
517         # Sleep 3 sec to guarantee at least one object processed by LFSCK
518         sleep 3
519         echo "stop $SINGLEMDS"
520         stop $SINGLEMDS > /dev/null || error "(4) Fail to stop MDS!"
521
522         echo "start $SINGLEMDS"
523         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
524                 error "(5) Fail to start MDS!"
525
526         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
527         [ "$STATUS" == "scanning-phase1" ] ||
528                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
529
530         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
531         do_facet $SINGLEMDS $LCTL set_param fail_val=0
532         sleep 3
533         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
534         [ "$STATUS" == "completed" ] ||
535                 error "(7) Expect 'completed', but got '$STATUS'"
536 }
537 run_test 7a "non-stopped LFSCK should auto restarts after MDS remount (1)"
538
539 test_7b()
540 {
541         lfsck_prep 2 2
542         echo "start $SINGLEMDS"
543         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
544                 error "(1) Fail to start MDS!"
545
546         mount_client $MOUNT || error "(2) Fail to start client!"
547
548         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
549         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
550         for ((i = 0; i < 20; i++)); do
551                 touch $DIR/$tdir/dummy${i}
552         done
553
554         #define OBD_FAIL_LFSCK_DELAY3           0x1602
555         do_facet $SINGLEMDS $LCTL set_param fail_val=1
556         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1602
557         $START_NAMESPACE || error "(3) Fail to start LFSCK for namespace!"
558
559         sleep 3
560         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
561         [ "$STATUS" == "scanning-phase2" ] ||
562                 error "(4) Expect 'scanning-phase2', but got '$STATUS'"
563
564         echo "stop $SINGLEMDS"
565         stop $SINGLEMDS > /dev/null || error "(5) Fail to stop MDS!"
566
567         echo "start $SINGLEMDS"
568         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
569                 error "(6) Fail to start MDS!"
570
571         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
572         [ "$STATUS" == "scanning-phase2" ] ||
573                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
574
575         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
576         do_facet $SINGLEMDS $LCTL set_param fail_val=0
577         sleep 3
578         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
579         [ "$STATUS" == "completed" ] ||
580                 error "(8) Expect 'completed', but got '$STATUS'"
581 }
582 run_test 7b "non-stopped LFSCK should auto restarts after MDS remount (2)"
583
584 test_8()
585 {
586         lfsck_prep 20 20
587         echo "start $SINGLEMDS"
588         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
589                 error "(1) Fail to start MDS!"
590
591         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
592         [ "$STATUS" == "init" ] ||
593                 error "(2) Expect 'init', but got '$STATUS'"
594
595         mount_client $MOUNT || error "(3) Fail to start client!"
596
597         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
598         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
599         mkdir $DIR/$tdir/crashed
600
601         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
602         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
603         for ((i = 0; i < 5; i++)); do
604                 touch $DIR/$tdir/dummy${i}
605         done
606
607         #define OBD_FAIL_LFSCK_DELAY2           0x1601
608         do_facet $SINGLEMDS $LCTL set_param fail_val=2
609         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
610         $START_NAMESPACE || error "(4) Fail to start LFSCK for namespace!"
611
612         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
613         [ "$STATUS" == "scanning-phase1" ] ||
614                 error "(5) Expect 'scanning-phase1', but got '$STATUS'"
615
616         $STOP_LFSCK || error "(6) Fail to stop LFSCK!"
617
618         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
619         [ "$STATUS" == "stopped" ] ||
620                 error "(7) Expect 'stopped', but got '$STATUS'"
621
622         $START_NAMESPACE || error "(8) Fail to start LFSCK for namespace!"
623
624         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
625         [ "$STATUS" == "scanning-phase1" ] ||
626                 error "(9) Expect 'scanning-phase1', but got '$STATUS'"
627
628         #define OBD_FAIL_LFSCK_FATAL2           0x1609
629         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x80001609
630         sleep 3
631         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
632         [ "$STATUS" == "failed" ] ||
633                 error "(10) Expect 'failed', but got '$STATUS'"
634
635         #define OBD_FAIL_LFSCK_DELAY1           0x1600
636         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1600
637         $START_NAMESPACE || error "(11) Fail to start LFSCK for namespace!"
638
639         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
640         [ "$STATUS" == "scanning-phase1" ] ||
641                 error "(12) Expect 'scanning-phase1', but got '$STATUS'"
642
643         #define OBD_FAIL_LFSCK_CRASH            0x160a
644         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160a
645         sleep 5
646
647         echo "stop $SINGLEMDS"
648         stop $SINGLEMDS > /dev/null || error "(13) Fail to stop MDS!"
649
650         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
651         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
652
653         echo "start $SINGLEMDS"
654         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
655                 error "(14) Fail to start MDS!"
656
657         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
658         [ "$STATUS" == "crashed" ] ||
659                 error "(15) Expect 'crashed', but got '$STATUS'"
660
661         #define OBD_FAIL_LFSCK_DELAY2           0x1601
662         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1601
663         $START_NAMESPACE || error "(16) Fail to start LFSCK for namespace!"
664
665         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
666         [ "$STATUS" == "scanning-phase1" ] ||
667                 error "(17) Expect 'scanning-phase1', but got '$STATUS'"
668
669         echo "stop $SINGLEMDS"
670         stop $SINGLEMDS > /dev/null || error "(18) Fail to stop MDS!"
671
672         #define OBD_FAIL_LFSCK_NO_AUTO          0x160b
673         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160b
674
675         echo "start $SINGLEMDS"
676         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
677                 error "(19) Fail to start MDS!"
678
679         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
680         [ "$STATUS" == "paused" ] ||
681                 error "(20) Expect 'paused', but got '$STATUS'"
682
683         #define OBD_FAIL_LFSCK_DELAY3           0x1602
684         do_facet $SINGLEMDS $LCTL set_param fail_val=2
685         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1602
686
687         $START_NAMESPACE || error "(21) Fail to start LFSCK for namespace!"
688         sleep 2
689         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
690         [ "$STATUS" == "scanning-phase2" ] ||
691                 error "(22) Expect 'scanning-phase2', but got '$STATUS'"
692
693         local FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
694         [ "$FLAGS" == "scanned-once,inconsistent" ] ||
695                 error "(23) Expect 'scanned-once,inconsistent',but got '$FLAGS'"
696
697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
698         do_facet $SINGLEMDS $LCTL set_param fail_val=0
699         sleep 2
700         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
701         [ "$STATUS" == "completed" ] ||
702                 error "(24) Expect 'completed', but got '$STATUS'"
703
704         FLAGS=$($SHOW_NAMESPACE | awk '/^flags/ { print $2 }')
705         [ -z "$FLAGS" ] || error "(25) Expect empty flags, but got '$FLAGS'"
706
707 }
708 run_test 8 "LFSCK state machine"
709
710 test_9a() {
711         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
712                 skip "Testing on UP system, the speed may be inaccurate."
713                 return 0
714         fi
715
716         lfsck_prep 70 70
717         echo "start $SINGLEMDS"
718         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
719                 error "(1) Fail to start MDS!"
720
721         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
722         [ "$STATUS" == "init" ] ||
723                 error "(2) Expect 'init', but got '$STATUS'"
724
725         local BASE_SPEED1=100
726         local RUN_TIME1=10
727         $START_NAMESPACE -s $BASE_SPEED1 || error "(3) Fail to start LFSCK!"
728
729         sleep $RUN_TIME1
730         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
731         [ "$STATUS" == "scanning-phase1" ] ||
732                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
733
734         local SPEED=$($SHOW_NAMESPACE |
735                       awk '/^average_speed_phase1/ { print $2 }')
736
737         # There may be time error, normally it should be less than 2 seconds.
738         # We allow another 20% schedule error.
739         local TIME_DIFF=2
740         # MAX_MARGIN = 1.2 = 12 / 10
741         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
742                            RUN_TIME1 * 12 / 10))
743         [ $SPEED -lt $MAX_SPEED ] ||
744                 error "(4) Got speed $SPEED, expected less than $MAX_SPEED"
745
746         # adjust speed limit
747         local BASE_SPEED2=300
748         local RUN_TIME2=10
749         do_facet $SINGLEMDS \
750                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
751         sleep $RUN_TIME2
752
753         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase1/ { print $2 }')
754         # MIN_MARGIN = 0.8 = 8 / 10
755         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
756                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
757                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
758         [ $SPEED -gt $MIN_SPEED ] ||
759                 error "(5) Got speed $SPEED, expected more than $MIN_SPEED"
760
761         # MAX_MARGIN = 1.2 = 12 / 10
762         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
763                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
764                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
765         [ $SPEED -lt $MAX_SPEED ] ||
766                 error "(6) Got speed $SPEED, expected less than $MAX_SPEED"
767
768         do_facet $SINGLEMDS \
769                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
770         sleep 5
771         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
772         [ "$STATUS" == "completed" ] ||
773                 error "(7) Expect 'completed', but got '$STATUS'"
774 }
775 run_test 9a "LFSCK speed control (1)"
776
777 test_9b() {
778         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
779                 skip "Testing on UP system, the speed may be inaccurate."
780                 return 0
781         fi
782
783         lfsck_prep 0 0
784         echo "start $SINGLEMDS"
785         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
786                 error "(1) Fail to start MDS!"
787
788         mount_client $MOUNT || error "(2) Fail to start client!"
789
790         echo "Another preparing... 50 * 50 files (with error) will be created."
791         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
792         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
793         for ((i = 0; i < 50; i++)); do
794                 mkdir -p $DIR/$tdir/d${i}
795                 touch $DIR/$tdir/f${i}
796                 for ((j = 0; j < 50; j++)); do
797                         touch $DIR/$tdir/d${i}/f${j}
798                 done
799         done
800
801         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
802         [ "$STATUS" == "init" ] ||
803                 error "(3) Expect 'init', but got '$STATUS'"
804
805         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
806         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
807         $START_NAMESPACE || error "(4) Fail to start LFSCK!"
808
809         sleep 10
810         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
811         [ "$STATUS" == "stopped" ] ||
812                 error "(5) Expect 'stopped', but got '$STATUS'"
813
814         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
815
816         local BASE_SPEED1=50
817         local RUN_TIME1=10
818         $START_NAMESPACE -s $BASE_SPEED1 || error "(6) Fail to start LFSCK!"
819
820         sleep $RUN_TIME1
821         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
822         [ "$STATUS" == "scanning-phase2" ] ||
823                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
824
825         local SPEED=$($SHOW_NAMESPACE |
826                       awk '/^average_speed_phase2/ { print $2 }')
827         # There may be time error, normally it should be less than 2 seconds.
828         # We allow another 20% schedule error.
829         local TIME_DIFF=2
830         # MAX_MARGIN = 1.2 = 12 / 10
831         local MAX_SPEED=$((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) / \
832                           RUN_TIME1 * 12 / 10))
833         [ $SPEED -lt $MAX_SPEED ] ||
834                 error "(8) Got speed $SPEED, expected less than $MAX_SPEED"
835
836         # adjust speed limit
837         local BASE_SPEED2=150
838         local RUN_TIME2=10
839         do_facet $SINGLEMDS \
840                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit $BASE_SPEED2
841         sleep $RUN_TIME2
842
843         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
844         # MIN_MARGIN = 0.8 = 8 / 10
845         local MIN_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 - TIME_DIFF) + \
846                             BASE_SPEED2 * (RUN_TIME2 - TIME_DIFF)) / \
847                            (RUN_TIME1 + RUN_TIME2) * 8 / 10))
848         [ $SPEED -gt $MIN_SPEED ] ||
849                 error "(9) Got speed $SPEED, expected more than $MIN_SPEED"
850
851         # MAX_MARGIN = 1.2 = 12 / 10
852         MAX_SPEED=$(((BASE_SPEED1 * (RUN_TIME1 + TIME_DIFF) + \
853                       BASE_SPEED2 * (RUN_TIME2 + TIME_DIFF)) / \
854                      (RUN_TIME1 + RUN_TIME2) * 12 / 10))
855         [ $SPEED -lt $MAX_SPEED ] ||
856                 error "(10) Got speed $SPEED, expected less than $MAX_SPEED"
857
858         do_facet $SINGLEMDS \
859                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
860         sleep 5
861         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
862         [ "$STATUS" == "completed" ] ||
863                 error "(11) Expect 'completed', but got '$STATUS'"
864 }
865 run_test 9b "LFSCK speed control (2)"
866
867 test_10()
868 {
869         lfsck_prep 1 1
870         echo "start $SINGLEMDS"
871         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
872                 error "(1) Fail to start MDS!"
873
874         mount_client $MOUNT || error "(2) Fail to start client!"
875
876         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
877         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
878         for ((i = 0; i < 1000; i = $((i+2)))); do
879                 mkdir -p $DIR/$tdir/d${i}
880                 touch $DIR/$tdir/f${i}
881                 for ((j = 0; j < 5; j++)); do
882                         touch $DIR/$tdir/d${i}/f${j}
883                 done
884         done
885
886         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
887         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
888         for ((i = 1; i < 1000; i = $((i+2)))); do
889                 mkdir -p $DIR/$tdir/d${i}
890                 touch $DIR/$tdir/f${i}
891                 for ((j = 0; j < 5; j++)); do
892                         touch $DIR/$tdir/d${i}/f${j}
893                 done
894         done
895
896         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
897         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
898
899         umount_client $MOUNT
900         mount_client $MOUNT || error "(3) Fail to start client!"
901
902         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
903         [ "$STATUS" == "init" ] ||
904                 error "(4) Expect 'init', but got '$STATUS'"
905
906         $START_NAMESPACE -s 100 || error "(5) Fail to start LFSCK!"
907
908         sleep 10
909         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
910         [ "$STATUS" == "scanning-phase1" ] ||
911                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
912
913         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
914
915         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
916
917         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
918
919         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
920
921         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
922
923         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
924
925         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
926
927         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
928                 error "(14) Fail to softlink!"
929
930         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
931         [ "$STATUS" == "scanning-phase1" ] ||
932                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
933
934         do_facet $SINGLEMDS \
935                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
936         umount_client $MOUNT
937         sleep 10
938         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
939         [ "$STATUS" == "completed" ] ||
940                 error "(16) Expect 'completed', but got '$STATUS'"
941 }
942 run_test 10 "System is available during LFSCK scanning"
943
944 $LCTL set_param debug=-lfsck > /dev/null || true
945
946 # restore MDS/OST size
947 MDSSIZE=${SAVED_MDSSIZE}
948 OSTSIZE=${SAVED_OSTSIZE}
949
950 # cleanup the system at last
951 formatall
952
953 complete $SECONDS
954 exit_status