diff mbox series

[35/45] xfs_mdrestore: restore rt group superblocks to realtime device

Message ID 167243878823.731133.6732858030193291234.stgit@magnolia (mailing list archive)
State Superseded, archived
Headers show
Series libxfs: shard the realtime section | expand

Commit Message

Darrick J. Wong Dec. 30, 2022, 10:19 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Support restoring realtime device metadata to the realtime device, if
the dumped filesystem had one.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 man/man8/xfs_mdrestore.8  |    7 +++++++
 mdrestore/xfs_mdrestore.c |   30 ++++++++++++++++++++++++------
 2 files changed, 31 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/man/man8/xfs_mdrestore.8 b/man/man8/xfs_mdrestore.8
index 4626b98e749..4a6b335a380 100644
--- a/man/man8/xfs_mdrestore.8
+++ b/man/man8/xfs_mdrestore.8
@@ -7,6 +7,8 @@  xfs_mdrestore \- restores an XFS metadump image to a filesystem image
 .B \-gi
 ] [
 .B \-l logdev
+] [
+.B \-R rtdev
 ]
 .I source
 .I target
@@ -15,6 +17,8 @@  xfs_mdrestore \- restores an XFS metadump image to a filesystem image
 .B \-i
 [
 .B \-l logdev
+] [
+.B \-R rtdev
 ]
 .I source
 .br
@@ -57,6 +61,9 @@  Shows metadump information on stdout.  If no
 is specified, exits after displaying information.  Older metadumps man not
 include any descriptive information.
 .TP
+.B \-R
+Restore realtime device metadata to this device.
+.TP
 .B \-V
 Prints the version number and exits.
 .SH DIAGNOSTICS
diff --git a/mdrestore/xfs_mdrestore.c b/mdrestore/xfs_mdrestore.c
index 672010bcc6e..b75b30830ea 100644
--- a/mdrestore/xfs_mdrestore.c
+++ b/mdrestore/xfs_mdrestore.c
@@ -115,7 +115,8 @@  perform_restore(
 	int			dst_fd,
 	int			is_target_file,
 	const struct xfs_metablock	*mbp,
-	char			*log_path)
+	char			*log_path,
+	char			*rtdev_path)
 {
 	struct xfs_metablock	*metablock;	/* header + index + blocks */
 	__be64			*block_index;
@@ -127,7 +128,7 @@  perform_restore(
 	xfs_sb_t		sb;
 	int64_t			bytes_read;
 	int64_t			mb_read = 0;
-	int			log_fd = -1;
+	int			log_fd = -1, rtdev_fd = -1;
 	bool			is_mdx;
 
 	is_mdx = mbp->mb_magic == cpu_to_be32(XFS_MDX_MAGIC);
@@ -201,9 +202,19 @@  perform_restore(
 			write_fd = log_fd;
 		}
 		if (metablock->mb_info & XFS_METADUMP_RTDEV) {
+			int rtdev_is_file;
+
 			if (!is_mdx)
 				fatal("rtdev set on an old style metadump?\n");
-			fatal("rtdev not supported\n");
+			if (rtdev_fd == -1) {
+				if (!rtdev_path)
+					fatal(
+	"metadump has rtdev contents but -R was not specified?\n");
+				rtdev_fd = open_device(rtdev_path, &rtdev_is_file);
+				check_dev(rtdev_fd, rtdev_is_file,
+						sb.sb_rblocks * sb.sb_blocksize);
+			}
+			write_fd = rtdev_fd;
 		}
 
 		if (show_progress) {
@@ -267,6 +278,8 @@  perform_restore(
 	if (pwrite(dst_fd, block_buffer, sb.sb_sectsize, 0) < 0)
 		fatal("error writing primary superblock: %s\n", strerror(errno));
 
+	if (rtdev_fd >= 0)
+		close(rtdev_fd);
 	if (log_fd >= 0)
 		close(log_fd);
 
@@ -276,7 +289,7 @@  perform_restore(
 static void
 usage(void)
 {
-	fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] source target\n", progname);
+	fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] [-R rtdev] source target\n", progname);
 	exit(1);
 }
 
@@ -286,6 +299,7 @@  main(
 	char 		**argv)
 {
 	char		*log_path = NULL;
+	char		*rtdev_path = NULL;
 	FILE		*src_f;
 	int		dst_fd;
 	int		c;
@@ -294,7 +308,7 @@  main(
 
 	progname = basename(argv[0]);
 
-	while ((c = getopt(argc, argv, "gl:iV")) != EOF) {
+	while ((c = getopt(argc, argv, "gl:iVR:")) != EOF) {
 		switch (c) {
 			case 'g':
 				show_progress = 1;
@@ -308,6 +322,9 @@  main(
 			case 'V':
 				printf("%s version %s\n", progname, VERSION);
 				exit(0);
+			case 'R':
+				rtdev_path = optarg;
+				break;
 			default:
 				usage();
 		}
@@ -363,7 +380,8 @@  main(
 	/* check and open target */
 	dst_fd = open_device(argv[optind], &is_target_file);
 
-	perform_restore(src_f, dst_fd, is_target_file, &mb, log_path);
+	perform_restore(src_f, dst_fd, is_target_file, &mb, log_path,
+			rtdev_path);
 
 	close(dst_fd);
 	if (src_f != stdin)