blob: 228f52bb010f371c2eecf13515ff280387569a08 [file] [log] [blame]
#! /bin/bash
# FS QA Test No. 057
#
# Attempt to reproduce log recovery failure by writing corrupt log records over
# the last good tail in the log. The tail is force pinned while a workload runs
# the head as close as possible behind the tail. Once the head is pinned,
# corrupted log records are written to the log and the filesystem shuts down.
#
# While log recovery should handle the corrupted log records, it has historical
# problems dealing with the situation where the corrupted log records may have
# overwritten the tail of the previous good record in the log. If this occurs,
# log recovery may fail.
#
# This can be reproduced more reliably under non-default conditions such as with
# the smallest supported FSB sizes and/or largest supported log buffer sizes and
# counts (logbufs and logbsize mount options).
#
# Note that this test requires a DEBUG mode kernel.
#
#-----------------------------------------------------------------------
# Copyright (c) 2017 Red Hat, 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.*
$KILLALL_PROG -9 fsstress > /dev/null 2>&1
[ -e /sys/fs/xfs/$sdev/errortag/log_item_pin ] &&
echo 0 > /sys/fs/xfs/$sdev/errortag/log_item_pin
wait > /dev/null 2>&1
}
rm -f $seqres.full
# get standard environment, filters and checks
. ./common/rc
. ./common/inject
# real QA test starts here
# Modify as appropriate.
_supported_fs xfs
_supported_os Linux
_require_xfs_io_error_injection log_item_pin
_require_xfs_io_error_injection log_bad_crc
_require_scratch
_require_command "$KILLALL_PROG" killall
echo "Silence is golden."
sdev=$(_short_dev $SCRATCH_DEV)
# use a small log fs
_scratch_mkfs_sized $((1024 * 1024 * 500)) >> $seqres.full 2>&1 ||
_fail "mkfs failed"
_scratch_mount
# populate the fs with some data and cycle the mount to reset the log head/tail
$FSSTRESS_PROG -d $SCRATCH_MNT -z -fcreat=1 -p 4 -n 100000 > /dev/null 2>&1
_scratch_cycle_mount || _fail "cycle mount failed"
# Pin the tail and start a file removal workload. File removal tends to
# reproduce the corruption more reliably.
_scratch_inject_error log_item_pin 1
rm -rf $SCRATCH_MNT/* > /dev/null 2>&1 &
workpid=$!
# wait for the head to stop pushing forward
prevhead=-1
head=`cat /sys/fs/xfs/$sdev/log/log_head_lsn`
while [ "$head" != "$prevhead" ]; do
sleep 5
prevhead=$head
head=`cat /sys/fs/xfs/$sdev/log/log_head_lsn`
done
# Once the head is pinned behind the tail, enable log record corruption and
# unpin the tail. All subsequent log buffer writes end up corrupted on-disk and
# result in log I/O errors.
_scratch_inject_error log_bad_crc 1
_scratch_inject_error log_item_pin 0
# wait for fs shutdown to kill the workload
wait $workpid
# cycle mount to test log recovery
_scratch_cycle_mount
# success, all done
status=0
exit