2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2015 Oracle, Inc. All Rights Reserved.
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.
12 seqres=$RESULT_DIR/$seq
13 echo "QA output created by $seq"
17 status=1 # failure is the default!
18 trap "_cleanup; exit \$status" 0 1 2 3 15
26 # get standard environment, filters and checks
33 # real QA test starts here
38 #_require_xfs_crc # checksum not required, but you probably want it anyway...
39 #_require_xfs_mkfs_crc
41 _require_populate_commands
46 FSCK_LOG="${tmp}-fuzz-${fsck_pass}.log"
47 echo "++ fsck pass ${fsck_pass}" > "${FSCK_LOG}"
48 _scratch_xfs_repair >> "${FSCK_LOG}" 2>&1
50 if [ "${res}" -eq 0 ]; then
51 echo "++ allegedly fixed, reverify" >> "${FSCK_LOG}"
52 _scratch_xfs_repair -n >> "${FSCK_LOG}" 2>&1
55 echo "++ fsck returns ${res}" >> "${FSCK_LOG}"
56 if [ "${res}" -eq 0 ]; then
57 echo "++ fsck thinks we are done" >> "${FSCK_LOG}"
60 elif [ "${res}" -eq 2 ]; then
62 echo "+++ replaying log" >> "${FSCK_LOG}"
63 _try_scratch_mount >> "${FSCK_LOG}" 2>&1
65 echo "+++ mount returns ${res}" >> "${FSCK_LOG}"
66 if [ "${res}" -gt 0 ]; then
67 echo "+++ zeroing log" >> "${FSCK_LOG}"
68 _scratch_xfs_repair -L >> "${FSCK_LOG}" 2>&1
69 echo "+++ returns $?" >> "${FSCK_LOG}"
71 umount "${SCRATCH_MNT}" >> "${FSCK_LOG}" 2>&1
73 elif [ "${fsck_pass}" -eq "${FSCK_PASSES}" ]; then
74 echo "++ fsck did not fix in ${FSCK_PASSES} passes." >> "${FSCK_LOG}"
79 if [ "${fsck_pass}" -gt 1 ]; then
80 cmp -s "${tmp}-fuzz-$((fsck_pass - 1)).log" "${FSCK_LOG}"
82 echo "++ fsck makes no progress"
90 # This test will corrupt fs intentionally, so there will be WARNINGs
91 # in dmesg as expected
94 echo "See interesting results in $seqres.full" | sed -e "s,$RESULT_DIR,RESULT_DIR,g"
96 test -z "${FUZZ_ARGS}" && FUZZ_ARGS="-3 -n 32"
97 test -z "${FSCK_PASSES}" && FSCK_PASSES=10
100 echo "fuzzing xfs with FUZZ_ARGS=$FUZZ_ARGS and FSCK_PASSES=$FSCK_PASSES" > $seqres.full
102 echo "+ create scratch fs" >> $seqres.full
103 _scratch_mkfs_xfs >> $seqres.full 2>&1
105 echo "+ populate fs image" >> $seqres.full
106 _scratch_populate >> $seqres.full
108 echo "+ check fs" >> $seqres.full
109 _scratch_xfs_repair >> $seqres.full 2>&1 || _fail "should pass initial fsck"
111 echo "++ corrupt image" >> $seqres.full
112 xfs_db -x -c blockget -c "blocktrash ${FUZZ_ARGS}" "${SCRATCH_DEV}" >> $seqres.full 2>&1
114 echo "++ mount image" >> $seqres.full
115 _try_scratch_mount >> $seqres.full 2>&1
117 echo "+++ test scratch" >> $seqres.full
118 _scratch_fuzz_test >> $seqres.full 2>&1
120 echo "+++ modify scratch" >> $seqres.full
121 _scratch_fuzz_modify >> $seqres.full 2>&1
123 echo "++ umount" >> $seqres.full
124 umount "${SCRATCH_MNT}"
126 # repair in a loop...
127 for p in $(seq 1 "${FSCK_PASSES}"); do
128 scratch_repair "$p" >> $seqres.full 2>&1 && break
130 echo "+ fsck loop returns ${fsck_loop_ret}" >> $seqres.full
132 echo "++ check fs for round 2" >> $seqres.full
133 _scratch_xfs_repair >> $seqres.full 2>&1
135 ROUND2_LOG="${tmp}-round2-${fsck_pass}.log"
136 echo "++ mount image (2)" >> $ROUND2_LOG
137 _try_scratch_mount >> $ROUND2_LOG 2>&1
139 echo "++ chattr -R -i" >> $ROUND2_LOG
140 $CHATTR_PROG -R -f -i "${SCRATCH_MNT}/" > /dev/null 2>> $ROUND2_LOG
142 echo "+++ test scratch" >> $ROUND2_LOG
143 _scratch_fuzz_test >> $ROUND2_LOG 2>&1
145 echo "+++ modify scratch" >> $ROUND2_LOG
146 _scratch_fuzz_modify >> $ROUND2_LOG 2>&1
148 echo "++ umount" >> $ROUND2_LOG
149 umount "${SCRATCH_MNT}" >> $ROUND2_LOG 2>&1
151 cat "$ROUND2_LOG" >> $seqres.full
153 echo "++ check fs (2)" >> $seqres.full
154 _scratch_xfs_repair >> $seqres.full 2>&1
156 egrep -q '(did not fix|makes no progress)' $seqres.full && echo "xfs_repair failed" | tee -a $seqres.full
157 if [ "$(wc -l < "$ROUND2_LOG")" -ne 8 ]; then
158 echo "xfs_repair did not fix everything" | tee -a $seqres.full
160 echo "finished fuzzing" | tee -a "$seqres.full"