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