X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=debugfs%2Flogdump.c;h=2bf67b575e04a5fa3d3044c36d53403d531a61ef;hb=dcf7b091c3efb2e6218a1f139ef2823db9d7c4bb;hp=c7a5ca944339197c9ce501958322cd16985b482b;hpb=e1018eeaa3285cd0ca26986d929194c1b577d211;p=tools%2Fe2fsprogs.git diff --git a/debugfs/logdump.c b/debugfs/logdump.c index c7a5ca9..2bf67b5 100644 --- a/debugfs/logdump.c +++ b/debugfs/logdump.c @@ -28,16 +28,16 @@ extern int optind; extern char *optarg; #endif -#ifdef HAVE_OPTRESET -extern int optreset; /* defined by BSD, but not others */ -#endif #include "debugfs.h" +#include "blkid/blkid.h" #include "jfs_user.h" #include enum journal_location {JOURNAL_IS_INTERNAL, JOURNAL_IS_EXTERNAL}; +#define ANY_BLOCK ((unsigned int) -1) + int dump_all, dump_contents, dump_descriptors; unsigned int block_to_dump, group_to_dump, bitmap_to_dump; unsigned int inode_block_to_dump, inode_offset_to_dump, bitmap_to_dump; @@ -70,7 +70,6 @@ static void do_hexdump (FILE *, char *, int); blocknr -= (be32_to_cpu((jsb)->s_maxlen) - \ be32_to_cpu((jsb)->s_first)); - void do_logdump(int argc, char **argv) { int c; @@ -81,34 +80,27 @@ void do_logdump(int argc, char **argv) char *inode_spec = NULL; char *journal_fn = NULL; int journal_fd = 0; + int use_sb = 0; ext2_ino_t journal_inum; struct ext2_inode journal_inode; ext2_file_t journal_file; - char *tmp; - - const char *logdump_usage = ("Usage: logdump " - "[-ac] [-b] [-i] " - "[-f] [output_file]"); - struct journal_source journal_source; - - optind = 0; -#ifdef HAVE_OPTRESET - optreset = 1; /* Makes BSD getopt happy */ -#endif + struct ext2_super_block *es = NULL; + journal_source.where = 0; journal_source.fd = 0; journal_source.file = 0; dump_all = 0; dump_contents = 0; dump_descriptors = 1; - block_to_dump = -1; + block_to_dump = ANY_BLOCK; bitmap_to_dump = -1; - inode_block_to_dump = -1; + inode_block_to_dump = ANY_BLOCK; inode_to_dump = -1; - while ((c = getopt (argc, argv, "ab:ci:f:")) != EOF) { + reset_getopt(); + while ((c = getopt (argc, argv, "ab:ci:f:s")) != EOF) { switch (c) { case 'a': dump_all++; @@ -132,19 +124,23 @@ void do_logdump(int argc, char **argv) inode_spec = optarg; dump_descriptors = 0; break; + case 's': + use_sb++; + break; default: - com_err(argv[0], 0, logdump_usage); - return; + goto print_usage; } } if (optind != argc && optind != argc-1) { - com_err(argv[0], 0, logdump_usage); - return; + goto print_usage; } + if (current_fs) + es = current_fs->super; + if (inode_spec) { int inode_group, group_offset, inodes_per_block; - + if (check_fs_open(argv[0])) return; @@ -153,9 +149,9 @@ void do_logdump(int argc, char **argv) return; inode_group = ((inode_to_dump - 1) - / current_fs->super->s_inodes_per_group); + / es->s_inodes_per_group); group_offset = ((inode_to_dump - 1) - % current_fs->super->s_inodes_per_group); + % es->s_inodes_per_group); inodes_per_block = (current_fs->blocksize / sizeof(struct ext2_inode)); @@ -174,22 +170,22 @@ void do_logdump(int argc, char **argv) } else { out_fn = argv[optind]; out_file = fopen(out_fn, "w"); - if (!out_file < 0) { + if (!out_file) { com_err(argv[0], errno, "while opening %s for logdump", out_fn); - return; + goto errout; } } - if (block_to_dump != -1 && current_fs != NULL) { + if (block_to_dump != ANY_BLOCK && current_fs != NULL) { group_to_dump = ((block_to_dump - - current_fs->super->s_first_data_block) - / current_fs->super->s_blocks_per_group); + es->s_first_data_block) + / es->s_blocks_per_group); bitmap_to_dump = current_fs->group_desc[group_to_dump].bg_block_bitmap; } if (!journal_fn && check_fs_open(argv[0])) - return; + goto errout; if (journal_fn) { /* Set up to read journal from a regular file somewhere */ @@ -197,40 +193,61 @@ void do_logdump(int argc, char **argv) if (journal_fd < 0) { com_err(argv[0], errno, "while opening %s for logdump", journal_fn); - return; + goto errout; } journal_source.where = JOURNAL_IS_EXTERNAL; journal_source.fd = journal_fd; - } else if ((journal_inum = current_fs->super->s_journal_inum)) { - if (debugfs_read_inode(journal_inum, &journal_inode, argv[0])) - return; - - retval = ext2fs_file_open(current_fs, journal_inum, - 0, &journal_file); + } else if ((journal_inum = es->s_journal_inum)) { + if (use_sb) { + if (es->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS) { + com_err(argv[0], 0, + "no journal backup in super block\n"); + goto errout; + } + memset(&journal_inode, 0, sizeof(struct ext2_inode)); + memcpy(&journal_inode.i_block[0], es->s_jnl_blocks, + EXT2_N_BLOCKS*4); + journal_inode.i_size = es->s_jnl_blocks[16]; + journal_inode.i_links_count = 1; + journal_inode.i_mode = LINUX_S_IFREG | 0600; + } else { + if (debugfs_read_inode(journal_inum, &journal_inode, + argv[0])) + goto errout; + } + + retval = ext2fs_file_open2(current_fs, journal_inum, + &journal_inode, 0, &journal_file); if (retval) { com_err(argv[0], retval, "while opening ext2 file"); - return; + goto errout; } journal_source.where = JOURNAL_IS_INTERNAL; journal_source.file = journal_file; - } else if ((journal_fn = - ext2fs_find_block_device(current_fs->super->s_journal_dev))) { + } else { + char uuid[37]; + + uuid_unparse(es->s_journal_uuid, uuid); + journal_fn = blkid_get_devname(NULL, "UUID", uuid); + if (!journal_fn) + journal_fn = blkid_devno_to_devname(es->s_journal_dev); + if (!journal_fn) { + com_err(argv[0], 0, "filesystem has no journal"); + goto errout; + } journal_fd = open(journal_fn, O_RDONLY, 0); if (journal_fd < 0) { com_err(argv[0], errno, "while opening %s for logdump", journal_fn); free(journal_fn); - return; + goto errout; } fprintf(out_file, "Using external journal found at %s\n", journal_fn); free(journal_fn); journal_source.where = JOURNAL_IS_EXTERNAL; journal_source.fd = journal_fd; - } else { - com_err(argv[0], 0, "filesystem has no journal"); - return; } dump_journal(argv[0], out_file, &journal_source); @@ -240,10 +257,15 @@ void do_logdump(int argc, char **argv) else close(journal_fd); +errout: if (out_file != stdout) fclose(out_file); return; + +print_usage: + fprintf(stderr, "%s: Usage: logdump [-ac] [-b] [-i]\n\t" + "[-f] [output_file]\n", argv[0]); } @@ -278,7 +300,7 @@ static int read_journal_block(const char *cmd, struct journal_source *source, if (retval) com_err(cmd, retval, "while while reading journal"); - else if (*got != size) { + else if (*got != (unsigned int) size) { com_err(cmd, 0, "short read (read %d, expected %d) while while reading journal", *got, size); retval = -1; } @@ -311,7 +333,7 @@ static void dump_journal(char *cmdname, FILE *out_file, char jsb_buffer[1024]; char buf[8192]; journal_superblock_t *jsb; - int blocksize = 1024; + unsigned int blocksize = 1024; unsigned int got; int retval; __u32 magic, sequence, blocktype; @@ -492,9 +514,10 @@ static void dump_descriptor_block(FILE *out_file, static void dump_revoke_block(FILE *out_file, char *buf, - journal_superblock_t *jsb, - unsigned int blocknr, int blocksize, - tid_t transaction) + journal_superblock_t *jsb EXT2FS_ATTR((unused)), + unsigned int blocknr, + int blocksize EXT2FS_ATTR((unused)), + tid_t transaction) { int offset, max; journal_revoke_header_t *header; @@ -540,7 +563,7 @@ static void show_indirect(FILE *out_file, const char *name, __u32 where) static void dump_metadata_block(FILE *out_file, struct journal_source *source, - journal_superblock_t *jsb, + journal_superblock_t *jsb EXT2FS_ATTR((unused)), unsigned int log_blocknr, unsigned int fs_blocknr, int blocksize,