From patchwork Fri Jul 6 20:08:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phillip Susi X-Patchwork-Id: 169538 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 603C62C01D3 for ; Sat, 7 Jul 2012 06:19:41 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756114Ab2GFUT1 (ORCPT ); Fri, 6 Jul 2012 16:19:27 -0400 Received: from rrcs-67-78-168-186.se.biz.rr.com ([67.78.168.186]:39419 "EHLO iriserv.iradimed.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755814Ab2GFUTY (ORCPT ); Fri, 6 Jul 2012 16:19:24 -0400 X-Greylist: delayed 525 seconds by postgrey-1.27 at vger.kernel.org; Fri, 06 Jul 2012 16:19:24 EDT Received: by iriserv.iradimed.com (Postfix, from userid 1000) id 9AB8D40B28; Fri, 6 Jul 2012 16:10:38 -0400 (EDT) From: Phillip Susi To: linux-ext4@vger.kernel.org Cc: Phillip Susi Subject: [PATCH v2] e2image: add -a switch to include all data Date: Fri, 6 Jul 2012 16:08:52 -0400 Message-Id: <1341605332-26568-1-git-send-email-psusi@ubuntu.com> X-Mailer: git-send-email 1.7.5.4 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Normally the raw and QCOW2 images only contain fs metadata. Add a new switch ( -a ) to include all data. This makes it possible to use e2image to clone a whole filesystem. Signed-off-by: Phillip Susi --- misc/e2image.8.in | 22 +++++++++++++++++++++- misc/e2image.c | 31 ++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/misc/e2image.8.in b/misc/e2image.8.in index 8876e77..f8205a6 100644 --- a/misc/e2image.8.in +++ b/misc/e2image.8.in @@ -8,7 +8,7 @@ e2image \- Save critical ext2/ext3/ext4 filesystem metadata to a file .SH SYNOPSIS .B e2image [ -.B \-rsI +.B \-rsIQa ] .I device .I image-file @@ -171,6 +171,26 @@ is regular QCOW2 image and can be processed by tools aware of QCOW2 format such as for example .BR qemu-img . .PP +You can convert a qcow2 image into a raw image with: +.PP +.br +\ \fBe2image \-r hda1.qcow2 hda1.raw\fR +.br +.PP +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 +.SH INCLUDING DATA +Normally +.B e2image +only includes fs metadata, not regular file data. The +.B \-a +option can be specified to include all data. This will +give an image that is suitible 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 AUTHOR .B e2image was written by Theodore Ts'o (tytso@mit.edu). diff --git a/misc/e2image.c b/misc/e2image.c index 3a956ef..3e4b717 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -52,6 +52,9 @@ extern int optind; const char * program_name = "e2image"; char * device_name = NULL; +char all_data; +char output_is_blk; +/* writing to blk device: don't skip zeroed blocks */ static void lseek_error_and_exit(int errnum) { @@ -84,7 +87,7 @@ static int get_bits_from_size(size_t size) static void usage(void) { - fprintf(stderr, _("Usage: %s [-rsIQ] device image_file\n"), + fprintf(stderr, _("Usage: %s [-rsIQa] device image_file\n"), program_name); exit (1); } @@ -309,7 +312,7 @@ static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)), int ref_offset EXT2FS_ATTR((unused)), void *priv_data EXT2FS_ATTR((unused))) { - if (blockcnt < 0) { + if (blockcnt < 0 || all_data) { ext2fs_mark_block_bitmap2(meta_block_map, *block_nr); meta_blocks_count++; } @@ -341,11 +344,12 @@ static void mark_table_blocks(ext2_filsys fs) /* * Mark the blocks used for the inode table */ - if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) && + if ((output_is_blk || !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) && ext2fs_inode_table_loc(fs, i)) { unsigned int end = (unsigned) fs->inode_blocks_per_group; /* skip unused blocks */ - if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super, + if (!output_is_blk && + EXT2_HAS_RO_COMPAT_FEATURE(fs->super, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) end -= (ext2fs_bg_itable_unused(fs, i) / EXT2_INODES_PER_BLOCK(fs->super)); @@ -387,6 +391,8 @@ static int check_zero_block(char *buf, int blocksize) char *cp = buf; int left = blocksize; + if (output_is_blk) + return 0; while (left > 0) { if (*cp++) return 0; @@ -1134,7 +1140,7 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) if ((inode.i_flags & EXT4_EXTENTS_FL) || inode.i_block[EXT2_IND_BLOCK] || inode.i_block[EXT2_DIND_BLOCK] || - inode.i_block[EXT2_TIND_BLOCK]) { + inode.i_block[EXT2_TIND_BLOCK] || all_data) { retval = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY, block_buf, process_file_block, &pb); @@ -1249,6 +1255,7 @@ int main (int argc, char ** argv) int qcow2_fd = 0; int fd = 0; int ret = 0; + struct stat st; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); @@ -1262,7 +1269,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, "rsIQ")) != EOF) + while ((c = getopt(argc, argv, "rsIQa")) != EOF) switch (c) { case 'I': flags |= E2IMAGE_INSTALL_FLAG; @@ -1280,6 +1287,9 @@ int main (int argc, char ** argv) case 's': flags |= E2IMAGE_SCRAMBLE_FLAG; break; + case 'a': + all_data = 1; + break; default: usage(); } @@ -1327,7 +1337,14 @@ skip_device: "the stdout!\n"); exit(1); } - + if (fd != 1) { + if (fstat(fd, &st)) { + com_err(program_name, 0, "Can not stat output\n"); + exit(1); + } + if (S_ISBLK(st.st_mode)) + output_is_blk = 1; + } if (flags & E2IMAGE_IS_QCOW2_FLAG) { ret = qcow2_write_raw_image(qcow2_fd, fd, header); if (ret) {