]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Make the findsuper program more powerful
authorAndreas Dilger <adilger@clusterfs.com>
Sun, 6 Aug 2006 04:56:37 +0000 (00:56 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 6 Aug 2006 04:56:37 +0000 (00:56 -0400)
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>
misc/ChangeLog
misc/findsuper.c

index 9b3ccd1a10f023e11f3dfedf003f47f5774ce7ea..86254330188e736429a604b94965097ead3085e5 100644 (file)
@@ -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
index d82805b7c07af49122ccb0e4d934509b24465ece..5eade88976a9aa5dc12073c585f9219b366eee54 100644 (file)
 #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;