blob: a1e511e30c99b04837ca0280f7b4f44918436e3a [file] [log] [blame]
#! /bin/bash
# FS QA Test No. 006
#
# Create and populate an ext4 filesystem, fuzz the metadata, then see how
# the kernel reacts, how e2fsck fares in fixing the mess, and then
# try more kernel accesses to see if it really fixed things.
#
#-----------------------------------------------------------------------
# Copyright (c) 2015 Oracle, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#-----------------------------------------------------------------------
#
seq=`basename $0`
seqres=$RESULT_DIR/$seq
echo "QA output created by $seq"
here=`pwd`
tmp=/tmp/$$
status=1 # failure is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15
_cleanup()
{
cd /
#rm -f $tmp.*
}
# get standard environment, filters and checks
. ./common/rc
. ./common/filter
. ./common/attr
. ./common/populate
. ./common/fuzzy
if [ ! -x "$(which e2fuzz)" ]; then
_notrun "Couldn't find e2fuzz"
fi
# real QA test starts here
_supported_fs ext4
_supported_os Linux
_require_scratch
_require_attrs
_require_populate_commands
repair_scratch() {
fsck_pass="$1"
FSCK_LOG="${tmp}-fuzz-${fsck_pass}.log"
echo "++ fsck pass ${fsck_pass}" > "${FSCK_LOG}"
e2fsck -f -y "${SCRATCH_DEV}"
res=$?
if [ "${res}" -eq 0 ]; then
echo "++ allegedly fixed, reverify" >> "${FSCK_LOG}"
_check_scratch_fs -n >> "${FSCK_LOG}" 2>&1
res=$?
fi
echo "++ fsck returns ${res}" >> "${FSCK_LOG}"
if [ "${res}" -eq 0 ]; then
echo "++ fsck thinks we are done" >> "${FSCK_LOG}"
cat "${FSCK_LOG}"
return 0
elif [ "${fsck_pass}" -eq "${FSCK_PASSES}" ]; then
echo "++ fsck did not fix in ${FSCK_PASSES} passes." >> "${FSCK_LOG}"
cat "${FSCK_LOG}"
return 0
fi
cat "${FSCK_LOG}"
if [ "${fsck_pass}" -gt 1 ]; then
cmp -s "${tmp}-fuzz-$((fsck_pass - 1)).log" "${FSCK_LOG}"
if [ $? -eq 0 ]; then
echo "++ fsck makes no progress"
return 2
fi
fi
return 1
}
rm -f $seqres.full
echo "See interesting results in $seqres.full" | sed -e "s,$RESULT_DIR,RESULT_DIR,g"
SRCDIR=`pwd`
test -z "${FUZZ_ARGS}" && FUZZ_ARGS="-b 32 -v"
test -z "${FSCK_PASSES}" && FSCK_PASSES=10
BLK_SZ=4096
echo "fuzzing ext4 with FUZZ_ARGS=$FUZZ_ARGS and FSCK_PASSES=$FSCK_PASSES" > $seqres.full
echo "+ create scratch fs" >> $seqres.full
_scratch_mkfs_ext4 >> $seqres.full 2>&1
echo "+ populate fs image" >> $seqres.full
_scratch_populate >> $seqres.full
echo "+ check fs" >> $seqres.full
_check_scratch_fs >> $seqres.full 2>&1 || _fail "should pass initial fsck"
echo "++ corrupt image" >> $seqres.full
e2fuzz ${FUZZ_ARGS} ${SCRATCH_DEV} >> $seqres.full 2>&1
echo "++ mount image" >> $seqres.full
_try_scratch_mount >> $seqres.full 2>&1
echo "++ test scratch" >> $seqres.full
_scratch_fuzz_test >> $seqres.full 2>&1
echo "++ modify scratch" >> $seqres.full
_scratch_fuzz_modify >> $seqres.full 2>&1
echo "++ unmount" >> $seqres.full
umount "${SCRATCH_MNT}"
# repair in a loop...
for p in $(seq 1 "${FSCK_PASSES}"); do
repair_scratch "$p" >> $seqres.full 2>&1 && break
done
echo "+ fsck loop returns ${fsck_loop_ret}" >> $seqres.full
echo "++ check fs for round 2" >> $seqres.full
_check_scratch_fs >> $seqres.full 2>&1
ROUND2_LOG="${tmp}-round2-${fsck_pass}.log"
echo "++ mount image (2)" >> $ROUND2_LOG
_try_scratch_mount >> $ROUND2_LOG 2>&1
echo "++ chattr -R -i" >> $ROUND2_LOG
$CHATTR_PROG -R -f -i "${SCRATCH_MNT}/" > /dev/null 2>> $ROUND2_LOG
echo "++ test scratch" >> $ROUND2_LOG
_scratch_fuzz_test >> $ROUND2_LOG 2>&1
echo "++ modify scratch" >> $ROUND2_LOG
_scratch_fuzz_modify >> $ROUND2_LOG 2>&1
echo "++ unmount" >> $ROUND2_LOG
umount "${SCRATCH_MNT}" >> $ROUND2_LOG 2>&1
cat "$ROUND2_LOG" >> $seqres.full
echo "++ check fs (2)" >> $seqres.full
_check_scratch_fs >> $seqres.full 2>&1
egrep -q '(did not fix|makes no progress)' $seqres.full && echo "e2fsck failed" | tee -a $seqres.full
if [ "$(wc -l < "$ROUND2_LOG")" -ne 8 ]; then
echo "e2fsck did not fix everything" | tee -a $seqres.full
fi
echo "finished fuzzing" | tee -a "$seqres.full"
status=0
exit