]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_mdrestore: restore rt group superblocks to realtime device
authorDarrick J. Wong <djwong@kernel.org>
Thu, 25 Aug 2022 22:20:05 +0000 (15:20 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 22 Nov 2023 23:03:35 +0000 (15:03 -0800)
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
mdrestore/xfs_mdrestore.c

index f60e7b56ebf0d1128edcaa10368ec7d31d85b0d2..6f6e14e96c6a5c192bc0a4fcbdac14f48ab08543 100644 (file)
@@ -8,6 +8,9 @@ xfs_mdrestore \- restores an XFS metadump image to a filesystem image
 ] [
 .B \-l
 .I logdev
+] [
+.B \-r
+.I rtdev
 ]
 .I source
 .I target
@@ -17,6 +20,9 @@ xfs_mdrestore \- restores an XFS metadump image to a filesystem image
 [
 .B \-l
 .I logdev
+] [
+.B \-r
+.I rtdev
 ]
 .I source
 .br
@@ -61,6 +67,10 @@ Metadump in v2 format can contain metadata dumped from an external log.
 In such a scenario, the user has to provide a device to which the log device
 contents from the metadump file are copied.
 .TP
+.BI \-r " rtdev"
+Restore realtime device metadata to this device.
+This is only required for a metadump in v2 format.
+.TP
 .B \-V
 Prints the version number and exits.
 .SH DIAGNOSTICS
index ad50842ce19f428a795dc41cb1f0b86c722481a8..410e333715dce10039b53d0decb6aee207fa55e9 100644 (file)
@@ -19,8 +19,9 @@ struct mdrestore_ops {
        void (*read_header)(union mdrestore_headers *header, FILE *md_fp);
        void (*show_info)(union mdrestore_headers *header, const char *md_file);
        void (*restore)(union mdrestore_headers *header, FILE *md_fp,
-                       int ddev_fd, bool is_data_target_file, int logdev_fd,
-                       bool is_log_target_file);
+                       int ddev_fd, bool is_data_target_file,
+                       int logdev_fd, bool is_log_target_file,
+                       int rtdev_fd, bool is_rt_target_file);
 };
 
 static struct mdrestore {
@@ -29,6 +30,7 @@ static struct mdrestore {
        bool                    show_info;
        bool                    progress_since_warning;
        bool                    external_log;
+       bool                    realtime_data;
 } mdrestore;
 
 static void
@@ -150,7 +152,9 @@ restore_v1(
        int                     ddev_fd,
        bool                    is_data_target_file,
        int                     logdev_fd,
-       bool                    is_log_target_file)
+       bool                    is_log_target_file,
+       int                     rtdev_fd,
+       bool                    is_rt_target_file)
 {
        struct xfs_metablock    *metablock;     /* header + index + blocks */
        __be64                  *block_index;
@@ -290,8 +294,9 @@ read_header_v2(
            !mdrestore.external_log)
                fatal("External Log device is required\n");
 
-       if (h->v2.xmh_incompat_flags & cpu_to_be32(XFS_MD2_INCOMPAT_RTDEVICE))
-               fatal("Realtime device not yet supported\n");
+       if ((h->v2.xmh_incompat_flags & cpu_to_be32(XFS_MD2_INCOMPAT_RTDEVICE)) &&
+           !mdrestore.realtime_data)
+               fatal("Realtime device is required\n");
 }
 
 static void
@@ -300,14 +305,17 @@ show_info_v2(
        const char              *md_file)
 {
        uint32_t                compat_flags;
+       uint32_t                incompat_flags;
 
        compat_flags = be32_to_cpu(h->v2.xmh_compat_flags);
+       incompat_flags = be32_to_cpu(h->v2.xmh_incompat_flags);
 
-       printf("%s: %sobfuscated, %s log, external log contents are %sdumped, %s metadata blocks,\n",
+       printf("%s: %sobfuscated, %s log, external log contents are %sdumped, rt device contents are %sdumped, %s metadata blocks,\n",
                md_file,
                compat_flags & XFS_MD2_COMPAT_OBFUSCATED ? "":"not ",
                compat_flags & XFS_MD2_COMPAT_DIRTYLOG ? "dirty":"clean",
                compat_flags & XFS_MD2_COMPAT_EXTERNALLOG ? "":"not ",
+               incompat_flags & XFS_MD2_INCOMPAT_RTDEVICE ? "":"not ",
                compat_flags & XFS_MD2_COMPAT_FULLBLOCKS ? "full":"zeroed");
 }
 
@@ -346,7 +354,9 @@ restore_v2(
        int                     ddev_fd,
        bool                    is_data_target_file,
        int                     logdev_fd,
-       bool                    is_log_target_file)
+       bool                    is_log_target_file,
+       int                     rtdev_fd,
+       bool                    is_rt_target_file)
 {
        struct xfs_sb           sb;
        struct xfs_meta_extent  xme;
@@ -415,6 +425,10 @@ restore_v2(
                        device = "log";
                        fd = logdev_fd;
                        break;
+               case XME_ADDR_RT_DEVICE:
+                       device = "rt";
+                       fd = rtdev_fd;
+                       break;
                default:
                        fatal("Invalid device found in metadump\n");
                        break;
@@ -469,7 +483,7 @@ static struct mdrestore_ops mdrestore_ops_v2 = {
 static void
 usage(void)
 {
-       fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] source target\n",
+       fprintf(stderr, "Usage: %s [-V] [-g] [-i] [-l logdev] [-r rtdev] source target\n",
                progname);
        exit(1);
 }
@@ -482,20 +496,24 @@ main(
        union mdrestore_headers headers;
        FILE                    *src_f;
        char                    *logdev = NULL;
+       char                    *rtdev = NULL;
        int                     data_dev_fd = -1;
        int                     log_dev_fd = -1;
+       int                     rt_dev_fd = -1;
        int                     c;
        bool                    is_data_dev_file = false;
        bool                    is_log_dev_file = false;
+       bool                    is_rt_dev_file = false;
 
        mdrestore.show_progress = false;
        mdrestore.show_info = false;
        mdrestore.progress_since_warning = false;
        mdrestore.external_log = false;
+       mdrestore.realtime_data = false;
 
        progname = basename(argv[0]);
 
-       while ((c = getopt(argc, argv, "gil:V")) != EOF) {
+       while ((c = getopt(argc, argv, "gil:r:V")) != EOF) {
                switch (c) {
                        case 'g':
                                mdrestore.show_progress = true;
@@ -507,6 +525,10 @@ main(
                                logdev = optarg;
                                mdrestore.external_log = true;
                                break;
+                       case 'r':
+                               rtdev = optarg;
+                               mdrestore.realtime_data = true;
+                               break;
                        case 'V':
                                printf("%s version %s\n", progname, VERSION);
                                exit(0);
@@ -575,12 +597,20 @@ main(
                /* check and open log device */
                log_dev_fd = open_device(logdev, &is_log_dev_file);
 
-       mdrestore.mdrops->restore(&headers, src_f, data_dev_fd,
-                       is_data_dev_file, log_dev_fd, is_log_dev_file);
+       if (mdrestore.realtime_data)
+               /* check and open realtime device */
+               rt_dev_fd = open_device(rtdev, &is_rt_dev_file);
+
+       mdrestore.mdrops->restore(&headers, src_f,
+                       data_dev_fd, is_data_dev_file,
+                       log_dev_fd, is_log_dev_file,
+                       rt_dev_fd, is_rt_dev_file);
 
        close(data_dev_fd);
        if (mdrestore.external_log)
                close(log_dev_fd);
+       if (mdrestore.realtime_data)
+               close(rt_dev_fd);
 
        if (src_f != stdin)
                fclose(src_f);