Whamcloud - gitweb
LU-17117 debugfs: allow debugfs to disable MMP directly
authorAndreas Dilger <adilger@whamcloud.com>
Fri, 15 Sep 2023 00:42:15 +0000 (18:42 -0600)
committerLi Dongyang <dongyangli@ddn.com>
Tue, 28 May 2024 05:53:20 +0000 (15:53 +1000)
Instead of needing to use "tune2fs -f -E clear_mmp" to clear the
MMP status, it should be possible to open and clear the MMP block
directly with debugfs in case of issues with tune2fs.

Add the "-m" option to debugfs and the "open" command to allow
opening the device and skipping the MMP status check.  Otherwise,
if sequence EXT4_MMP_SEQ_FSCK is set then debugfs will report an
error and the device cannot be not opened for write, even with -f:

    debugfs -f /dev/sdc
    MMP: e2fsck being run while trying to open /dev/sdc

Add the "clear_mmp" command to match the tune2fs extended command.
Add command aliases "mmp_clear", "mmp_dump", and "mmp_set_value"
so that they can be grouped together and found more easily.

Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: I580ba4f30c366b0d0e75596c80cef2892c408fb0
Reviewed-on: https://review.whamcloud.com/c/tools/e2fsprogs/+/52380
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Li Dongyang <dongyangli@ddn.com>
debugfs/debug_cmds.ct
debugfs/debugfs.8.in
debugfs/debugfs.c
misc/tune2fs.c

index 1ff6c9d..d059de1 100644 (file)
@@ -181,11 +181,14 @@ request do_set_current_time, "Set current time to use when setting filesystem fi
 request do_supported_features, "Print features supported by this version of e2fsprogs",
        supported_features;
 
+request do_clear_mmp, "Reset MMP block",
+       clear_mmp, mmp_clear;
+
 request do_dump_mmp, "Dump MMP information",
-       dump_mmp;
+       dump_mmp, mmp_dump;
 
 request do_set_mmp_value, "Set MMP value",
-       set_mmp_value, smmp;
+       set_mmp_value, smmp, mmp_set_value;
 
 request do_extent_open, "Open inode for extent manipulation",
        extent_open, eo;
index 68c363b..2e02679 100644 (file)
@@ -8,7 +8,7 @@ debugfs \- ext2/ext3/ext4 file system debugger
 .SH SYNOPSIS
 .B debugfs
 [
-.B \-DVwcin
+.B \-cDimnwV
 ]
 [
 .B \-b
@@ -56,6 +56,20 @@ Disables metadata checksum verification.  This should only be used if
 you believe the metadata to be correct despite the complaints of
 e2fsprogs.
 .TP
+.I \-m
+Disables MMP status verification on open.  This should only be used if
+you are positive that the filesystem is not in use by another node and
+no other
+.BR e2fsck ,
+.BR tune2fs ,
+.BR debugfs ,
+.BR FUSE ,
+or other program or system is currently accessing it.  Run
+.B "dump_mmp"
+with the filesystem opened read-only, or
+.BI "e2mmpstatus -i" " device"
+to check the current MMP status for the filesystem.
+.TP
 .I \-c
 Specifies that the file system should be opened in catastrophic mode, in
 which the inode and group bitmaps are not read initially.  This can be
@@ -230,6 +244,13 @@ master superblock.
 Clear the contents of the inode
 .IR filespec .
 .TP
+.BI clear_mmp
+Reset the contents of the filesystem multi-mount protection block.
+Use with caution, as this may result in severe filesystem corruption if
+it is currently in use on another node or if e2fsck is running.  Use
+.B \-m
+to override the MMP check at open if debugfs reports is e2fsck being run.
+.TP
 .BI copy_inode " source_inode destination_inode"
 Copy the contents of the inode structure in
 .I source_inode
@@ -644,7 +665,7 @@ to those inodes.  The
 flag will enable checking the file type information in the directory
 entry to make sure it matches the inode's type.
 .TP
-.BI open " [-weficD] [-b blocksize] [-d image_filename] [-s superblock] [-z undo_file] device"
+.BI open " [-cDefimw] [-b blocksize] [-d image_filename] [-s superblock] [-z undo_file] device"
 Open a file system for editing.  The
 .I -f
 flag forces the file system to be opened even if there are some unknown
@@ -652,7 +673,7 @@ or incompatible file system features which would normally
 prevent the file system from being opened.  The
 .I -e
 flag causes the file system to be opened in exclusive mode.  The
-.IR -b ", " -c ", " -d ", " -i ", " -s ", " -w ", and " -D
+.IR -b ", " -c ", " -d ", " -i ", " -m ", " -s ", " -w ", and " -D
 options behave the same as the command-line options to
 .BR debugfs .
 .TP
index 8b4a513..3fc2b8a 100644 (file)
@@ -235,7 +235,7 @@ void do_open_filesys(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused))
        char    *undo_file = NULL;
 
        reset_getopt();
-       while ((c = getopt(argc, argv, "iwfecb:s:d:Dz:")) != EOF) {
+       while ((c = getopt(argc, argv, "b:cd:Defims:wz:")) != EOF) {
                switch (c) {
                case 'i':
                        open_flags |= EXT2_FLAG_IMAGE_FILE;
@@ -268,6 +268,9 @@ void do_open_filesys(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused))
                        if (err)
                                return;
                        break;
+               case 'm':
+                       open_flags |= EXT2_FLAG_SKIP_MMP;
+                       break;
                case 's':
                        err = strtoblk(argv[0], optarg,
                                       "superblock block number", &superblock);
@@ -298,9 +301,9 @@ void do_open_filesys(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused))
 print_usage:
        fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] "
 #ifdef READ_ONLY
-               "[-d image_filename] [-z undo_file] [-c] [-i] [-f] [-e] [-D] "
+               "[-d image_filename] [-z undo_file] [-cDefim] "
 #else
-               "[-d image_filename] [-c] [-i] [-f] [-e] [-D] [-w] "
+               "[-d image_filename] [-cDefimw] "
 #endif
                "<device>\n", argv[0]);
 }
@@ -2486,6 +2489,20 @@ void do_dump_mmp(int argc EXT2FS_ATTR((unused)), ss_argv_t argv,
        fprintf(stdout, "magic: 0x%x\n", mmp_s->mmp_magic);
        fprintf(stdout, "checksum: 0x%08x\n", mmp_s->mmp_checksum);
 }
+
+void do_clear_mmp(int argc EXT2FS_ATTR((unused)), char *argv[],
+                 int sci_idx EXT2FS_ATTR((unused)),
+                 void *infop EXT2FS_ATTR((unused)))
+{
+       errcode_t retval = 0;
+
+       if (check_fs_open(argv[0]))
+               return;
+
+       retval = ext2fs_mmp_clear(current_fs);
+       if (retval)
+               com_err(argv[0], retval, "Error clearing MMP block.\n");
+}
 #else
 void do_dump_mmp(int argc EXT2FS_ATTR((unused)),
                 ss_argv_t argv EXT2FS_ATTR((unused)),
@@ -2495,6 +2512,14 @@ void do_dump_mmp(int argc EXT2FS_ATTR((unused)),
        fprintf(stdout, "MMP is unsupported, please recompile with "
                        "--enable-mmp\n");
 }
+
+void do_clear_mmp(int argc EXT2FS_ATTR((unused)),
+                char *argv[] EXT2FS_ATTR((unused)),
+                int sci_idx EXT2FS_ATTR((unused)),
+                void *infop EXT2FS_ATTR((unused)))
+{
+       do_dump_mmp(argc, argv, sci_idx, infop);
+}
 #endif
 
 static int source_file(const char *cmd_file, int ss_idx)
@@ -2550,7 +2575,7 @@ int main(int argc, char **argv)
                "Usage: %s [-b blocksize] [-s superblock] [-f cmd_file] "
                "[-R request] [-d data_source_device] [-i] [-n] [-D] [-V] ["
 #ifndef READ_ONLY
-               "[-w] [-z undo_file] "
+               "[-m] [-w] [-z undo_file] "
 #endif
                "[-c]] [device]";
        int             c;
@@ -2564,9 +2589,9 @@ int main(int argc, char **argv)
        int             catastrophic = 0;
        char            *data_filename = 0;
 #ifdef READ_ONLY
-       const char      *opt_string = "nicR:f:b:s:Vd:D";
+       const char      *opt_string = "b:cd:Df:inR:s:V";
 #else
-       const char      *opt_string = "niwcR:f:b:s:Vd:Dz:";
+       const char      *opt_string = "b:cd:Df:imnR:s:Vwz:";
 #endif
        char            *undo_file = NULL;
 #ifdef CONFIG_JBD_DEBUG
@@ -2610,6 +2635,9 @@ int main(int argc, char **argv)
                case 'i':
                        open_flags |= EXT2_FLAG_IMAGE_FILE;
                        break;
+               case 'm':
+                       open_flags |= EXT2_FLAG_SKIP_MMP;
+                       break;
                case 'n':
                        open_flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
                        break;
index 9754a5d..31f62c9 100644 (file)
@@ -2392,7 +2392,9 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts)
                        arg++;
                }
                if (strcmp(token, "clear-mmp") == 0 ||
-                   strcmp(token, "clear_mmp") == 0) {
+                   strcmp(token, "clear_mmp") == 0 ||
+                   strcmp(token, "mmp-clear") == 0 ||
+                   strcmp(token, "mmp_clear") == 0) {
                        clear_mmp = 1;
                } else if (strcmp(token, "mmp_update_interval") == 0) {
                        unsigned long intv;