diff mbox series

[v4,2/4] e2image: add -b option to use supperblock backup

Message ID 20180525124225.31089-3-artem.blagodarenko@gmail.com
State Superseded
Headers show
Series e2image -b option to pass superblock number | expand

Commit Message

Artem Blagodarenko May 25, 2018, 12:42 p.m. UTC
e2image has no ability to use superblock backup to copy metadata.
This feature can be useful if someone wants to make partition
image and fix it using e2fsck utility.

New -b option allows to pass superblock number, like e2fsck utility do.
e2image doesn't change primary superblock and store is as is, so
it can be fixed using e2fsck latter.

Signed-off-by: Artem Blagodarenko <artem.blagodarenko@gmail.com>
---
 misc/e2image.8.in | 33 +++++++++++++++++++++++++++++++++
 misc/e2image.c    | 44 ++++++++++++++++++++++++++++++++++++++------
 2 files changed, 71 insertions(+), 6 deletions(-)

Comments

Andreas Dilger May 26, 2018, 3:17 a.m. UTC | #1
On May 25, 2018, at 6:42 AM, Artem Blagodarenko <artem.blagodarenko@gmail.com> wrote:
> 
> e2image has no ability to use superblock backup to copy metadata.
> This feature can be useful if someone wants to make partition
> image and fix it using e2fsck utility.
> 
> New -b option allows to pass superblock number, like e2fsck utility do.

The patch also adds the "-B" option.

> e2image doesn't change primary superblock and store is as is, so
> it can be fixed using e2fsck latter.
> 
> Signed-off-by: Artem Blagodarenko <artem.blagodarenko@gmail.com>

Aside from minor whitespace and comment cleanup, you can add:

Reviewed-by: Andreas Dilger <adilger@dilger.ca>

> ---
> misc/e2image.8.in | 33 +++++++++++++++++++++++++++++++++
> misc/e2image.c    | 44 ++++++++++++++++++++++++++++++++++++++------
> 2 files changed, 71 insertions(+), 6 deletions(-)
> 
> diff --git a/misc/e2image.8.in b/misc/e2image.8.in
> index a7bfdf24..c8dadc9d 100644
> --- a/misc/e2image.8.in
> +++ b/misc/e2image.8.in
> @@ -12,6 +12,15 @@ e2image \- Save critical ext2/ext3/ext4 filesystem metadata to a file
> ]
> [
> .B \-f
> +.B \-b
> +.I superblock
> +]
> +[
> +.B \-B
> +.I blocksize
> +]
> +[
> +.B \-fr
> ]
> .I device
> .I image-file
> @@ -167,6 +176,22 @@ the
> option will prevent analysis of problems related to hash-tree indexed
> directories.
> .PP
> +Option
> +.B \-b
> +.I superblock
> +can be used to get image from partition with broken primary superblock.
> +The partition is copied as is including broken primary superblock.

"as-is"

> +.PP
> +Option
> +.B \-B
> +.I blocksize
> +can be used to set superblock block size. Normally,  e2fsck  will  search
> +for  the superblock at various different block sizes in an attempt to find

Replace double spaces with single spaces.  It doesn't really matter, since
nroff will re-wrap the text to fit the terminal, just cosmetic.

> +the appropriate blocksize. This search can be fooled in some cases.  This
> +option forces e2fsck to only try locating the superblock at a particular
> +blocksize. If the superblock is not found, e2fsck will terminate with a
> +fatal error.
> +.PP
> Note that this will work even if you substitute "/dev/hda1" for another raw
> disk image, or QCOW2 image previously created by
> .BR e2image .
> @@ -217,6 +242,14 @@ This can be useful to write a qcow2 image containing all data to a
> sparse image file where it can be loop mounted, or to a disk partition.
> Note that this may not work with qcow2 images not generated by e2image.
> .PP
> +Options
> +.B \-b
> +.I superblock
> +and
> +.B \-B
> +.I blocksize
> +can be used same way as for raw images.
> +.PP
> .SH INCLUDING DATA
> Normally
> .B e2image
> diff --git a/misc/e2image.c b/misc/e2image.c
> index 83ae6335..fa5f3b7a 100644
> --- a/misc/e2image.c
> +++ b/misc/e2image.c
> @@ -104,7 +104,8 @@ static int get_bits_from_size(size_t size)
> 
> static void usage(void)
> {
> -	fprintf(stderr, _("Usage: %s [ -r|Q ] [ -f ] device image-file\n"),
> +	fprintf(stderr, _("Usage: %s [ -r|Q ] [ -f ] [ -b superblock ] [ -B blocksize]"
> +			  "[ -fr ] device image-file\n"),
> 		program_name);
> 	fprintf(stderr, _("       %s -I device image-file\n"), program_name);
> 	fprintf(stderr, _("       %s -ra  [  -cfnp  ] [ -o src_offset ] "
> @@ -1256,7 +1257,8 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
> 	free_qcow2_image(img);
> }
> 
> -static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
> +static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags,
> +				 blk64_t superblock)
> {
> 	struct process_block_struct	pb;
> 	struct ext2_inode		inode;
> @@ -1284,6 +1286,22 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
> 		}
> 	}
> 
> +	if (superblock) {
> +		int j;
> +
> +		ext2fs_mark_block_bitmap2(meta_block_map, superblock);
> +		meta_blocks_count++;
> +
> +		/*
> +		 * Mark the backup superblock descriptors
> +		 */
> +		for (j = 0; j < fs->desc_blocks; j++) {
> +			ext2fs_mark_block_bitmap2(meta_block_map,
> +			ext2fs_descriptor_block_loc2(fs, superblock, j));
> +		}
> +		meta_blocks_count += fs->desc_blocks;
> +	}
> +
> 	mark_table_blocks(fs);
> 	if (show_progress)
> 		fprintf(stderr, "%s", _("Scanning inodes...\n"));
> @@ -1463,6 +1481,8 @@ int main (int argc, char ** argv)
> 	int ignore_rw_mount = 0;
> 	int check = 0;
> 	struct stat st;
> +	blk64_t superblock = 0;
> +	int blocksize = 0;
> 
> #ifdef ENABLE_NLS
> 	setlocale(LC_MESSAGES, "");
> @@ -1476,8 +1496,14 @@ int main (int argc, char ** argv)
> 	if (argc && *argv)
> 		program_name = *argv;
> 	add_error_table(&et_ext2_error_table);
> -	while ((c = getopt(argc, argv, "nrsIQafo:O:pc")) != EOF)
> +	while ((c = getopt(argc, argv, "b:B:nrsIQafo:O:pc")) != EOF)
> 		switch (c) {
> +		case 'b':
> +			superblock = strtoull(optarg, NULL, 0);
> +			break;
> +		case 'B':
> +			blocksize = strtoul(optarg, NULL, 0);
> +			break;
> 		case 'I':
> 			flags |= E2IMAGE_INSTALL_FLAG;
> 			break;
> @@ -1529,6 +1555,11 @@ int main (int argc, char ** argv)
> 						 "with raw or QCOW2 images."));
> 		exit(1);
> 	}
> +	if (superblock && !img_type) {
> +		com_err(program_name, 0, "%s", _("-b option can only be used "
> +						 "with raw or QCOW2 images."));
> +		exit(1);
> +	}
> 	if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
> 		com_err(program_name, 0, "%s",
> 			_("Offsets are only allowed with raw images."));
> @@ -1579,8 +1610,9 @@ int main (int argc, char ** argv)
> 		}
> 	}
> 	sprintf(offset_opt, "offset=%llu", source_offset);
> -	retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0,
> -			      unix_io_manager, &fs);
> +	retval = ext2fs_open2(device_name, offset_opt, open_flag,
> +				    superblock, blocksize, unix_io_manager,
> +				    &fs);

(style) align after '(' on previous line, then "&fs);" can fit on that line.

>         if (retval) {
> 		com_err (program_name, retval, _("while trying to open %s"),
> 			 device_name);
> @@ -1665,7 +1697,7 @@ skip_device:
> 		exit(1);
> 	}
> 	if (img_type)
> -		write_raw_image_file(fs, fd, img_type, flags);
> +		write_raw_image_file(fs, fd, img_type, flags, superblock);
> 	else
> 		write_image_file(fs, fd);
> 
> --
> 2.14.3
> 


Cheers, Andreas
diff mbox series

Patch

diff --git a/misc/e2image.8.in b/misc/e2image.8.in
index a7bfdf24..c8dadc9d 100644
--- a/misc/e2image.8.in
+++ b/misc/e2image.8.in
@@ -12,6 +12,15 @@  e2image \- Save critical ext2/ext3/ext4 filesystem metadata to a file
 ]
 [
 .B \-f
+.B \-b
+.I superblock
+]
+[
+.B \-B
+.I blocksize
+]
+[
+.B \-fr
 ]
 .I device
 .I image-file
@@ -167,6 +176,22 @@  the
 option will prevent analysis of problems related to hash-tree indexed
 directories.
 .PP
+Option
+.B \-b
+.I superblock
+can be used to get image from partition with broken primary superblock.
+The partition is copied as is including broken primary superblock.
+.PP
+Option
+.B \-B
+.I blocksize
+can be used to set superblock block size. Normally,  e2fsck  will  search
+for  the superblock at various different block sizes in an attempt to find
+the appropriate blocksize. This search can be fooled in some cases.  This
+option forces e2fsck to only try locating the superblock at a particular
+blocksize. If the superblock is not found, e2fsck will terminate with a
+fatal error.
+.PP
 Note that this will work even if you substitute "/dev/hda1" for another raw
 disk image, or QCOW2 image previously created by
 .BR e2image .
@@ -217,6 +242,14 @@  This can be useful to write a qcow2 image containing all data to a
 sparse image file where it can be loop mounted, or to a disk partition.
 Note that this may not work with qcow2 images not generated by e2image.
 .PP
+Options
+.B \-b
+.I superblock
+and
+.B \-B
+.I blocksize
+can be used same way as for raw images.
+.PP
 .SH INCLUDING DATA
 Normally
 .B e2image
diff --git a/misc/e2image.c b/misc/e2image.c
index 83ae6335..fa5f3b7a 100644
--- a/misc/e2image.c
+++ b/misc/e2image.c
@@ -104,7 +104,8 @@  static int get_bits_from_size(size_t size)
 
 static void usage(void)
 {
-	fprintf(stderr, _("Usage: %s [ -r|Q ] [ -f ] device image-file\n"),
+	fprintf(stderr, _("Usage: %s [ -r|Q ] [ -f ] [ -b superblock ] [ -B blocksize]"
+			  "[ -fr ] device image-file\n"),
 		program_name);
 	fprintf(stderr, _("       %s -I device image-file\n"), program_name);
 	fprintf(stderr, _("       %s -ra  [  -cfnp  ] [ -o src_offset ] "
@@ -1256,7 +1257,8 @@  static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd)
 	free_qcow2_image(img);
 }
 
-static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
+static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags,
+				 blk64_t superblock)
 {
 	struct process_block_struct	pb;
 	struct ext2_inode		inode;
@@ -1284,6 +1286,22 @@  static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags)
 		}
 	}
 
+	if (superblock) {
+		int j;
+
+		ext2fs_mark_block_bitmap2(meta_block_map, superblock);
+		meta_blocks_count++;
+
+		/*
+		 * Mark the backup superblock descriptors
+		 */
+		for (j = 0; j < fs->desc_blocks; j++) {
+			ext2fs_mark_block_bitmap2(meta_block_map,
+			ext2fs_descriptor_block_loc2(fs, superblock, j));
+		}
+		meta_blocks_count += fs->desc_blocks;
+	}
+
 	mark_table_blocks(fs);
 	if (show_progress)
 		fprintf(stderr, "%s", _("Scanning inodes...\n"));
@@ -1463,6 +1481,8 @@  int main (int argc, char ** argv)
 	int ignore_rw_mount = 0;
 	int check = 0;
 	struct stat st;
+	blk64_t superblock = 0;
+	int blocksize = 0;
 
 #ifdef ENABLE_NLS
 	setlocale(LC_MESSAGES, "");
@@ -1476,8 +1496,14 @@  int main (int argc, char ** argv)
 	if (argc && *argv)
 		program_name = *argv;
 	add_error_table(&et_ext2_error_table);
-	while ((c = getopt(argc, argv, "nrsIQafo:O:pc")) != EOF)
+	while ((c = getopt(argc, argv, "b:B:nrsIQafo:O:pc")) != EOF)
 		switch (c) {
+		case 'b':
+			superblock = strtoull(optarg, NULL, 0);
+			break;
+		case 'B':
+			blocksize = strtoul(optarg, NULL, 0);
+			break;
 		case 'I':
 			flags |= E2IMAGE_INSTALL_FLAG;
 			break;
@@ -1529,6 +1555,11 @@  int main (int argc, char ** argv)
 						 "with raw or QCOW2 images."));
 		exit(1);
 	}
+	if (superblock && !img_type) {
+		com_err(program_name, 0, "%s", _("-b option can only be used "
+						 "with raw or QCOW2 images."));
+		exit(1);
+	}
 	if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) {
 		com_err(program_name, 0, "%s",
 			_("Offsets are only allowed with raw images."));
@@ -1579,8 +1610,9 @@  int main (int argc, char ** argv)
 		}
 	}
 	sprintf(offset_opt, "offset=%llu", source_offset);
-	retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0,
-			      unix_io_manager, &fs);
+	retval = ext2fs_open2(device_name, offset_opt, open_flag,
+				    superblock, blocksize, unix_io_manager,
+				    &fs);
         if (retval) {
 		com_err (program_name, retval, _("while trying to open %s"),
 			 device_name);
@@ -1665,7 +1697,7 @@  skip_device:
 		exit(1);
 	}
 	if (img_type)
-		write_raw_image_file(fs, fd, img_type, flags);
+		write_raw_image_file(fs, fd, img_type, flags, superblock);
 	else
 		write_image_file(fs, fd);