Whamcloud - gitweb
LU-1866 lfsck: LFSCK for namespace consistency (3)
[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         if [ ! -z $igif ]; then
56                 #define OBD_FAIL_FID_IGIF       0x1504
57                 do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1504
58         fi
59
60         echo "setupall"
61         setupall > /dev/null
62
63         echo "preparing... ${nfiles} * ${ndirs} files will be created."
64         mkdir -p $DIR/$tdir
65         cp $LUSTRE/tests/*.sh $DIR/$tdir/
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 $POSITINO0 -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         $START_NAMESPACE -s 100 || error "(3) Fail to start LFSCK!"
721
722         sleep 10
723         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
724         [ "$STATUS" == "scanning-phase1" ] ||
725                 error "(3) Expect 'scanning-phase1', but got '$STATUS'"
726
727         local SPEED=$($SHOW_NAMESPACE |
728                       awk '/^average_speed_phase1/ { print $2 }')
729         # (100 * (10 + 1)) / 10 = 110
730         [ $SPEED -lt 120 ] ||
731                 error "(4) Unexpected speed $SPEED, should not more than 120"
732
733         # adjust speed limit
734         do_facet $SINGLEMDS \
735                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 300
736         sleep 10
737
738         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase1/ { print $2 }')
739         # (100 * (10 - 1) + 300 * (10 - 1)) / 20 = 180
740         [ $SPEED -lt 170 ] &&
741                 error "(5) Unexpected speed $SPEED, should not less than 170"
742
743         # (100 * (10 + 1) + 300 * (10 + 1)) / 20 = 220
744         [ $SPEED -lt 230 ] ||
745                 error "(6) Unexpected speed $SPEED, should not more than 230"
746
747         do_facet $SINGLEMDS \
748                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
749         sleep 5
750         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
751         [ "$STATUS" == "completed" ] ||
752                 error "(7) Expect 'completed', but got '$STATUS'"
753 }
754 run_test 9a "LFSCK speed control (1)"
755
756 test_9b() {
757         if [ -z "$(grep "processor.*: 1" /proc/cpuinfo)" ]; then
758                 skip "Testing on UP system, the speed may be inaccurate."
759                 return 0
760         fi
761
762         lfsck_prep 0 0
763         echo "start $SINGLEMDS"
764         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
765                 error "(1) Fail to start MDS!"
766
767         mount_client $MOUNT || error "(2) Fail to start client!"
768
769         echo "Another preparing... 50 * 50 files (with error) will be created."
770         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
771         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
772         for ((i=0; i<50; i++)); do
773                 mkdir -p $DIR/$tdir/d${i}
774                 touch $DIR/$tdir/f${i}
775                 for ((j=0; j<50; j++)); do
776                         touch $DIR/$tdir/d${i}/f${j}
777                 done
778         done
779
780         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
781         [ "$STATUS" == "init" ] ||
782                 error "(3) Expect 'init', but got '$STATUS'"
783
784         #define OBD_FAIL_LFSCK_NO_DOUBLESCAN    0x160c
785         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x160c
786         $START_NAMESPACE || error "(4) Fail to start LFSCK!"
787
788         sleep 10
789         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
790         [ "$STATUS" == "stopped" ] ||
791                 error "(5) Expect 'stopped', but got '$STATUS'"
792
793         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
794         $START_NAMESPACE -s 50 || error "(6) Fail to start LFSCK!"
795
796         sleep 10
797         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
798         [ "$STATUS" == "scanning-phase2" ] ||
799                 error "(7) Expect 'scanning-phase2', but got '$STATUS'"
800
801         local SPEED=$($SHOW_NAMESPACE |
802                       awk '/^average_speed_phase2/ { print $2 }')
803         # (50 * (10 + 1)) / 10 = 55
804         [ $SPEED -lt 60 ] ||
805                 error "(8) Unexpected speed $SPEED, should not more than 60"
806
807         # adjust speed limit
808         do_facet $SINGLEMDS \
809                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 150
810         sleep 10
811
812         SPEED=$($SHOW_NAMESPACE | awk '/^average_speed_phase2/ { print $2 }')
813         # (50 * (10 - 1) + 150 * (10 - 1)) / 20 = 90
814         [ $SPEED -lt 85 ] &&
815                 error "(9) Unexpected speed $SPEED, should not less than 85"
816
817         # (50 * (10 + 1) + 150 * (10 + 1)) / 20 = 110
818         [ $SPEED -lt 115 ] ||
819                 error "(10) Unexpected speed $SPEED, should not more than 115"
820
821         do_facet $SINGLEMDS \
822                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
823         sleep 5
824         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
825         [ "$STATUS" == "completed" ] ||
826                 error "(11) Expect 'completed', but got '$STATUS'"
827 }
828 run_test 9b "LFSCK speed control (2)"
829
830 test_10()
831 {
832         lfsck_prep 1 1
833         echo "start $SINGLEMDS"
834         start $SINGLEMDS $MDT_DEVNAME $MOUNT_OPTS_SCRUB > /dev/null ||
835                 error "(1) Fail to start MDS!"
836
837         mount_client $MOUNT || error "(2) Fail to start client!"
838
839         #define OBD_FAIL_LFSCK_LINKEA_CRASH     0x1603
840         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1603
841         for ((i=0; i<1000; i=$((i+2)))); do
842                 mkdir -p $DIR/$tdir/d${i}
843                 touch $DIR/$tdir/f${i}
844                 for ((j=0; j<5; j++)); do
845                         touch $DIR/$tdir/d${i}/f${j}
846                 done
847         done
848
849         #define OBD_FAIL_LFSCK_LINKEA_MORE      0x1604
850         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1604
851         for ((i=1; i<1000; i=$((i+2)))); do
852                 mkdir -p $DIR/$tdir/d${i}
853                 touch $DIR/$tdir/f${i}
854                 for ((j=0; j<5; j++)); do
855                         touch $DIR/$tdir/d${i}/f${j}
856                 done
857         done
858
859         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
860         ln $DIR/$tdir/f200 $DIR/$tdir/d200/dummy
861
862         umount_client $MOUNT
863         mount_client $MOUNT || error "(3) Fail to start client!"
864
865         local STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
866         [ "$STATUS" == "init" ] ||
867                 error "(4) Expect 'init', but got '$STATUS'"
868
869         $START_NAMESPACE -s 100 || error "(5) Fail to start LFSCK!"
870
871         sleep 10
872         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
873         [ "$STATUS" == "scanning-phase1" ] ||
874                 error "(6) Expect 'scanning-phase1', but got '$STATUS'"
875
876         ls -ailR $MOUNT > /dev/null || error "(7) Fail to ls!"
877
878         touch $DIR/$tdir/d198/a0 || error "(8) Fail to touch!"
879
880         mkdir $DIR/$tdir/d199/a1 || error "(9) Fail to mkdir!"
881
882         unlink $DIR/$tdir/f200 || error "(10) Fail to unlink!"
883
884         rm -rf $DIR/$tdir/d201 || error "(11) Fail to rmdir!"
885
886         mv $DIR/$tdir/f202 $DIR/$tdir/d203/ || error "(12) Fail to rename!"
887
888         ln $DIR/$tdir/f204 $DIR/$tdir/d205/a3 || error "(13) Fail to hardlink!"
889
890         ln -s $DIR/$tdir/d206 $DIR/$tdir/d207/a4 ||
891                 error "(14) Fail to softlink!"
892
893         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
894         [ "$STATUS" == "scanning-phase1" ] ||
895                 error "(15) Expect 'scanning-phase1', but got '$STATUS'"
896
897         do_facet $SINGLEMDS \
898                 $LCTL set_param -n mdd.${MDT_DEV}.lfsck_speed_limit 0
899         umount_client $MOUNT
900         sleep 10
901         STATUS=$($SHOW_NAMESPACE | awk '/^status/ { print $2 }')
902         [ "$STATUS" == "completed" ] ||
903                 error "(16) Expect 'completed', but got '$STATUS'"
904 }
905 run_test 10 "System is available during LFSCK scanning"
906
907 $LCTL set_param debug=-lfsck > /dev/null || true
908
909 # restore MDS/OST size
910 MDSSIZE=${SAVED_MDSSIZE}
911 OSTSIZE=${SAVED_OSTSIZE}
912
913 # cleanup the system at last
914 formatall
915
916 complete $SECONDS
917 exit_status