1From 6e4cc3d5eeb2dfaa055e652b5390beaa6c3d05da Mon Sep 17 00:00:00 2001 2From: "lihaoxiang (F)" <lihaoxiang9@huawei.com> 3Date: Thu, 14 Jul 2022 09:32:48 +0800 4Subject: [PATCH] debugfs: teach logdump the -n <num_trans> option 5 6The current version's debugfs possessed the function 7logdump. Executing with option -O could output the log history. But 8when it occurred the block which had no magic number in it's header, 9the program would exit. 10 11Sometimes we were locating problems, needed for more transactions that 12had replayed instead of the latest batch of transactions and we 13weren't hope to display all the history in the meanwhile. So we 14introduced the option -n used for controlling the print of history 15transactions. Specially, this parameter was depending on the option 16-O otherwise it couldn't work. 17 18So in this modification, we used logdump with -O -n <num_trans>. The 19-n options causes logdump to continue past a block with a missing 20magic nuber. Instead, it will terminate only when the entire log has 21been printed or after <num_trans> transactions. 22 23Link: https://lore.kernel.org/r/608df030-593f-8c69-cb65-632a34729d23@huawei.com 24Signed-off-by: lihaoxiang <lihaoxiang9@huawei.com> 25Signed-off-by: Theodore Ts'o <tytso@mit.edu> 26--- 27 debugfs/debugfs.8.in | 13 +++++++++++-- 28 debugfs/logdump.c | 32 ++++++++++++++++++++++++++++---- 29 2 files changed, 39 insertions(+), 6 deletions(-) 30 31diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in 32index aa6128a..a3227a8 100644 33--- a/debugfs/debugfs.8.in 34+++ b/debugfs/debugfs.8.in 35@@ -505,7 +505,7 @@ which is a hard link to 36 .IR filespec . 37 Note this does not adjust the inode reference counts. 38 .TP 39-.BI logdump " [-acsOS] [-b block] [-i filespec] [-f journal_file] [output_file]" 40+.BI logdump " [-acsOS] [-b block] [-n num_trans ] [-i filespec] [-f journal_file] [output_file]" 41 Dump the contents of the ext3 journal. By default, dump the journal inode as 42 specified in the superblock. However, this can be overridden with the 43 .I \-i 44@@ -528,7 +528,7 @@ The 45 .I \-a 46 option causes the 47 .B logdump 48-program to print the contents of all of the descriptor blocks. 49+to print the contents of all of the descriptor blocks. 50 The 51 .I \-b 52 option causes 53@@ -548,6 +548,15 @@ The 54 option causes logdump to display old (checkpointed) journal entries. 55 This can be used to try to track down journal problems even after the 56 journal has been replayed. 57+.IP 58+The 59+.I \-n 60+option causes 61+.B logdump 62+to continue past a journal block which is missing a magic number. 63+Instead, it will stop only when the entire log is printed or after 64+.I num_trans 65+transactions. 66 .TP 67 .BI ls " [-l] [-c] [-d] [-p] [-r] filespec" 68 Print a listing of the files in the directory 69diff --git a/debugfs/logdump.c b/debugfs/logdump.c 70index 6b0133e..614414e 100644 71--- a/debugfs/logdump.c 72+++ b/debugfs/logdump.c 73@@ -48,6 +48,7 @@ enum journal_location {JOURNAL_IS_INTERNAL, JOURNAL_IS_EXTERNAL}; 74 #define ANY_BLOCK ((blk64_t) -1) 75 76 static int dump_all, dump_super, dump_old, dump_contents, dump_descriptors; 77+static int64_t dump_counts; 78 static blk64_t block_to_dump, bitmap_to_dump, inode_block_to_dump; 79 static unsigned int group_to_dump, inode_offset_to_dump; 80 static ext2_ino_t inode_to_dump; 81@@ -113,9 +114,10 @@ void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)), 82 bitmap_to_dump = -1; 83 inode_block_to_dump = ANY_BLOCK; 84 inode_to_dump = -1; 85+ dump_counts = -1; 86 87 reset_getopt(); 88- while ((c = getopt (argc, argv, "ab:ci:f:OsS")) != EOF) { 89+ while ((c = getopt (argc, argv, "ab:ci:f:OsSn:")) != EOF) { 90 switch (c) { 91 case 'a': 92 dump_all++; 93@@ -148,6 +150,14 @@ void do_logdump(int argc, char **argv, int sci_idx EXT2FS_ATTR((unused)), 94 case 'S': 95 dump_super++; 96 break; 97+ case 'n': 98+ dump_counts = strtol(optarg, &tmp, 10); 99+ if (*tmp) { 100+ com_err(argv[0], 0, 101+ "Bad log counts number - %s", optarg); 102+ return; 103+ } 104+ break; 105 default: 106 goto print_usage; 107 } 108@@ -289,7 +299,7 @@ cleanup: 109 return; 110 111 print_usage: 112- fprintf(stderr, "%s: Usage: logdump [-acsOS] [-b<block>] [-i<filespec>]\n\t" 113+ fprintf(stderr, "%s: Usage: logdump [-acsOS] [-n<num_trans>] [-b<block>] [-i<filespec>]\n\t" 114 "[-f<journal_file>] [output_file]\n", argv[0]); 115 } 116 117@@ -369,6 +379,8 @@ static void dump_journal(char *cmdname, FILE *out_file, 118 int fc_done; 119 __u64 total_len; 120 __u32 maxlen; 121+ int64_t cur_counts = 0; 122+ bool exist_no_magic = false; 123 124 /* First, check to see if there's an ext2 superblock header */ 125 retval = read_journal_block(cmdname, source, 0, buf, 2048); 126@@ -459,6 +471,9 @@ static void dump_journal(char *cmdname, FILE *out_file, 127 } 128 129 while (1) { 130+ if (dump_old && (dump_counts != -1) && (cur_counts >= dump_counts)) 131+ break; 132+ 133 retval = read_journal_block(cmdname, source, 134 ((ext2_loff_t) blocknr) * blocksize, 135 buf, blocksize); 136@@ -472,8 +487,16 @@ static void dump_journal(char *cmdname, FILE *out_file, 137 blocktype = be32_to_cpu(header->h_blocktype); 138 139 if (magic != JBD2_MAGIC_NUMBER) { 140- fprintf (out_file, "No magic number at block %u: " 141- "end of journal.\n", blocknr); 142+ if (exist_no_magic == false) { 143+ exist_no_magic = true; 144+ fprintf(out_file, "No magic number at block %u: " 145+ "end of journal.\n", blocknr); 146+ } 147+ if (dump_old && (dump_counts != -1)) { 148+ blocknr++; 149+ WRAP(jsb, blocknr, maxlen); 150+ continue; 151+ } 152 break; 153 } 154 155@@ -500,6 +523,7 @@ static void dump_journal(char *cmdname, FILE *out_file, 156 continue; 157 158 case JBD2_COMMIT_BLOCK: 159+ cur_counts++; 160 transaction++; 161 blocknr++; 162 WRAP(jsb, blocknr, maxlen); 163-- 1641.8.3.1 165 166