From 6b5535f40974d522e827c83d02d005ac5c8b5056 Mon Sep 17 00:00:00 2001 From: Phillip Susi Date: Mon, 16 Dec 2013 11:32:39 -0500 Subject: [PATCH] e2image: add offset switches Add -o and -O switches to specify the offset where the source and destination filesystems start. This is useful if you have an image of a partitioned disk or wish to create one. Signed-off-by: Phillip Susi Signed-off-by: "Theodore Ts'o" --- misc/e2image.8.in | 36 ++++++++++++++++++++++++++++++++++++ misc/e2image.c | 30 ++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/misc/e2image.8.in b/misc/e2image.8.in index 78f06828..ba97ef80 100644 --- a/misc/e2image.8.in +++ b/misc/e2image.8.in @@ -10,6 +10,14 @@ e2image \- Save critical ext2/ext3/ext4 filesystem metadata to a file [ .B \-rsIQa ] +[ +.B \-o +.I source_offset +] +[ +.B \-O +.I dest_offset +] .I device .I image-file .SH DESCRIPTION @@ -201,6 +209,34 @@ give an image that is suitable to use to clone the entire FS or for backup purposes. Note that this option only works with the raw or QCOW2 formats. .PP +.SH OFFSETS +Normally a filesystem starts at the beginning of a partition, and +.B e2image +is run on the partition. When working with image files, you don't +have the option of using the partition device, so you can specify +the offset where the filesystem starts directly with the +.B \-o +option. Similarly the +.B \-O +option specifies the offset that should be seeked to in the destination +before writing the filesystem. +.PP +For example, if you have a +.B dd +image of a whole hard drive that contains an ext2 fs in a partition +starting at 1 MiB, you can clone that fs with: +.PP +.br +\ \fBe2image \-aro 1048576 img /dev/sda1\fR +.br +.PP +Or you can clone a fs into an image file, leaving room in the first +MiB for a partition table with: +.PP +.br +\ \fBe2image -arO 1048576 /dev/sda1 img\fR +.br +.PP .SH AUTHOR .B e2image was written by Theodore Ts'o (tytso@mit.edu). diff --git a/misc/e2image.c b/misc/e2image.c index 4fb9a969..2f80efff 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -55,6 +55,7 @@ static char * device_name = NULL; static char all_data; static char output_is_blk; /* writing to blk device: don't skip zeroed blocks */ +blk64_t source_offset, dest_offset; static void lseek_error_and_exit(int errnum) { @@ -87,7 +88,7 @@ static int get_bits_from_size(size_t size) static void usage(void) { - fprintf(stderr, _("Usage: %s [-rsIQaf] device image_file\n"), + fprintf(stderr, _("Usage: %s [-rsIQaf] [-o source_offset] [-O dest_offset] device image_file\n"), program_name); exit (1); } @@ -1278,7 +1279,7 @@ int main (int argc, char ** argv) if (argc && *argv) program_name = *argv; add_error_table(&et_ext2_error_table); - while ((c = getopt(argc, argv, "rsIQaf")) != EOF) + while ((c = getopt(argc, argv, "rsIQafo:O:")) != EOF) switch (c) { case 'I': flags |= E2IMAGE_INSTALL_FLAG; @@ -1302,6 +1303,12 @@ int main (int argc, char ** argv) case 'f': ignore_rw_mount = 1; break; + case 'o': + source_offset = strtoull(optarg, NULL, 0); + break; + case 'O': + dest_offset = strtoull(optarg, NULL, 0); + break; default: usage(); } @@ -1313,7 +1320,11 @@ int main (int argc, char ** argv) "with raw or QCOW2 images."); exit(1); } - + if ((source_offset || dest_offset) && img_type != E2IMAGE_RAW) { + com_err(program_name, 0, + "Offsets are only allowed with raw images."); + exit(1); + } device_name = argv[optind]; image_fn = argv[optind+1]; @@ -1346,9 +1357,11 @@ int main (int argc, char ** argv) goto skip_device; } } - - retval = ext2fs_open (device_name, open_flag, 0, 0, - unix_io_manager, &fs); + char *options; + asprintf (&options, "offset=%llu", source_offset); + retval = ext2fs_open2 (device_name, options, open_flag, 0, 0, + unix_io_manager, &fs); + free (options); if (retval) { com_err (program_name, retval, _("while trying to open %s"), device_name); @@ -1367,6 +1380,11 @@ skip_device: exit(1); } } + if (dest_offset) + if (ext2fs_llseek (fd, dest_offset, SEEK_SET) < 0) { + perror("ext2fs_llseek"); + exit(1); + } if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) { com_err(program_name, 0, "QCOW2 image can not be written to "