xfs: force file creation to the data device for certain layout tests
[xfstests-dev.git] / tests / xfs / 083
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2015 Oracle, Inc.  All Rights Reserved.
4 #
5 # FS QA Test No. 083
6 #
7 # Create and populate an XFS filesystem, fuzz the metadata, then see how
8 # the kernel reacts, how xfs_repair fares in fixing the mess, and then
9 # try more kernel accesses to see if it really fixed things.
10 #
11 seq=`basename $0`
12 seqres=$RESULT_DIR/$seq
13 echo "QA output created by $seq"
14
15 here=`pwd`
16 tmp=/tmp/$$
17 status=1        # failure is the default!
18 trap "_cleanup; exit \$status" 0 1 2 3 15
19
20 _cleanup()
21 {
22     cd /
23     #rm -f $tmp.*
24 }
25
26 # get standard environment, filters and checks
27 . ./common/rc
28 . ./common/filter
29 . ./common/attr
30 . ./common/populate
31 . ./common/fuzzy
32
33 # real QA test starts here
34 _supported_fs xfs
35
36 _require_scratch
37 #_require_xfs_crc       # checksum not required, but you probably want it anyway...
38 #_require_xfs_mkfs_crc
39 _require_attrs
40 _require_populate_commands
41
42 scratch_repair() {
43         fsck_pass="$1"
44
45         FSCK_LOG="${tmp}-fuzz-${fsck_pass}.log"
46         echo "++ fsck pass ${fsck_pass}" > "${FSCK_LOG}"
47         _repair_scratch_fs >> "${FSCK_LOG}" 2>&1
48         res=$?
49         if [ "${res}" -eq 0 ]; then
50                 echo "++ allegedly fixed, reverify" >> "${FSCK_LOG}"
51                 _scratch_xfs_repair -n >> "${FSCK_LOG}" 2>&1
52                 res=$?
53         fi
54         echo "++ fsck returns ${res}" >> "${FSCK_LOG}"
55         if [ "${res}" -eq 0 ]; then
56                 echo "++ fsck thinks we are done" >> "${FSCK_LOG}"
57                 cat "${FSCK_LOG}"
58                 return 0
59         elif [ "${res}" -eq 2 ]; then
60                 # replay log?
61                 echo "+++ replaying log" >> "${FSCK_LOG}"
62                 _try_scratch_mount >> "${FSCK_LOG}" 2>&1
63                 res=$?
64                 echo "+++ mount returns ${res}" >> "${FSCK_LOG}"
65                 if [ "${res}" -gt 0 ]; then
66                         echo "+++ zeroing log" >> "${FSCK_LOG}"
67                         _scratch_xfs_repair -L >> "${FSCK_LOG}" 2>&1
68                         echo "+++ returns $?" >> "${FSCK_LOG}"
69                 else
70                         umount "${SCRATCH_MNT}" >> "${FSCK_LOG}" 2>&1
71                 fi
72         elif [ "${fsck_pass}" -eq "${FSCK_PASSES}" ]; then
73                 echo "++ fsck did not fix in ${FSCK_PASSES} passes." >> "${FSCK_LOG}"
74                 cat "${FSCK_LOG}"
75                 return 0
76         fi
77         cat "${FSCK_LOG}"
78         if [ "${fsck_pass}" -gt 1 ]; then
79                 cmp -s "${tmp}-fuzz-$((fsck_pass - 1)).log" "${FSCK_LOG}"
80                 if [ $? -eq 0 ]; then
81                         echo "++ fsck makes no progress"
82                         return 2
83                 fi
84         fi
85         return 1
86 }
87
88 rm -f $seqres.full
89 # This test will corrupt fs intentionally, so there will be WARNINGs
90 # in dmesg as expected
91 _disable_dmesg_check
92
93 echo "See interesting results in $seqres.full" | sed -e "s,$RESULT_DIR,RESULT_DIR,g"
94 SRCDIR=`pwd`
95 test -z "${FUZZ_ARGS}" && FUZZ_ARGS="-3 -n 32"
96 test -z "${FSCK_PASSES}" && FSCK_PASSES=10
97 BLK_SZ=4096
98
99 echo "fuzzing xfs with FUZZ_ARGS=$FUZZ_ARGS and FSCK_PASSES=$FSCK_PASSES" > $seqres.full
100
101 echo "+ create scratch fs" >> $seqres.full
102 _scratch_mkfs_xfs >> $seqres.full 2>&1
103
104 echo "+ populate fs image" >> $seqres.full
105 _scratch_populate >> $seqres.full
106
107 echo "+ check fs" >> $seqres.full
108 _repair_scratch_fs >> $seqres.full 2>&1 || _fail "should pass initial fsck"
109
110 echo "++ corrupt image" >> $seqres.full
111 _scratch_xfs_db -x -c blockget -c "blocktrash ${FUZZ_ARGS}" >> $seqres.full 2>&1
112
113 echo "++ mount image" >> $seqres.full
114 _try_scratch_mount >> $seqres.full 2>&1
115
116 echo "+++ test scratch" >> $seqres.full
117 _scratch_fuzz_test >> $seqres.full 2>&1
118
119 echo "+++ modify scratch" >> $seqres.full
120 _scratch_fuzz_modify >> $seqres.full 2>&1
121
122 echo "++ umount" >> $seqres.full
123 umount "${SCRATCH_MNT}"
124
125 # repair in a loop...
126 for p in $(seq 1 "${FSCK_PASSES}"); do
127         scratch_repair "$p" >> $seqres.full 2>&1 && break
128 done
129 echo "+ fsck loop returns ${fsck_loop_ret}" >> $seqres.full
130
131 echo "++ check fs for round 2" >> $seqres.full
132 _repair_scratch_fs >> $seqres.full 2>&1
133
134 ROUND2_LOG="${tmp}-round2-${fsck_pass}.log"
135 echo "++ mount image (2)" >> $ROUND2_LOG
136 _try_scratch_mount >> $ROUND2_LOG 2>&1
137
138 echo "++ chattr -R -i" >> $ROUND2_LOG
139 $CHATTR_PROG -R -f -i "${SCRATCH_MNT}/" > /dev/null 2>> $ROUND2_LOG
140
141 echo "+++ test scratch" >> $ROUND2_LOG
142 _scratch_fuzz_test >> $ROUND2_LOG 2>&1
143
144 echo "+++ modify scratch" >> $ROUND2_LOG
145 _scratch_fuzz_modify >> $ROUND2_LOG 2>&1
146
147 echo "++ umount" >> $ROUND2_LOG
148 umount "${SCRATCH_MNT}" >> $ROUND2_LOG 2>&1
149
150 cat "$ROUND2_LOG" >> $seqres.full
151
152 echo "++ check fs (2)" >> $seqres.full
153 _repair_scratch_fs >> $seqres.full 2>&1
154
155 egrep -q '(did not fix|makes no progress)' $seqres.full && echo "xfs_repair failed" | tee -a $seqres.full
156 if [ "$(wc -l < "$ROUND2_LOG")" -ne 8 ]; then
157         echo "xfs_repair did not fix everything" | tee -a $seqres.full
158 fi
159 echo "finished fuzzing" | tee -a "$seqres.full"
160
161 status=0
162 exit