summaryrefslogtreecommitdiff
path: root/tests/xfs/057
blob: d4cfa8dce72794f286864211889ea633e0969adf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2017 Red Hat, Inc. All Rights Reserved.
#
# 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.
#
. ./common/preamble
_begin_fstest auto log

# Override the default cleanup function.
_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
}

# Import common functions.
. ./common/inject

# real QA test starts here

# Modify as appropriate.
_supported_fs xfs
_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