diff options
author | Andreas Dilger <adilger@clusterfs.com> | 2006-08-06 00:56:37 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2006-08-06 00:56:37 -0400 |
commit | 42fef8df5c5aeadaf1b8020739cdaf190753efa1 (patch) | |
tree | 539d94442c02c3c5686cf7a2c27b53dbbc150a7e /misc/findsuper.c | |
parent | c16e610c5100cd5829d969272af3035fac8e1a31 (diff) | |
download | e2fsprogs-42fef8df5c5aeadaf1b8020739cdaf190753efa1.tar.gz |
Make the findsuper program more powerful
Improve the findsuper program by printing the uuid and label from the
superblocks, as well as the starting and ending offsets of the
filesystem given the information in the superblock. Omit by
default printing superblocks that are likely found in located in an ext3
journal unless an explicit -j option is given.
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'misc/findsuper.c')
-rw-r--r-- | misc/findsuper.c | 114 |
1 files changed, 83 insertions, 31 deletions
diff --git a/misc/findsuper.c b/misc/findsuper.c index d82805b7..5eade889 100644 --- a/misc/findsuper.c +++ b/misc/findsuper.c @@ -102,6 +102,14 @@ #define WHY(fmt, arg...) { continue; } #endif +static void usage(void) +{ + fprintf(stderr, + _("Usage: findsuper device [skipbytes [startkb]]\n")); + exit(1); +} + + int main(int argc, char *argv[]) { int skiprate=512; /* one sector */ @@ -110,7 +118,8 @@ int main(int argc, char *argv[]) char *s; time_t tm, last = time(0); loff_t interval = 1024 * 1024; - + int c, print_jnl_copies = 0; + const char * device_name; struct ext2_super_block ext2; /* interesting fields: EXT2_SUPER_MAGIC * s_blocks_count s_log_block_size s_mtime s_magic s_lastcheck */ @@ -121,43 +130,66 @@ int main(int argc, char *argv[]) bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif - if (argc<2) { - fprintf(stderr, - _("Usage: findsuper device [skipbytes [startkb]]\n")); - exit(1); + + while ((c = getopt (argc, argv, "j")) != EOF) { + switch (c) { + case 'j': + print_jnl_copies++; + break; + default: + usage(); + } } - if (argc>2) - skiprate = strtol(argv[2], &s, 0); - if (s == argv[2]) { - fprintf(stderr,_("skipbytes should be a number, not %s\n"), s); - exit(1); + + if (optind == argc) + usage(); + + device_name = argv[optind++]; + + if (optind < argc) { + skiprate = strtol(argv[optind], &s, 0); + if (s == argv[optind]) { + fprintf(stderr,_("skipbytes should be a number, not %s\n"), s); + exit(1); + } + optind++; } if (skiprate & 0x1ff) { fprintf(stderr, _("skipbytes must be a multiple of the sector size\n")); exit(2); } - if (argc>3) - sk = skl = strtoll(argv[3], &s, 0) << 10; - if (s == argv[3]) { - fprintf(stderr,_("startkb should be a number, not %s\n"), s); - exit(1); + if (optind < argc) { + sk = skl = strtoll(argv[optind], &s, 0) << 10; + if (s == argv[optind]) { + fprintf(stderr, + _("startkb should be a number, not %s\n"), s); + exit(1); + } + optind++; } if (sk < 0) { - fprintf(stderr,_("startkb should be positive, not %Ld\n"), sk); + fprintf(stderr, _("startkb should be positive, not %Lu\n"), sk); exit(1); } - fd = open(argv[1], O_RDONLY); + + fd = open(device_name, O_RDONLY); if (fd < 0) { - perror(argv[1]); + perror(device_name); exit(1); } - + /* Now, go looking for the superblock! */ - printf(_("starting at %Ld, with %d byte increments\n"), sk, skiprate); - printf(_(" thisoff block fs_blk_sz blksz grp last_mount\n")); + printf(_("starting at %Lu, with %u byte increments\n"), sk, skiprate); + if (print_jnl_copies) + printf(_("[*] probably superblock written in the ext3 " + "journal superblock,\n\tso start/end/grp wrong\n")); + printf(_("byte_offset byte_start byte_end fs_blocks blksz grp last_mount_time sb_uuid label\n")); for (; lseek64(fd, sk, SEEK_SET) != -1 && read(fd, &ext2, 512) == 512; sk += skiprate) { + static unsigned char last_uuid[16] = "blah"; + unsigned long long bsize, grpsize; + int jnl_copy, sb_offset; if (sk && !(sk & (interval - 1))) { time_t now, diff; @@ -168,7 +200,7 @@ int main(int argc, char *argv[]) if (diff > 0) { s = ctime(&now); s[24] = 0; - printf("\r%14Ld: %8LdkB/s @ %s", sk, + printf("\r%11Lu: %8LukB/s @ %s", sk, (((sk - skl)) / diff) >> 10, s); fflush(stdout); } @@ -181,8 +213,8 @@ int main(int argc, char *argv[]) } if (ext2.s_magic != EXT2_SUPER_MAGIC) continue; - if (ext2.s_log_block_size > 4) - WHY("log block size > 4 (%u)\n", ext2.s_log_block_size); + if (ext2.s_log_block_size > 6) + WHY("log block size > 6 (%u)\n", ext2.s_log_block_size); if (ext2.s_r_blocks_count > ext2.s_blocks_count) WHY("r_blocks_count > blocks_count (%u > %u)\n", ext2.s_r_blocks_count, ext2.s_blocks_count); @@ -194,14 +226,34 @@ int main(int argc, char *argv[]) ext2.s_free_inodes_count, ext2.s_inodes_count); tm = ext2.s_mtime; - s=ctime(&tm); - s[24]=0; - printf("\r%14Ld %9Ld %9d %5d %4d %s\n", - sk, sk >> 10, ext2.s_blocks_count, - 1 << (ext2.s_log_block_size + 10), - ext2.s_block_group_nr, s); + s = ctime(&tm); + s[24] = 0; + bsize = 1 << (ext2.s_log_block_size + 10); + grpsize = bsize * ext2.s_blocks_per_group; + if (memcmp(ext2.s_uuid, last_uuid, sizeof(last_uuid)) == 0 && + ext2.s_rev_level > 0 && ext2.s_block_group_nr == 0) { + jnl_copy = 1; + } else { + jnl_copy = 0; + memcpy(last_uuid, ext2.s_uuid, sizeof(last_uuid)); + } + if (ext2.s_block_group_nr == 0 || bsize == 1024) + sb_offset = 1024; + else + sb_offset = 0; + if (jnl_copy && !print_jnl_copies) + continue; + printf("\r%11Lu %11Lu%s %11Lu%s %9u %5Lu %4u%s %s %02x%02x%02x%02x %s\n", + sk, sk - ext2.s_block_group_nr * grpsize - sb_offset, + jnl_copy ? "*":" ", + sk + ext2.s_blocks_count * bsize - + ext2.s_block_group_nr * grpsize - sb_offset, + jnl_copy ? "*" : " ", ext2.s_blocks_count, bsize, + ext2.s_block_group_nr, jnl_copy ? "*" : " ", s, + ext2.s_uuid[0], ext2.s_uuid[1], + ext2.s_uuid[2], ext2.s_uuid[3], ext2.s_volume_name); } - printf(_("\n%14Ld: finished with errno %d\n"), sk, errno); + printf(_("\n%11Lu: finished with errno %d\n"), sk, errno); close(fd); return errno; |