diff mbox series

[1/4] common: capture metadump output if xfs filesystem check fails

Message ID 161526475154.1212855.395880843881325184.stgit@magnolia (mailing list archive)
State New, archived
Headers show
Series fstests: improve metadata dump capture helpers | expand

Commit Message

Darrick J. Wong March 9, 2021, 4:39 a.m. UTC
From: Darrick J. Wong <djwong@djwong.org>

Capture metadump output when various userspace repair and checker tools
fail or indicate corruption, to aid in debugging.  We don't bother to
annotate xfs_check because it's bitrotting.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 README     |    2 ++
 common/xfs |   50 ++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 46 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/README b/README
index 43bb0cee..b00328ac 100644
--- a/README
+++ b/README
@@ -109,6 +109,8 @@  Preparing system for tests:
              - Set TEST_FS_MODULE_RELOAD=1 to unload the module and reload
                it between test invocations.  This assumes that the name of
                the module is the same as FSTYP.
+             - Set DUMP_CORRUPT_FS=1 to record metadata dumps of XFS
+               filesystems if a filesystem check fails.
 
         - or add a case to the switch in common/config assigning
           these variables based on the hostname of your test
diff --git a/common/xfs b/common/xfs
index 2156749d..b30d289f 100644
--- a/common/xfs
+++ b/common/xfs
@@ -432,6 +432,27 @@  _supports_xfs_scrub()
 	return 0
 }
 
+# Save a snapshot of a corrupt xfs filesystem for later debugging.
+_xfs_metadump() {
+	local metadump="$1"
+	local device="$2"
+	local logdev="$3"
+	local compressopt="$4"
+	shift; shift; shift; shift
+	local options="$@"
+	test -z "$options" && options="-a -o"
+
+	if [ "$logdev" != "none" ]; then
+		options="$options -l $logdev"
+	fi
+
+	$XFS_METADUMP_PROG $options "$device" "$metadump"
+	res=$?
+	[ "$compressopt" = "compress" ] && [ -n "$DUMP_COMPRESSOR" ] &&
+		$DUMP_COMPRESSOR "$metadump" &> /dev/null
+	return $res
+}
+
 # run xfs_check and friends on a FS.
 _check_xfs_filesystem()
 {
@@ -448,14 +469,16 @@  _check_xfs_filesystem()
 		extra_options="-f"
 	fi
 
-	if [ "$2" != "none" ]; then
-		extra_log_options="-l$2"
-		extra_mount_options="-ologdev=$2"
+	local logdev="$2"
+	if [ "$logdev" != "none" ]; then
+		extra_log_options="-l$logdev"
+		extra_mount_options="-ologdev=$logdev"
 	fi
 
-	if [ "$3" != "none" ]; then
-		extra_rt_options="-r$3"
-		extra_mount_options=$extra_mount_options" -ortdev=$3"
+	local rtdev="$3"
+	if [ "$rtdev" != "none" ]; then
+		extra_rt_options="-r$rtdev"
+		extra_mount_options=$extra_mount_options" -ortdev=$rtdev"
 	fi
 	extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS"
 
@@ -520,8 +543,15 @@  _check_xfs_filesystem()
 	fi
 	rm -f $tmp.fs_check $tmp.logprint $tmp.repair
 
+	if [ "$ok" -ne 1 ] && [ "$DUMP_CORRUPT_FS" = "1" ]; then
+		local flatdev="$(basename "$device")"
+		_xfs_metadump "$seqres.$flatdev.check.md" "$device" "$logdev" \
+			compress >> $seqres.full
+	fi
+
 	# Optionally test the index rebuilding behavior.
 	if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then
+		rebuild_ok=1
 		$XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1
 		if [ $? -ne 0 ]; then
 			_log_err "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)"
@@ -530,6 +560,7 @@  _check_xfs_filesystem()
 			echo "*** end xfs_repair output"	>>$seqres.full
 
 			ok=0
+			rebuild_ok=0
 		fi
 		rm -f $tmp.repair
 
@@ -541,8 +572,15 @@  _check_xfs_filesystem()
 			echo "*** end xfs_repair output"	>>$seqres.full
 
 			ok=0
+			rebuild_ok=0
 		fi
 		rm -f $tmp.repair
+
+		if [ "$rebuild_ok" -ne 1 ] && [ "$DUMP_CORRUPT_FS" = "1" ]; then
+			local flatdev="$(basename "$device")"
+			_xfs_metadump "$seqres.$flatdev.rebuild.md" "$device" \
+				"$logdev" compress >> $seqres.full
+		fi
 	fi
 
 	if [ $ok -eq 0 ]; then