X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=misc%2Fe2image.c;h=3c881feec01a7aa77ac84ae698ece3689518f253;hb=b5ea01604850e4de8b407a55405f969908a9686b;hp=e9b4ae26a8bb88dd4f826573d643cf97d5cd415d;hpb=f1644c324bd6bc0ed8f48275d64ccde4ce13a044;p=tools%2Fe2fsprogs.git diff --git a/misc/e2image.c b/misc/e2image.c index e9b4ae2..3c881fe 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -43,6 +43,7 @@ extern int optind; #include "ext2fs/ext2_fs.h" #include "ext2fs/ext2fs.h" +#include "ext2fs/ext2fsP.h" #include "et/com_err.h" #include "uuid/uuid.h" #include "e2p/e2p.h" @@ -103,7 +104,8 @@ static int get_bits_from_size(size_t size) static void usage(void) { - fprintf(stderr, _("Usage: %s [ -r|Q ] [ -fr ] 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 ] " @@ -239,7 +241,7 @@ static void write_image_file(ext2_filsys fs, int fd) write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize); memset(&hdr, 0, sizeof(struct ext2_image_hdr)); - hdr.offset_super = seek_relative(fd, 0); + hdr.offset_super = ext2fs_cpu_to_le32(seek_relative(fd, 0)); retval = ext2fs_image_super_write(fs, fd, 0); if (retval) { com_err(program_name, retval, "%s", @@ -247,7 +249,7 @@ static void write_image_file(ext2_filsys fs, int fd) exit(1); } - hdr.offset_inode = seek_relative(fd, 0); + hdr.offset_inode = ext2fs_cpu_to_le32(seek_relative(fd, 0)); retval = ext2fs_image_inode_write(fs, fd, (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0); if (retval) { @@ -256,7 +258,7 @@ static void write_image_file(ext2_filsys fs, int fd) exit(1); } - hdr.offset_blockmap = seek_relative(fd, 0); + hdr.offset_blockmap = ext2fs_cpu_to_le32(seek_relative(fd, 0)); retval = ext2fs_image_bitmap_write(fs, fd, 0); if (retval) { com_err(program_name, retval, "%s", @@ -264,7 +266,7 @@ static void write_image_file(ext2_filsys fs, int fd) exit(1); } - hdr.offset_inodemap = seek_relative(fd, 0); + hdr.offset_inodemap = ext2fs_cpu_to_le32(seek_relative(fd, 0)); retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP); if (retval) { com_err(program_name, retval, "%s", @@ -272,23 +274,23 @@ static void write_image_file(ext2_filsys fs, int fd) exit(1); } - hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE; + hdr.magic_number = ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE); strcpy(hdr.magic_descriptor, "Ext2 Image 1.0"); gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname)); strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1); hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0; - hdr.fs_blocksize = fs->blocksize; + hdr.fs_blocksize = ext2fs_cpu_to_le32(fs->blocksize); if (stat(device_name, &st) == 0) - hdr.fs_device = st.st_rdev; + hdr.fs_device = ext2fs_cpu_to_le32(st.st_rdev); if (fstat(fd, &st) == 0) { - hdr.image_device = st.st_dev; - hdr.image_inode = st.st_ino; + hdr.image_device = ext2fs_cpu_to_le32(st.st_dev); + hdr.image_inode = ext2fs_cpu_to_le32(st.st_ino); } memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid)); - hdr.image_time = time(0); + hdr.image_time = ext2fs_cpu_to_le32(time(0)); write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize); } @@ -415,6 +417,14 @@ static void mark_table_blocks(ext2_filsys fs) } meta_blocks_count += fs->desc_blocks; + /* + * Mark MMP block + */ + if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) { + ext2fs_mark_block_bitmap2(meta_block_map, fs->super->s_mmp_block); + meta_blocks_count++; + } + for (i = 0; i < fs->group_desc_count; i++) { /* * Mark the blocks used for the inode table @@ -551,7 +561,7 @@ static void sigint_handler(int unused EXT2FS_ATTR((unused))) #define calc_percent(a, b) ((int) ((100.0 * (((float) (a)) / \ ((float) (b)))) + 0.5)) -#define calc_rate(t, b, d) (((float)(t) / ((1024 * 1024) / (b))) / (d)) +#define calc_rate(t, b, d) (((float)(t) / ((float)(1024 * 1024) / (b))) / (d)) static int print_progress(blk64_t num, blk64_t total) { @@ -873,8 +883,8 @@ static int init_refcount(struct ext2_qcow2_image *img, blk64_t table_offset) return ret; } -static int initialize_qcow2_image(int fd, ext2_filsys fs, - struct ext2_qcow2_image *image) +static errcode_t initialize_qcow2_image(int fd, ext2_filsys fs, + struct ext2_qcow2_image *image) { struct ext2_qcow2_hdr *header; blk64_t total_size, offset; @@ -882,6 +892,9 @@ static int initialize_qcow2_image(int fd, ext2_filsys fs, int cluster_bits = get_bits_from_size(fs->blocksize); struct ext2_super_block *sb = fs->super; + if (fs->blocksize < 1024) + return EINVAL; /* Can never happen, but just in case... */ + /* Allocate header */ ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header); if (ret) @@ -1108,7 +1121,7 @@ static int update_refcount(int fd, struct ext2_qcow2_image *img, /* * We are relying on the fact that we are creating the qcow2 * image sequentially, hence we will always allocate refcount - * block items sequentialy. + * block items sequentially. */ ref->refcount_block[ref->refcount_block_index] = ext2fs_cpu_to_be16(1); ref->refcount_block_index++; @@ -1255,7 +1268,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; @@ -1283,9 +1297,25 @@ 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) - printf("%s", _("Scanning inodes...\n")); + fprintf(stderr, "%s", _("Scanning inodes...\n")); retval = ext2fs_open_inode_scan(fs, 0, &scan); if (retval) { @@ -1374,7 +1404,8 @@ static void install_image(char *device, char *image_fn, int type) { errcode_t retval; ext2_filsys fs; - int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS; + int open_flag = EXT2_FLAG_IMAGE_FILE | EXT2_FLAG_64BITS | + EXT2_FLAG_IGNORE_CSUM_ERRORS; int fd = 0; io_manager io_ptr; io_channel io; @@ -1421,7 +1452,7 @@ static void install_image(char *device, char *image_fn, int type) ext2fs_rewrite_to_io(fs, io); - seek_set(fd, fs->image_header->offset_inode); + seek_set(fd, ext2fs_le32_to_cpu(fs->image_header->offset_inode)); retval = ext2fs_image_inode_read(fs, fd, 0); if (retval) { @@ -1451,7 +1482,7 @@ int main (int argc, char ** argv) ext2_filsys fs; char *image_fn, offset_opt[64]; struct ext2_qcow2_hdr *header = NULL; - int open_flag = EXT2_FLAG_64BITS; + int open_flag = EXT2_FLAG_64BITS | EXT2_FLAG_IGNORE_CSUM_ERRORS; int img_type = 0; int flags = 0; int mount_flags = 0; @@ -1461,6 +1492,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, ""); @@ -1474,8 +1507,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; @@ -1527,6 +1566,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.")); @@ -1577,8 +1621,8 @@ 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); @@ -1619,7 +1663,7 @@ skip_device: _("Can not stat output\n")); exit(1); } - if (S_ISBLK(st.st_mode)) + if (ext2fsP_is_disk_device(st.st_mode)) output_is_blk = 1; } if (flags & E2IMAGE_IS_QCOW2_FLAG) { @@ -1628,13 +1672,18 @@ skip_device: if (ret == -QCOW_COMPRESSED) fprintf(stderr, _("Image (%s) is compressed\n"), image_fn); - if (ret == -QCOW_ENCRYPTED) + else if (ret == -QCOW_ENCRYPTED) fprintf(stderr, _("Image (%s) is encrypted\n"), image_fn); - com_err(program_name, ret, - _("while trying to convert qcow2 image" - " (%s) into raw image (%s)"), - device_name, image_fn); + else if (ret == -QCOW_CORRUPTED) + fprintf(stderr, _("Image (%s) is corrupted\n"), + image_fn); + else + com_err(program_name, ret, + _("while trying to convert qcow2 image" + " (%s) into raw image (%s)"), + image_fn, device_name); + ret = 1; } goto out; } @@ -1663,7 +1712,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);