summaryrefslogtreecommitdiff
path: root/misc/findsuper.c
diff options
context:
space:
mode:
authorAndreas Dilger <adilger@clusterfs.com>2006-08-06 00:56:37 -0400
committerTheodore Ts'o <tytso@mit.edu>2006-08-06 00:56:37 -0400
commit42fef8df5c5aeadaf1b8020739cdaf190753efa1 (patch)
tree539d94442c02c3c5686cf7a2c27b53dbbc150a7e /misc/findsuper.c
parentc16e610c5100cd5829d969272af3035fac8e1a31 (diff)
downloade2fsprogs-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.c114
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;