]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_metadump: tag metadump image with informational flags
authorEric Sandeen <sandeen@sandeen.net>
Wed, 21 Jun 2017 22:14:29 +0000 (17:14 -0500)
committerEric Sandeen <sandeen@redhat.com>
Wed, 21 Jun 2017 22:14:29 +0000 (17:14 -0500)
After the long discussion about warning the user and/or consumer
of xfs_metadumps about dirty logs, it crossed my mind that we
could use the reserved slot in the metadump header to tag the
file with attributes, so the consumer of the metadump knows how
it was created.

This patch adds 4 flags to describe the metadump: The first simply
indicates the presence of any (or no) informational flags.
The old mb_reserved field has been 0 on disk since inception, so
the presence of XFS_METADUMP_INFO_FLAGS indicates that this metadump
may contain the informational flags:

 - dirty log
 - obfuscated
 - full blocks (unused portions of metadata blocks
                are not zeroed out).

It then adds a new option to xfs_mdrestore, "-i" to show info,
which can be used with or without a target file:

# xfs_mdrestore -i metadumpfile
metadumpfile: not obfuscated, clean log, full metadata blocks

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
db/metadump.c
include/xfs_metadump.h
man/man8/xfs_mdrestore.8
mdrestore/xfs_mdrestore.c

index 66952f6cb12ee4db21921b1b733545e1fdd75a1a..e83665891499e84546f02c30d9ed7f31ee8148d7 100644 (file)
@@ -2815,6 +2815,28 @@ metadump_f(
        metablock->mb_blocklog = BBSHIFT;
        metablock->mb_magic = cpu_to_be32(XFS_MD_MAGIC);
 
+       /* Set flags about state of metadump */
+       metablock->mb_info = XFS_METADUMP_INFO_FLAGS;
+       if (obfuscate)
+               metablock->mb_info |= XFS_METADUMP_OBFUSCATED;
+       if (!zero_stale_data)
+               metablock->mb_info |= XFS_METADUMP_FULLBLOCKS;
+
+       /* If we'll copy the log, see if the log is dirty */
+       if (mp->m_sb.sb_logstart) {
+               push_cur();
+               set_cur(&typtab[TYP_LOG],
+                       XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
+                       mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN, NULL);
+               if (iocur_top->data) {  /* best effort */
+                       struct xlog     log;
+
+                       if (xlog_is_dirty(mp, &log, &x, 0))
+                               metablock->mb_info |= XFS_METADUMP_DIRTYLOG;
+               }
+               pop_cur();
+       }
+
        block_index = (__be64 *)((char *)metablock + sizeof(xfs_metablock_t));
        block_buffer = (char *)metablock + BBSIZE;
        num_indices = (BBSIZE - sizeof(xfs_metablock_t)) / sizeof(__be64);
index f4be51b42a6e5afae1f8c57f696e68d0c1cd6f15..7f3039eba8692a10127ec730cfaa12d6d545394f 100644 (file)
@@ -25,8 +25,14 @@ typedef struct xfs_metablock {
        __be32          mb_magic;
        __be16          mb_count;
        __uint8_t       mb_blocklog;
-       __uint8_t       mb_reserved;
+       __uint8_t       mb_info;
        /* followed by an array of xfs_daddr_t */
 } xfs_metablock_t;
 
+/* These flags are informational only, not backwards compatible */
+#define XFS_METADUMP_INFO_FLAGS        (1 << 0) /* This image has informative flags */
+#define XFS_METADUMP_OBFUSCATED        (1 << 1)
+#define XFS_METADUMP_FULLBLOCKS        (1 << 2)
+#define XFS_METADUMP_DIRTYLOG  (1 << 3)
+
 #endif /* _XFS_METADUMP_H_ */
index 2095f15d58221fdc3a7e3616d7b8e8a57e0df020..72f3b297787b70af9a326298f749944313e62006 100644 (file)
@@ -4,11 +4,15 @@ xfs_mdrestore \- restores an XFS metadump image to a filesystem image
 .SH SYNOPSIS
 .B xfs_mdrestore
 [
-.B \-g
+.B \-gi
 ]
 .I source
 .I target
 .br
+.B xfs_mdrestore
+.B \-i
+.I source
+.br
 .B xfs_mdrestore \-V
 .SH DESCRIPTION
 .B xfs_mdrestore
@@ -39,6 +43,12 @@ can be destroyed.
 .B \-g
 Shows restore progress on stdout.
 .TP
+.B \-i
+Shows metadump information on stdout.  If no
+.I target
+is specified, exits after displaying information.  Older metadumps man not
+include any descriptive information.
+.TP
 .B \-V
 Prints the version number and exits.
 .SH DIAGNOSTICS
index 0d399f16aaa460c13bf19ce419df06e773077229..9d1b4e8027cccf78fab8b597a36969cbd9918afd 100644 (file)
@@ -21,6 +21,7 @@
 
 char           *progname;
 int            show_progress = 0;
+int            show_info = 0;
 int            progress_since_warning = 0;
 
 static void
@@ -213,11 +214,14 @@ main(
 
        progname = basename(argv[0]);
 
-       while ((c = getopt(argc, argv, "gV")) != EOF) {
+       while ((c = getopt(argc, argv, "giV")) != EOF) {
                switch (c) {
                        case 'g':
                                show_progress = 1;
                                break;
+                       case 'i':
+                               show_info = 1;
+                               break;
                        case 'V':
                                printf("%s version %s\n", progname, VERSION);
                                exit(0);
@@ -226,7 +230,11 @@ main(
                }
        }
 
-       if (argc - optind != 2)
+       if (argc - optind < 1 || argc - optind > 2)
+               usage();
+
+       /* show_info without a target is ok */
+       if (!show_info && argc - optind != 2)
                usage();
 
        /* open source */
@@ -239,6 +247,34 @@ main(
                if (src_f == NULL)
                        fatal("cannot open source dump file\n");
        }
+
+       if (show_info) {
+               xfs_metablock_t         mb;
+
+               if (fread(&mb, sizeof(mb), 1, src_f) != 1)
+                       fatal("error reading from file: %s\n", strerror(errno));
+
+               if (be32_to_cpu(mb.mb_magic) != XFS_MD_MAGIC)
+                       fatal("specified file is not a metadata dump\n");
+
+               if (mb.mb_info & XFS_METADUMP_INFO_FLAGS) {
+                       printf("%s: %sobfuscated, %s log, %s metadata blocks\n",
+                       argv[optind],
+                       mb.mb_info & XFS_METADUMP_OBFUSCATED ? "":"not ",
+                       mb.mb_info & XFS_METADUMP_DIRTYLOG ? "dirty":"clean",
+                       mb.mb_info & XFS_METADUMP_FULLBLOCKS ? "full":"zeroed");
+               } else {
+                       printf("%s: no informational flags present\n",
+                               argv[optind]);
+               }
+
+               if (argc - optind == 1)
+                       exit(0);
+
+               /* Go back to the beginning for the restore function */
+               fseek(src_f, 0L, SEEK_SET);
+       }
+
        optind++;
 
        /* check and open target */