summaryrefslogtreecommitdiff
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
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>
-rw-r--r--misc/ChangeLog9
-rw-r--r--misc/findsuper.c114
2 files changed, 92 insertions, 31 deletions
diff --git a/misc/ChangeLog b/misc/ChangeLog
index 9b3ccd1a..86254330 100644
--- a/misc/ChangeLog
+++ b/misc/ChangeLog
@@ -1,3 +1,12 @@
+2006-08-06 Theodore Tso <tytso@mit.edu>
+
+ * findsuper.c (main): Improve 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.
+
2006-08-05 Theodore Tso <tytso@mit.edu>
* mke2fs.c (PRS), util.c (check_mount): In order to force mke2fs
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;