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