]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_db: Add support to read from external log device
authorChandan Babu R <chandan.babu@oracle.com>
Mon, 6 Nov 2023 13:10:45 +0000 (18:40 +0530)
committerCarlos Maiolino <cem@kernel.org>
Tue, 21 Nov 2023 13:09:36 +0000 (14:09 +0100)
This commit introduces a new function set_log_cur() allowing xfs_db to read
from an external log device. This is required by a future commit which will
add the ability to dump metadata from external log devices.

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
db/io.c
db/io.h
db/metadump.c
db/xfs_metadump.sh
man/man8/xfs_metadump.8

diff --git a/db/io.c b/db/io.c
index 3d2572364d398d1ef8e0e6893568190a57e55ebe..5ccfe3b536a0296b0b1c303a16e5f1b02832f317 100644 (file)
--- a/db/io.c
+++ b/db/io.c
@@ -508,18 +508,19 @@ write_cur(void)
 
 }
 
-void
-set_cur(
-       const typ_t     *type,
-       xfs_daddr_t     blknum,
-       int             len,
-       int             ring_flag,
-       bbmap_t         *bbmap)
+static void
+__set_cur(
+       struct xfs_buftarg      *btargp,
+       const typ_t             *type,
+       xfs_daddr_t              blknum,
+       int                      len,
+       int                      ring_flag,
+       bbmap_t                 *bbmap)
 {
-       struct xfs_buf  *bp;
-       xfs_ino_t       dirino;
-       xfs_ino_t       ino;
-       uint16_t        mode;
+       struct xfs_buf          *bp;
+       xfs_ino_t               dirino;
+       xfs_ino_t               ino;
+       uint16_t                mode;
        const struct xfs_buf_ops *ops = type ? type->bops : NULL;
        int             error;
 
@@ -548,11 +549,11 @@ set_cur(
                if (!iocur_top->bbmap)
                        return;
                memcpy(iocur_top->bbmap, bbmap, sizeof(struct bbmap));
-               error = -libxfs_buf_read_map(mp->m_ddev_targp, bbmap->b,
+               error = -libxfs_buf_read_map(btargp, bbmap->b,
                                bbmap->nmaps, LIBXFS_READBUF_SALVAGE, &bp,
                                ops);
        } else {
-               error = -libxfs_buf_read(mp->m_ddev_targp, blknum, len,
+               error = -libxfs_buf_read(btargp, blknum, len,
                                LIBXFS_READBUF_SALVAGE, &bp, ops);
                iocur_top->bbmap = NULL;
        }
@@ -589,6 +590,35 @@ set_cur(
                ring_add();
 }
 
+void
+set_cur(
+       const typ_t     *type,
+       xfs_daddr_t     blknum,
+       int             len,
+       int             ring_flag,
+       bbmap_t         *bbmap)
+{
+       __set_cur(mp->m_ddev_targp, type, blknum, len, ring_flag, bbmap);
+}
+
+void
+set_log_cur(
+       const typ_t     *type,
+       xfs_daddr_t     blknum,
+       int             len,
+       int             ring_flag,
+       bbmap_t         *bbmap)
+{
+       if (mp->m_logdev_targp->bt_bdev == mp->m_ddev_targp->bt_bdev) {
+               fprintf(stderr, "no external log specified\n");
+               exitcode = 1;
+               return;
+       }
+
+       __set_cur(mp->m_logdev_targp, type, blknum, len, ring_flag, bbmap);
+}
+
+
 void
 set_iocur_type(
        const typ_t     *type)
diff --git a/db/io.h b/db/io.h
index c29a7488198991460f21c81d35b118e89cdd1b55..bd86c31f67e58b37f494a1a7040902375169dcf5 100644 (file)
--- a/db/io.h
+++ b/db/io.h
@@ -49,6 +49,8 @@ extern void   push_cur_and_set_type(void);
 extern void    write_cur(void);
 extern void    set_cur(const struct typ *type, xfs_daddr_t blknum,
                        int len, int ring_add, bbmap_t *bbmap);
+extern void    set_log_cur(const struct typ *type, xfs_daddr_t blknum,
+                       int len, int ring_add, bbmap_t *bbmap);
 extern void     ring_add(void);
 extern void    set_iocur_type(const struct typ *type);
 extern void    xfs_dummy_verify(struct xfs_buf *bp);
index 81023cf17886edc02c824008f82755f49d2e40a4..f9c82148e7dfb0763ec7f37151d9e5c3d22dba6f 100644 (file)
@@ -38,7 +38,7 @@ static void   metadump_help(void);
 
 static const cmdinfo_t metadump_cmd =
        { "metadump", NULL, metadump_f, 0, -1, 0,
-               N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] filename"),
+               N_("[-a] [-e] [-g] [-m max_extent] [-w] [-o] [-v 1|2] filename"),
                N_("dump metadata to a file"), metadump_help };
 
 struct metadump_ops {
@@ -75,6 +75,7 @@ static struct metadump {
        bool                    zero_stale_data;
        bool                    progress_since_warning;
        bool                    dirty_log;
+       bool                    external_log;
        bool                    stdout_metadump;
        xfs_ino_t               cur_ino;
        /* Metadump file */
@@ -108,6 +109,7 @@ metadump_help(void)
 "   -g -- Display dump progress\n"
 "   -m -- Specify max extent size in blocks to copy (default = %d blocks)\n"
 "   -o -- Don't obfuscate names and extended attributes\n"
+"   -v -- Metadump version to be used\n"
 "   -w -- Show warnings of bad metadata information\n"
 "\n"), DEFAULT_MAX_EXT_SIZE);
 }
@@ -2589,8 +2591,20 @@ copy_log(void)
                print_progress("Copying log");
 
        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 (metadump.external_log) {
+               ASSERT(mp->m_sb.sb_logstart == 0);
+               set_log_cur(&typtab[TYP_LOG],
+                               XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
+                               mp->m_sb.sb_logblocks * blkbb, DB_RING_IGN,
+                               NULL);
+       } else {
+               ASSERT(mp->m_sb.sb_logstart != 0);
+               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 == NULL) {
                pop_cur();
                print_warning("cannot read log");
@@ -2751,6 +2765,8 @@ init_metadump_v2(void)
                compat_flags |= XFS_MD2_COMPAT_FULLBLOCKS;
        if (metadump.dirty_log)
                compat_flags |= XFS_MD2_COMPAT_DIRTYLOG;
+       if (metadump.external_log)
+               compat_flags |= XFS_MD2_COMPAT_EXTERNALLOG;
 
        xmh.xmh_compat_flags = cpu_to_be32(compat_flags);
 
@@ -2811,6 +2827,7 @@ metadump_f(
        int             outfd = -1;
        int             ret;
        char            *p;
+       bool            version_opt_set = false;
 
        exitcode = 1;
 
@@ -2822,6 +2839,7 @@ metadump_f(
        metadump.obfuscate = true;
        metadump.zero_stale_data = true;
        metadump.dirty_log = false;
+       metadump.external_log = false;
 
        if (mp->m_sb.sb_magicnum != XFS_SB_MAGIC) {
                print_warning("bad superblock magic number %x, giving up",
@@ -2839,7 +2857,7 @@ metadump_f(
                return 0;
        }
 
-       while ((c = getopt(argc, argv, "aegm:ow")) != EOF) {
+       while ((c = getopt(argc, argv, "aegm:ov:w")) != EOF) {
                switch (c) {
                        case 'a':
                                metadump.zero_stale_data = false;
@@ -2863,6 +2881,17 @@ metadump_f(
                        case 'o':
                                metadump.obfuscate = false;
                                break;
+                       case 'v':
+                               metadump.version = (int)strtol(optarg, &p, 0);
+                               if (*p != '\0' ||
+                                   (metadump.version != 1 &&
+                                               metadump.version != 2)) {
+                                       print_warning("bad metadump version: %s",
+                                               optarg);
+                                       return 0;
+                               }
+                               version_opt_set = true;
+                               break;
                        case 'w':
                                metadump.show_warnings = true;
                                break;
@@ -2877,12 +2906,42 @@ metadump_f(
                return 0;
        }
 
-       /* If we'll copy the log, see if the log is dirty */
-       if (mp->m_sb.sb_logstart) {
+       if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
+               metadump.external_log = true;
+
+       if (metadump.external_log && !version_opt_set)
+               metadump.version = 2;
+
+       if (metadump.version == 2 && mp->m_sb.sb_logstart == 0 &&
+           !metadump.external_log) {
+               print_warning("external log device not loaded, use -l");
+               return 1;
+       }
+
+       /*
+        * If we'll copy the log, see if the log is dirty.
+        *
+        * Metadump v1 does not support dumping the contents of an external
+        * log. Hence we skip the dirty log check.
+        */
+       if (!(metadump.version == 1 && metadump.external_log)) {
                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 (metadump.external_log) {
+                       ASSERT(mp->m_sb.sb_logstart == 0);
+                       set_log_cur(&typtab[TYP_LOG],
+                                       XFS_FSB_TO_DADDR(mp,
+                                                       mp->m_sb.sb_logstart),
+                                       mp->m_sb.sb_logblocks * blkbb,
+                                       DB_RING_IGN, NULL);
+               } else {
+                       ASSERT(mp->m_sb.sb_logstart != 0);
+                       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;
 
@@ -2958,8 +3017,8 @@ metadump_f(
        if (!exitcode)
                exitcode = !copy_sb_inodes();
 
-       /* copy log if it's internal */
-       if ((mp->m_sb.sb_logstart != 0) && !exitcode)
+       /* copy log */
+       if (!exitcode && !(metadump.version == 1 && metadump.external_log))
                exitcode = !copy_log();
 
        /* write the remaining index */
index 9852a5bc2b0ff07afc722cc3d2754005023f3d21..9e8f86e53eb45da0c2a12da65f23700474a893a0 100755 (executable)
@@ -8,7 +8,7 @@ OPTS=" "
 DBOPTS=" "
 USAGE="Usage: xfs_metadump [-aefFogwV] [-m max_extents] [-l logdev] source target"
 
-while getopts "aefgl:m:owFV" c
+while getopts "aefgl:m:owFv:V" c
 do
        case $c in
        a)      OPTS=$OPTS"-a ";;
@@ -20,6 +20,7 @@ do
        f)      DBOPTS=$DBOPTS" -f";;
        l)      DBOPTS=$DBOPTS" -l "$OPTARG" ";;
        F)      DBOPTS=$DBOPTS" -F";;
+       v)      OPTS=$OPTS"-v "$OPTARG" ";;
        V)      xfs_db -p xfs_metadump -V
                status=$?
                exit $status
index c0e79d77993787a44ffe8a4b1fb80b84f79ac397..1732012cd0cd061e822a7fa96279f4085e4bc1a6 100644 (file)
@@ -11,6 +11,9 @@ xfs_metadump \- copy XFS filesystem metadata to a file
 ] [
 .B \-l
 .I logdev
+] [
+.B \-v
+.I version
 ]
 .I source
 .I target
@@ -74,6 +77,12 @@ metadata such as filenames is not considered sensitive.  If obfuscation
 is required on a metadump with a dirty log, please inform the recipient
 of the metadump image about this situation.
 .PP
+The contents of an external log device can be dumped only when using the v2
+format.
+Metadump in v2 format can be generated by passing the "-v 2" option.
+Metadump in v2 format is generated by default if the filesystem has an
+external log and the metadump version to use is not explicitly mentioned.
+.PP
 .B xfs_metadump
 should not be used for any purposes other than for debugging and reporting
 filesystem problems. The most common usage scenario for this tool is when
@@ -134,6 +143,11 @@ this value.  The default size is 2097151 blocks.
 .B \-o
 Disables obfuscation of file names and extended attributes.
 .TP
+.B \-v
+The format of the metadump file to be produced.
+Valid values are 1 and 2.
+The default metadump format is 1.
+.TP
 .B \-w
 Prints warnings of inconsistent metadata encountered to stderr. Bad metadata
 is still copied.