aboutsummaryrefslogtreecommitdiffstats
path: root/tests/btrfs/192
blob: 00ea1478ab1a71772db4084e3ef280074b2ce47c (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
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2019 SUSE Linux Products GmbH. All Rights Reserved.
#
# FS QA Test 192
#
# Test btrfs consistency after each FUA for a workload with snapshot creation
# and removal
#
. ./common/preamble
_begin_fstest auto replay snapshot stress recoveryloop

# Override the default cleanup function.
_cleanup()
{
	cd /
	kill -q $pid1 &> /dev/null
	kill -q $pid2 &> /dev/null
	"$KILLALL_PROG" -q $FSSTRESS_PROG &> /dev/null
	wait
	_log_writes_cleanup &> /dev/null
	rm -f $tmp.*
}

# Import common functions.
. ./common/filter
. ./common/attr
. ./common/dmlogwrites

# real QA test starts here

# Modify as appropriate.
_supported_fs btrfs

_require_command "$KILLALL_PROG" killall
_require_command "$BLKDISCARD_PROG" blkdiscard
_require_btrfs_fs_feature "no_holes"
_require_btrfs_mkfs_feature "no-holes"
_require_log_writes
_require_scratch
_require_attrs

# We require a 4K nodesize to ensure the test isn't too slow
if [ $(_get_page_size) -ne 4096 ]; then
	_notrun "This test doesn't support non-4K page size yet"
fi

runtime=30
nr_cpus=$("$here/src/feature" -o)
# cap nr_cpus to 8 to avoid spending too much time on hosts with many cpus
if [ $nr_cpus -gt 8 ]; then
	nr_cpus=8
fi
fsstress_args=$(_scale_fsstress_args -w -d $SCRATCH_MNT -n 99999 -p $nr_cpus \
		$FSSTRESS_AVOID)
_log_writes_init $SCRATCH_DEV

# Discard the whole devices so when some tree pointer is wrong, it won't point
# to some older valid tree blocks, so we can detect it.
$BLKDISCARD_PROG $LOGWRITES_DMDEV > /dev/null 2>&1

# Use no-holes to avoid warnings of missing file extent items (expected
# for holes due to mix of buffered and direct IO writes).
# And use 4K nodesize to bump tree height.
_log_writes_mkfs -O no-holes -n 4k >> $seqres.full
_log_writes_mount

$BTRFS_UTIL_PROG subvolume create $SCRATCH_MNT/src > /dev/null
mkdir -p $SCRATCH_MNT/snapshots
mkdir -p $SCRATCH_MNT/src/padding

snapshot_workload()
{
	trap "wait; exit" SIGTERM

	local i=0
	while true; do
		$BTRFS_UTIL_PROG subvolume snapshot \
			$SCRATCH_MNT/src $SCRATCH_MNT/snapshots/$i \
			> /dev/null
		# Do something small to make snapshots different
		rm -f "$(_random_file $SCRATCH_MNT/src/padding)"
		rm -f "$(_random_file $SCRATCH_MNT/src/padding)"
		touch "$(_random_file $SCRATCH_MNT/src/padding)"
		touch "$SCRATCH_MNT/src/padding/random_$RANDOM"

		i=$(($i + 1))
		sleep 1
	done
}

delete_workload()
{
	trap "wait; exit" SIGTERM

	while true; do
		sleep 2
		$BTRFS_UTIL_PROG subvolume delete \
			"$(_random_file $SCRATCH_MNT/snapshots)" \
			> /dev/null 2>&1
	done
}

# Replay and check each fua/flush (specified by $2) point.
#
# Since dm-log-writes records bio sequentially, even just replaying a range
# still needs to iterate all records before the end point.
# When number of records grows, it will be unacceptably slow, thus we need
# to use relay-log itself to trigger fsck, avoid unnecessary seek.
log_writes_fast_replay_check()
{
	local check_point=$1
	local blkdev=$2
	local fsck_command="$BTRFS_UTIL_PROG check $blkdev"
	local ret

	[ -z "$check_point" -o -z "$blkdev" ] && _fail \
	"check_point and blkdev must be specified for log_writes_fast_replay_check"

	$here/src/log-writes/replay-log --log $LOGWRITES_DEV \
		--replay $blkdev --check $check_point --fsck "$fsck_command" \
		&> $tmp.full_fsck
	ret=$?
	tail -n 150 $tmp.full_fsck >> $seqres.full
	[ $ret -ne 0 ] && _fail "fsck failed during replay"
}

xattr_value=$(printf '%0.sX' $(seq 1 3800))

# Bumping tree height to level 2.
for ((i = 0; i < 64; i++)); do
	touch "$SCRATCH_MNT/src/padding/$i"
	$SETFATTR_PROG -n 'user.x1' -v $xattr_value "$SCRATCH_MNT/src/padding/$i"
done

_log_writes_mark prepare

snapshot_workload &
pid1=$!
delete_workload &
pid2=$!

"$FSSTRESS_PROG" $fsstress_args >> $seqres.full &
sleep $runtime

"$KILLALL_PROG" -q "$FSSTRESS_PROG" &> /dev/null
kill $pid1 &> /dev/null
kill $pid2 &> /dev/null
wait
_log_writes_unmount
_log_writes_remove

log_writes_fast_replay_check fua "$SCRATCH_DEV"

echo "Silence is golden"

# success, all done
status=0
exit