common/rc: factor out _scratch_xfs_[get|set]_sb_field
[xfstests-dev.git] / tests / xfs / 057
1 #! /bin/bash
2 # FS QA Test No. 057
3 #
4 # Attempt to reproduce log recovery failure by writing corrupt log records over
5 # the last good tail in the log. The tail is force pinned while a workload runs
6 # the head as close as possible behind the tail. Once the head is pinned,
7 # corrupted log records are written to the log and the filesystem shuts down.
8 #
9 # While log recovery should handle the corrupted log records, it has historical
10 # problems dealing with the situation where the corrupted log records may have
11 # overwritten the tail of the previous good record in the log. If this occurs,
12 # log recovery may fail.
13 #
14 # This can be reproduced more reliably under non-default conditions such as with
15 # the smallest supported FSB sizes and/or largest supported log buffer sizes and
16 # counts (logbufs and logbsize mount options).
17 #
18 # Note that this test requires a DEBUG mode kernel.
19 #
20 #-----------------------------------------------------------------------
21 # Copyright (c) 2017 Red Hat, Inc. All Rights Reserved.
22 #
23 # This program is free software; you can redistribute it and/or
24 # modify it under the terms of the GNU General Public License as
25 # published by the Free Software Foundation.
26 #
27 # This program is distributed in the hope that it would be useful,
28 # but WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30 # GNU General Public License for more details.
31 #
32 # You should have received a copy of the GNU General Public License
33 # along with this program; if not, write the Free Software Foundation,
34 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
35 #-----------------------------------------------------------------------
36 #
37
38 seq=`basename $0`
39 seqres=$RESULT_DIR/$seq
40 echo "QA output created by $seq"
41
42 here=`pwd`
43 tmp=/tmp/$$
44 status=1        # failure is the default!
45 trap "_cleanup; exit \$status" 0 1 2 3 15
46
47 _cleanup()
48 {
49         cd /
50         rm -f $tmp.*
51         $KILLALL_PROG -9 fsstress > /dev/null 2>&1
52         [ -e /sys/fs/xfs/$sdev/errortag/log_item_pin ] &&
53                 echo 0 > /sys/fs/xfs/$sdev/errortag/log_item_pin
54         wait > /dev/null 2>&1
55 }
56
57 rm -f $seqres.full
58
59 # get standard environment, filters and checks
60 . ./common/rc
61 . ./common/inject
62
63 # real QA test starts here
64
65 # Modify as appropriate.
66 _supported_fs xfs
67 _supported_os Linux
68 _require_xfs_io_error_injection log_item_pin
69 _require_xfs_io_error_injection log_bad_crc
70 _require_scratch
71 _require_command "$KILLALL_PROG" killall
72
73 echo "Silence is golden."
74
75 sdev=$(_short_dev $SCRATCH_DEV)
76
77 # use a small log fs
78 _scratch_mkfs_sized $((1024 * 1024 * 500)) >> $seqres.full 2>&1 ||
79                 _fail "mkfs failed"
80 _scratch_mount || _fail "mount failed"
81
82 # populate the fs with some data and cycle the mount to reset the log head/tail
83 $FSSTRESS_PROG -d $SCRATCH_MNT -z -fcreat=1 -p 4 -n 100000 > /dev/null 2>&1
84 _scratch_cycle_mount || _fail "cycle mount failed"
85
86 # Pin the tail and start a file removal workload. File removal tends to
87 # reproduce the corruption more reliably.
88 _scratch_inject_error log_item_pin 1
89
90 rm -rf $SCRATCH_MNT/* > /dev/null 2>&1 &
91 workpid=$!
92
93 # wait for the head to stop pushing forward
94 prevhead=-1
95 head=`cat /sys/fs/xfs/$sdev/log/log_head_lsn`
96 while [ "$head" != "$prevhead" ]; do
97         sleep 5
98         prevhead=$head
99         head=`cat /sys/fs/xfs/$sdev/log/log_head_lsn`
100 done
101
102 # Once the head is pinned behind the tail, enable log record corruption and
103 # unpin the tail. All subsequent log buffer writes end up corrupted on-disk and
104 # result in log I/O errors.
105 _scratch_inject_error log_bad_crc 1
106 _scratch_inject_error log_item_pin 0
107
108 # wait for fs shutdown to kill the workload
109 wait $workpid
110
111 # cycle mount to test log recovery
112 _scratch_cycle_mount
113
114 # success, all done
115 status=0
116 exit