Re: [PATCH] 12/13 e2fsprogs-findsuper - print per-sb info in findsuper

Theodore Tso <[email protected]> Sun, 6 Aug 2006 01:08:17 -0400
Newsgroups gmane.comp.file-systems.ext2.devel
Message-ID <[email protected]>
On Wed, Aug 02, 2006 at 11:01:53AM -0600, Andreas Dilger wrote:
> Make it clearer which superblocks belong to the same filesystem by showing
> part of the UUID and LABEL fields.
> 
> Show the byte offset of the start and end of the filesystem instead of the
> block offset which was ambiguous and depended on the blocksize.

There were a few bugs in the patch; notably the logic for when to
print the '*' was backwards for the group number.  Also, I enhanced
the patch by default omitting superblocks that appear to be were
written into the ext3 journal unless the -j option is specified to the
findsuper program.

						- Ted


# HG changeset patch
# User [email protected]
# Date 1154840197 14400
# Node ID 933b06f21563c30d477fc2a241a88843f16a4939
# Parent  6f76ca8e929f5698d94b7b7bfd4768442b29433c
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 <[email protected]>
Signed-off-by: "Theodore Ts'o" <[email protected]>

diff -r 6f76ca8e929f -r 933b06f21563 misc/ChangeLog
--- a/misc/ChangeLog	Sat Aug 05 19:05:53 2006 -0400
+++ b/misc/ChangeLog	Sun Aug 06 00:56:37 2006 -0400
@@ -1,3 +1,12 @@ 2006-08-05  Theodore Tso  <[email protected]
+2006-08-06  Theodore Tso  <[email protected]>
+
+	* 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  <[email protected]>
 
 	* mke2fs.c (PRS), util.c (check_mount): In order to force mke2fs
diff -r 6f76ca8e929f -r 933b06f21563 misc/findsuper.c
--- a/misc/findsuper.c	Sat Aug 05 19:05:53 2006 -0400
+++ b/misc/findsuper.c	Sun Aug 06 00:56:37 2006 -0400
@@ -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);
-	}
-	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);
+
+	while ((c = getopt (argc, argv, "j")) != EOF) {
+		switch (c) {
+		case 'j':
+			print_jnl_copies++;
+			break;
+		default:
+			usage();
+		}
+	}
+
+	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);
+	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 %Lu\n"), sk);
 		exit(1);
 	}
-	if (sk < 0) {
-		fprintf(stderr,_("startkb should be positive, not %Ld\n"), sk);
+	
+	fd = open(device_name, O_RDONLY);
+	if (fd < 0) {
+		perror(device_name);
 		exit(1);
 	}
-	fd = open(argv[1], O_RDONLY);
-	if (fd < 0) {
-		perror(argv[1]);
-		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);
-	}
-	printf(_("\n%14Ld: finished with errno %d\n"), sk, errno);
+		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%11Lu: finished with errno %d\n"), sk, errno);
 	close(fd);
 
 	return errno;

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV