From: Darrick J. Wong <djwong@xxxxxxxxxx> Support restoring realtime device metadata to the realtime device, if the dumped filesystem had one. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- man/man8/xfs_mdrestore.8 | 7 +++++++ mdrestore/xfs_mdrestore.c | 30 ++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) 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)