summaryrefslogtreecommitdiff
path: root/tests/xfs/605
blob: 5cbf5d25502d86b6c42857b947468b5c660a1527 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2024 Oracle, Inc.  All Rights Reserved.
#
# FS QA Test No. 605
#
# Test metadump/mdrestore's ability to dump a dirty log and restore it
# correctly.
#
. ./common/preamble
_begin_fstest auto quick metadump log logprint punch

# Override the default cleanup function.
_cleanup()
{
	cd /
	rm -r -f $tmp.*
	_scratch_unmount > /dev/null 2>&1
	[[ -n $logdev && $logdev != "none" && $logdev != $SCRATCH_LOGDEV ]] && \
		_destroy_loop_device $logdev
	[[ -n $datadev ]] && _destroy_loop_device $datadev
	rm -r -f $metadump_file $TEST_DIR/data-image \
	   $TEST_DIR/log-image
}

# Import common functions.
. ./common/dmflakey
. ./common/inject

# real QA test starts here
_supported_fs xfs
_require_scratch
_require_test
_require_loop
_require_xfs_debug
_require_xfs_io_error_injection log_item_pin
_require_dm_target flakey
_require_xfs_io_command "pwrite"
_require_test_program "punch-alternating"

metadump_file=${TEST_DIR}/${seq}.md
testfile=${SCRATCH_MNT}/testfile

echo "Format filesystem on scratch device"
_scratch_mkfs >> $seqres.full 2>&1

max_md_version=1
_scratch_metadump_v2_supported && max_md_version=2

external_log=0
if [[ $USE_EXTERNAL = yes && -n "$SCRATCH_LOGDEV" ]]; then
	external_log=1
fi

if [[ $max_md_version == 1 && $external_log == 1 ]]; then
	_notrun "metadump v1 does not support external log device"
fi

verify_metadump_v1()
{
	local version=""
	if [[ $max_md_version == 2 ]]; then
		version="-v 1"
	fi

	_scratch_xfs_metadump $metadump_file -a -o $version

	SCRATCH_DEV=$TEST_DIR/data-image _scratch_xfs_mdrestore $metadump_file

	datadev=$(_create_loop_device $TEST_DIR/data-image)

	SCRATCH_DEV=$datadev _scratch_mount
	SCRATCH_DEV=$datadev _check_scratch_fs
	SCRATCH_DEV=$datadev _scratch_unmount

	_destroy_loop_device $datadev
	datadev=""
	rm -f $TEST_DIR/data-image
}

verify_metadump_v2()
{
	local version="-v 2"

	_scratch_xfs_metadump $metadump_file -a -o $version

	# Metadump v2 files can contain contents dumped from an external log
	# device. Use a temporary file to hold the log device contents restored
	# from such a metadump file.
	slogdev=""
	if [[ -n $SCRATCH_LOGDEV ]]; then
		slogdev=$TEST_DIR/log-image
	fi

	SCRATCH_DEV=$TEST_DIR/data-image SCRATCH_LOGDEV=$slogdev \
		   _scratch_xfs_mdrestore $metadump_file

	datadev=$(_create_loop_device $TEST_DIR/data-image)

	logdev=""
	if [[ -s $slogdev ]]; then
		logdev=$(_create_loop_device $slogdev)
	fi

	SCRATCH_DEV=$datadev SCRATCH_LOGDEV=$logdev _scratch_mount
	SCRATCH_DEV=$datadev SCRATCH_LOGDEV=$logdev _check_scratch_fs
	SCRATCH_DEV=$datadev SCRATCH_LOGDEV=$logdev _scratch_unmount

	if [[ -s $logdev ]]; then
		_destroy_loop_device $logdev
		logdev=""
		rm -f $slogdev
	fi

	_destroy_loop_device $datadev
	datadev=""
	rm -f $TEST_DIR/data-image
}

echo "Initialize and mount filesystem on flakey device"
_init_flakey
_load_flakey_table $FLAKEY_ALLOW_WRITES
_mount_flakey

echo "Create test file"
$XFS_IO_PROG -s -f -c "pwrite 0 5M" $testfile >> $seqres.full

echo "Punch alternative blocks of test file"
$here/src/punch-alternating $testfile

echo "Mount cycle the filesystem on flakey device"
_unmount_flakey
_mount_flakey

device=$(readlink -f $FLAKEY_DEV)
device=$(_short_dev $device)

echo "Pin log items in the AIL"
echo 1 > /sys/fs/xfs/${device}/errortag/log_item_pin

echo "Create two checkpoint transactions on ondisk log"
for ct in $(seq 1 2); do
	offset=$($XFS_IO_PROG -c 'fiemap' $testfile | tac |  grep -v hole | \
			 head -n 1 | awk -F '[\\[.]' '{ print $2 * 512; }')
	$XFS_IO_PROG -c "truncate $offset" -c fsync $testfile
done

echo "Drop writes to filesystem from here onwards"
_load_flakey_table $FLAKEY_DROP_WRITES

echo "Unpin log items in AIL"
echo 0 > /sys/fs/xfs/${device}/errortag/log_item_pin

echo "Unmount filesystem on flakey device"
_unmount_flakey

echo "Clean up flakey device"
_cleanup_flakey

echo -n "Filesystem has a "
_print_logstate

echo "Create metadump file, restore it and check restored fs"

if [[ $external_log == 0 ]]; then
	verify_metadump_v1 $max_md_version
fi

if [[ $max_md_version == 2 ]]; then
	verify_metadump_v2
fi

# Mount the fs to replay the contents from the dirty log.
_scratch_mount

# success, all done
status=0
exit