summaryrefslogtreecommitdiff
path: root/common/metadump
blob: 3373edfe92efd6d17174359737c6db92971698ff (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
##/bin/bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2024 Oracle.  All Rights Reserved.
#
# Filesystem metadata dump testing functions.
#

# Set up environment variables for a metadump test.  Requires the test and
# scratch devices.  Sets XFS_METADUMP_{FILE,IMG} and MAX_XFS_METADUMP_VERSION.
_xfs_setup_verify_metadump()
{
	XFS_METADUMP_FILE="$TEST_DIR/${seq}_metadump"
	XFS_METADUMP_IMG="$TEST_DIR/${seq}_image"
	MAX_XFS_METADUMP_VERSION="$(_xfs_metadump_max_version)"

	rm -f "$XFS_METADUMP_FILE" "$XFS_METADUMP_IMG"*
}

_xfs_cleanup_verify_metadump()
{
	local img

	_scratch_unmount &>> $seqres.full

	test -n "$XFS_METADUMP_FILE" && rm -f "$XFS_METADUMP_FILE"

	if [ -n "$XFS_METADUMP_IMG" ]; then
		losetup -n -a -O BACK-FILE,NAME | grep "^$XFS_METADUMP_IMG" | while read backing ldev; do
			losetup -d "$ldev"
		done

		# Don't call rm directly with a globbed argument here to avoid
		# issues issues with variable expansions.
		for img in "$XFS_METADUMP_IMG"*; do
			test -e "$img" && rm -f "$img"
		done
	fi
}

# Can xfs_metadump snapshot the fs metadata to a v1 metadump file?
_scratch_xfs_can_metadump_v1()
{
	# metadump v1 does not support log devices
	[ "$USE_EXTERNAL" = yes ] && [ -n "$SCRATCH_LOGDEV" ] && return 1

	# metadump v1 does not support realtime devices
	[ "$USE_EXTERNAL" = yes ] && [ -n "$SCRATCH_RTDEV" ] && return 1

	return 0
}

# Can xfs_metadump snapshot the fs metadata to a v2 metadump file?
_scratch_xfs_can_metadump_v2()
{
	test "$MAX_XFS_METADUMP_VERSION" -ge 2
}

# Create a metadump in v1 format, restore it to fs image files, then mount the
# images and fsck them.
_xfs_verify_metadump_v1()
{
	local metadump_args="$1"
	local extra_test="$2"

	local metadump_file="$XFS_METADUMP_FILE"
	local version=""
	local data_img="$XFS_METADUMP_IMG.data"
	local data_loop

	# Force v1 if we detect v2 support
	if [[ $MAX_XFS_METADUMP_FORMAT > 1 ]]; then
		version="-v 1"
	fi

	# Capture metadump, which creates metadump_file
	_scratch_xfs_metadump $metadump_file $metadump_args $version

	# Restore metadump, which creates data_img
	SCRATCH_DEV=$data_img _scratch_xfs_mdrestore $metadump_file

	# Create loopdev for data device so we can mount the fs
	data_loop=$(_create_loop_device $data_img)

	# Mount fs, run an extra test, fsck, and unmount
	SCRATCH_DEV=$data_loop _scratch_mount
	if [ -n "$extra_test" ]; then
		SCRATCH_DEV=$data_loop $extra_test
	fi
	SCRATCH_DEV=$data_loop _check_xfs_scratch_fs
	SCRATCH_DEV=$data_loop _scratch_unmount

	# Tear down what we created
	_destroy_loop_device $data_loop
	rm -f $data_img
}

# Create a metadump in v2 format, restore it to fs image files, then mount the
# images and fsck them.
_xfs_verify_metadump_v2()
{
	local metadump_args="$1"
	local extra_test="$2"

	local metadump_file="$XFS_METADUMP_FILE"
	local version="-v 2"
	local data_img="$XFS_METADUMP_IMG.data"
	local data_loop
	local log_img=""
	local log_loop

	# Capture metadump, which creates metadump_file
	_scratch_xfs_metadump $metadump_file $metadump_args $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.
	test -n "$SCRATCH_LOGDEV" && log_img="$XFS_METADUMP_IMG.log"

	# Restore metadump, which creates data_img and log_img
	SCRATCH_DEV=$data_img SCRATCH_LOGDEV=$log_img \
		_scratch_xfs_mdrestore $metadump_file

	# Create loopdev for data device so we can mount the fs
	data_loop=$(_create_loop_device $data_img)

	# Create loopdev for log device if we recovered anything
	test -s "$log_img" && log_loop=$(_create_loop_device $log_img)

	# Mount fs, run an extra test, fsck, and unmount
	SCRATCH_DEV=$data_loop SCRATCH_LOGDEV=$log_loop _scratch_mount
	if [ -n "$extra_test" ]; then
		SCRATCH_DEV=$data_loop SCRATCH_LOGDEV=$log_loop $extra_test
	fi
	SCRATCH_DEV=$data_loop SCRATCH_LOGDEV=$log_loop _check_xfs_scratch_fs
	SCRATCH_DEV=$data_loop _scratch_unmount

	# Tear down what we created
	if [ -b "$log_loop" ]; then
		_destroy_loop_device $log_loop
		rm -f $log_img
	fi
	_destroy_loop_device $data_loop
	rm -f $data_img
}

# Verify both metadump formats if possible
_xfs_verify_metadumps()
{
	_scratch_xfs_can_metadump_v1 && _xfs_verify_metadump_v1 "$@"
	_scratch_xfs_can_metadump_v2 && _xfs_verify_metadump_v2 "$@"
}