X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=misc%2Fe2image.c;h=1ae03001fe9f9a976c3ec5591dee0324ff733c28;hb=260dfea450e387cbd2c8de79a7c2eeacc26f74e9;hp=253fad1d011cb50b14fd399ae00b54ff81ec6f90;hpb=e9b5923544ea72b8287bf3d7226fc11068af945a;p=tools%2Fe2fsprogs.git diff --git a/misc/e2image.c b/misc/e2image.c index 253fad1..1ae0300 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -10,8 +10,12 @@ * %End-Header% */ +#ifndef _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE +#endif +#ifndef _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE +#endif #include "config.h" #include @@ -39,16 +43,19 @@ 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" #include "ext2fs/e2image.h" #include "ext2fs/qcow2.h" +#include "support/nls-enable.h" +#include "support/plausible.h" +#include "support/quotaio.h" #include "../version.h" -#include "nls-enable.h" -#define QCOW_OFLAG_COPIED (1LL << 63) +#define QCOW_OFLAG_COPIED (1ULL << 63) #define NO_BLK ((blk64_t) -1) /* Image types */ @@ -98,10 +105,11 @@ 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 ] " + "device image-file\n"), program_name); fprintf(stderr, _(" %s -I device image-file\n"), program_name); - fprintf(stderr, _(" %s -ra [ -cfnp ] [ -o src_offset ] " + fprintf(stderr, _(" %s -ra [ -cfnp ] [ -o src_offset ] " "[ -O dest_offset ] src_fs [ dest_fs ]\n"), program_name); exit (1); @@ -165,7 +173,7 @@ static void generic_write(int fd, void *buf, int blocksize, blk64_t block) free_buf = 1; err = ext2fs_get_arrayzero(1, blocksize, &buf); if (err) { - com_err(program_name, err, + com_err(program_name, err, "%s", _("while allocating buffer")); exit(1); } @@ -185,9 +193,11 @@ static void generic_write(int fd, void *buf, int blocksize, blk64_t block) if (block) com_err(program_name, err, - _("error writing block %llu"), block); + _("error writing block %llu"), + (unsigned long long) block); else - com_err(program_name, err, _("error in write()")); + com_err(program_name, err, "%s", + _("error in generic_write()")); exit(1); } @@ -233,7 +243,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", @@ -241,7 +251,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) { @@ -250,7 +260,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", @@ -258,7 +268,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", @@ -266,23 +276,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); } @@ -304,7 +314,7 @@ struct process_block_struct { * structure, so there's no point in letting the ext2fs library read * the inode again. */ -static ino_t stashed_ino = 0; +static ext2_ino_t stashed_ino = 0; static struct ext2_inode *stashed_inode; static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)), @@ -409,6 +419,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 @@ -418,9 +436,7 @@ static void mark_table_blocks(ext2_filsys fs) ext2fs_inode_table_loc(fs, i)) { unsigned int end = (unsigned) fs->inode_blocks_per_group; /* skip unused blocks */ - if (!output_is_blk && - EXT2_HAS_RO_COMPAT_FEATURE(fs->super, - EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) + if (!output_is_blk && ext2fs_has_group_desc_csum(fs)) end -= (ext2fs_bg_itable_unused(fs, i) / EXT2_INODES_PER_BLOCK(fs->super)); for (j = 0, b = ext2fs_inode_table_loc(fs, i); @@ -547,12 +563,14 @@ 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) { - return fprintf(stderr, _("%llu / %llu blocks (%d%%)"), num, total, - calc_percent(num, total)); + return fprintf(stderr, _("%llu / %llu blocks (%d%%)"), + (unsigned long long) num, + (unsigned long long) total, + calc_percent(num, total)); } static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags) @@ -571,16 +589,18 @@ static void output_meta_data_blocks(ext2_filsys fs, int fd, int flags) retval = ext2fs_get_mem(fs->blocksize, &buf); if (retval) { - com_err(program_name, retval, _("while allocating buffer")); + com_err(program_name, retval, "%s", + _("while allocating buffer")); exit(1); } retval = ext2fs_get_memzero(fs->blocksize, &zero_buf); if (retval) { - com_err(program_name, retval, _("while allocating buffer")); + com_err(program_name, retval, "%s", + _("while allocating buffer")); exit(1); } if (show_progress) { - fprintf(stderr, _("Copying ")); + fprintf(stderr, "%s", _("Copying ")); bscount = print_progress(total_written, meta_blocks_count); fflush(stderr); last_update = time(NULL); @@ -604,21 +624,23 @@ more_blocks: if (got_sigint) { if (distance) { /* moving to the right */ - if (distance >= ext2fs_blocks_count(fs->super) || - start == ext2fs_blocks_count(fs->super) - distance) - kill (getpid(), SIGINT); + if (distance >= ext2fs_blocks_count(fs->super)|| + start == ext2fs_blocks_count(fs->super) - + distance) + kill(getpid(), SIGINT); } else { /* moving to the left */ - if (blk < (source_offset - dest_offset) / fs->blocksize) - kill (getpid(), SIGINT); + if (blk < (source_offset - dest_offset) / + fs->blocksize) + kill(getpid(), SIGINT); } if (show_progress) fputc('\r', stderr); - fprintf(stderr, + fprintf(stderr, "%s", _("Stopping now will destroy the filesystem, " "interrupt again if you are sure\n")); if (show_progress) { - fprintf(stderr, _("Copying ")); + fprintf(stderr, "%s", _("Copying ")); bscount = print_progress(total_written, meta_blocks_count); fflush(stderr); @@ -634,16 +656,17 @@ more_blocks: bscount = print_progress(total_written, meta_blocks_count); duration = time(NULL) - start_time; - if (duration > 5) { + if (duration > 5 && total_written) { time_t est = (duration * meta_blocks_count / total_written) - duration; char buff[30]; strftime(buff, 30, "%T", gmtime(&est)); - bscount += fprintf(stderr, - _(" %s remaining at %.2f MB/s"), - buff, calc_rate(total_written, - fs->blocksize, - duration)); + bscount += + fprintf(stderr, + _(" %s remaining at %.2f MB/s"), + buff, calc_rate(total_written, + fs->blocksize, + duration)); } fflush (stderr); } @@ -652,7 +675,8 @@ more_blocks: retval = io_channel_read_blk64(fs->io, blk, 1, buf); if (retval) { com_err(program_name, retval, - _("error reading block %llu"), blk); + _("error reading block %llu"), + (unsigned long long) blk); } total_written++; if (scramble_block_map && @@ -704,14 +728,16 @@ more_blocks: if (show_progress) { time_t duration = time(NULL) - start_time; char buff[30]; - while (bscount--) - fputc('\b', stderr); + fputc('\r', stderr); strftime(buff, 30, "%T", gmtime(&duration)); - fprintf(stderr, _("\b\b\b\b\b\b\b\bCopied %llu / %llu " - "blocks (%d%%) in %s at %.2f MB/s \n"), - total_written, meta_blocks_count, - calc_percent(total_written, meta_blocks_count), buff, - calc_rate(total_written, fs->blocksize, duration)); + fprintf(stderr, _("Copied %llu / %llu blocks (%d%%) in %s "), + (unsigned long long) total_written, + (unsigned long long) meta_blocks_count, + calc_percent(total_written, meta_blocks_count), buff); + if (duration) + fprintf(stderr, _("at %.2f MB/s"), + calc_rate(total_written, fs->blocksize, duration)); + fputs(" \n", stderr); } #ifdef HAVE_FTRUNCATE64 if (sparse) { @@ -744,7 +770,8 @@ static void init_l1_table(struct ext2_qcow2_image *image) ret = ext2fs_get_arrayzero(image->l1_size, sizeof(__u64), &l1_table); if (ret) { - com_err(program_name, ret, _("while allocating l1 table")); + com_err(program_name, ret, "%s", + _("while allocating l1 table")); exit(1); } @@ -789,7 +816,7 @@ static void init_l2_cache(struct ext2_qcow2_image *image) return; alloc_err: - com_err(program_name, ret, _("while allocating l2 cache")); + com_err(program_name, ret, "%s", _("while allocating l2 cache")); exit(1); } @@ -812,9 +839,10 @@ again: } if (cache->free != cache->count) { - fprintf(stderr, _("Warning: There are still tables in the " - "cache while putting the cache, data will " - "be lost so the image may not be valid.\n")); + fprintf(stderr, "%s", _("Warning: There are still tables in " + "the cache while putting the cache, " + "data will be lost so the image may " + "not be valid.\n")); table = cache->used_head; cache->used_head = NULL; goto again; @@ -861,8 +889,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; @@ -870,6 +898,10 @@ 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; + /* Sbould never happen, but just in case... */ + if (cluster_bits < 0) + return EXT2_FILSYS_CORRUPTED; + /* Allocate header */ ret = ext2fs_get_memzero(sizeof(struct ext2_qcow2_hdr), &header); if (ret) @@ -911,7 +943,7 @@ static int initialize_qcow2_image(int fd, ext2_filsys fs, header->refcount_table_clusters = ext2fs_cpu_to_be32(image->refcount.refcount_table_clusters); offset += image->cluster_size; - offset += image->refcount.refcount_table_clusters << + offset += (blk64_t) image->refcount.refcount_table_clusters << image->cluster_bits; /* Make space for L2 tables */ @@ -1096,7 +1128,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++; @@ -1132,14 +1164,14 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) /* allocate struct ext2_qcow2_image */ retval = ext2fs_get_mem(sizeof(struct ext2_qcow2_image), &img); if (retval) { - com_err(program_name, retval, + com_err(program_name, retval, "%s", _("while allocating ext2_qcow2_image")); exit(1); } retval = initialize_qcow2_image(fd, fs, img); if (retval) { - com_err(program_name, retval, + com_err(program_name, retval, "%s", _("while initializing ext2_qcow2_image")); exit(1); } @@ -1165,7 +1197,8 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) retval = ext2fs_get_mem(fs->blocksize, &buf); if (retval) { - com_err(program_name, retval, _("while allocating buffer")); + com_err(program_name, retval, "%s", + _("while allocating buffer")); exit(1); } /* Write qcow2 data blocks */ @@ -1175,7 +1208,8 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) retval = io_channel_read_blk64(fs->io, blk, 1, buf); if (retval) { com_err(program_name, retval, - _("error reading block %llu"), blk); + _("error reading block %llu"), + (unsigned long long) blk); continue; } if (scramble_block_map && @@ -1197,9 +1231,10 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) * block should not be created! */ if (update_refcount(fd, img, offset, offset)) { - fprintf(stderr, _("Programming error: " - "multiple sequential refcount " - "blocks created!\n")); + fprintf(stderr, "%s", + _("Programming error: multiple " + "sequential refcount blocks " + "created!\n")); exit(1); } } @@ -1214,7 +1249,7 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) offset += img->cluster_size; if (update_refcount(fd, img, offset, offset)) { - fprintf(stderr, + fprintf(stderr, "%s", _("Programming error: multiple sequential refcount " "blocks created!\n")); exit(1); @@ -1228,7 +1263,7 @@ static void output_qcow2_meta_data_blocks(ext2_filsys fs, int fd) offset += img->cluster_size; } } - update_refcount(fd, img, offset, offset); + (void) update_refcount(fd, img, offset, offset); flush_l2_cache(img); sync_refcount(fd, img); @@ -1241,7 +1276,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; @@ -1254,7 +1290,7 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) retval = ext2fs_allocate_block_bitmap(fs, _("in-use block map"), &meta_block_map); if (retval) { - com_err(program_name, retval, + com_err(program_name, retval, "%s", _("while allocating block bitmap")); exit(1); } @@ -1263,19 +1299,35 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) retval = ext2fs_allocate_block_bitmap(fs, "scramble block map", &scramble_block_map); if (retval) { - com_err(program_name, retval, + com_err(program_name, retval, "%s", _("while allocating scramble block bitmap")); exit(1); } } + if (superblock) { + unsigned 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(_("Scanning inodes...\n")); + fprintf(stderr, "%s", _("Scanning inodes...\n")); retval = ext2fs_open_inode_scan(fs, 0, &scan); if (retval) { - com_err(program_name, retval,"%s", + com_err(program_name, retval, "%s", _("while opening inode scan")); exit(1); } @@ -1314,9 +1366,12 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags) pb.ino = ino; pb.is_dir = LINUX_S_ISDIR(inode.i_mode); if (LINUX_S_ISDIR(inode.i_mode) || - (LINUX_S_ISLNK(inode.i_mode) && - ext2fs_inode_has_valid_blocks2(fs, &inode)) || - ino == fs->super->s_journal_inum) { + LINUX_S_ISLNK(inode.i_mode) || + ino == fs->super->s_journal_inum || + ino == quota_type2inum(USRQUOTA, fs->super) || + ino == quota_type2inum(GRPQUOTA, fs->super) || + ino == quota_type2inum(PRJQUOTA, fs->super) || + ino == fs->super->s_orphan_file_inum) { retval = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY, block_buf, process_dir_block, &pb); @@ -1360,14 +1415,15 @@ 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; if (type) { - com_err(program_name, 0, _("Raw and qcow2 images cannot" - "be installed")); + com_err(program_name, 0, "%s", + _("Raw and qcow2 images cannot be installed")); exit(1); } @@ -1382,14 +1438,14 @@ static void install_image(char *device, char *image_fn, int type) retval = ext2fs_open (image_fn, open_flag, 0, 0, io_ptr, &fs); if (retval) { - com_err (program_name, retval, _("while trying to open %s"), - image_fn); + com_err(program_name, retval, _("while trying to open %s"), + image_fn); exit(1); } retval = ext2fs_read_bitmaps (fs); if (retval) { - com_err(program_name, retval, _("error reading bitmaps")); + com_err(program_name, retval, "%s", _("error reading bitmaps")); exit(1); } @@ -1401,22 +1457,23 @@ static void install_image(char *device, char *image_fn, int type) retval = io_ptr->open(device, IO_FLAG_RW, &io); if (retval) { - com_err(device, 0, _("while opening device file")); + com_err(device, 0, "%s", _("while opening device file")); exit(1); } 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) { - com_err(image_fn, 0, _("while restoring the image table")); + com_err(image_fn, 0, "%s", + _("while restoring the image table")); exit(1); } close(fd); - ext2fs_close (fs); + ext2fs_close_free(&fs); } static struct ext2_qcow2_hdr *check_qcow2_image(int *fd, char *name) @@ -1436,7 +1493,8 @@ 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_THREADS | + EXT2_FLAG_IGNORE_CSUM_ERRORS; int img_type = 0; int flags = 0; int mount_flags = 0; @@ -1446,6 +1504,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, ""); @@ -1458,9 +1518,17 @@ int main (int argc, char ** argv) E2FSPROGS_DATE); if (argc && *argv) program_name = *argv; + else + usage(); 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; @@ -1508,22 +1576,27 @@ int main (int argc, char ** argv) usage(); if (all_data && !img_type) { - com_err(program_name, 0, _("-a option can only be used " - "with raw or QCOW2 images.")); + com_err(program_name, 0, "%s", _("-a option can only be used " + "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, + com_err(program_name, 0, "%s", _("Offsets are only allowed with raw images.")); exit(1); } if (move_mode && img_type != E2IMAGE_RAW) { - com_err(program_name, 0, + com_err(program_name, 0, "%s", _("Move mode is only allowed with raw images.")); exit(1); } if (move_mode && !all_data) { - com_err(program_name, 0, + com_err(program_name, 0, "%s", _("Move mode requires all data mode.")); exit(1); } @@ -1534,14 +1607,14 @@ int main (int argc, char ** argv) retval = ext2fs_check_if_mounted(device_name, &mount_flags); if (retval) { - com_err(program_name, retval, _("checking if mounted")); + com_err(program_name, retval, "%s", _("checking if mounted")); exit(1); } if (img_type && !ignore_rw_mount && (mount_flags & EXT2_MF_MOUNTED) && !(mount_flags & EXT2_MF_READONLY)) { - fprintf(stderr, _("\nRunning e2image on a R/W mounted " + fprintf(stderr, "%s", _("\nRunning e2image on a R/W mounted " "filesystem can result in an\n" "inconsistent image which will not be useful " "for debugging purposes.\n" @@ -1561,13 +1634,15 @@ int main (int argc, char ** argv) goto skip_device; } } - sprintf(offset_opt, "offset=%llu", source_offset); - retval = ext2fs_open2(device_name, offset_opt, open_flag, 0, 0, - unix_io_manager, &fs); + sprintf(offset_opt, "offset=%llu", (unsigned long long) source_offset); + 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); fputs(_("Couldn't find valid filesystem superblock.\n"), stdout); + if (retval == EXT2_ET_BAD_MAGIC) + check_plausibility(device_name, CHECK_FS_EXIST, NULL); exit(1); } @@ -1592,16 +1667,17 @@ skip_device: seek_set(fd, dest_offset); if ((img_type & E2IMAGE_QCOW2) && (fd == 1)) { - com_err(program_name, 0, _("QCOW2 image can not be written to " - "the stdout!\n")); + com_err(program_name, 0, "%s", + _("QCOW2 image can not be written to the stdout!\n")); exit(1); } if (fd != 1) { if (fstat(fd, &st)) { - com_err(program_name, 0, _("Can not stat output\n")); + com_err(program_name, 0, "%s", + _("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) { @@ -1610,48 +1686,53 @@ 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; } if (check) { if (img_type != E2IMAGE_RAW) { - fprintf(stderr, _("The -c option only supported " - "in raw mode\n")); + fprintf(stderr, "%s", _("The -c option only supported " + "in raw mode\n")); exit(1); } if (fd == 1) { - fprintf(stderr, _("The -c option is not supported " - "when writing to stdout\n")); + fprintf(stderr, "%s", _("The -c option not supported " + "when writing to stdout\n")); exit(1); } retval = ext2fs_get_mem(fs->blocksize, &check_buf); if (retval) { - com_err(program_name, retval, + com_err(program_name, retval, "%s", _("while allocating check_buf")); exit(1); } } if (show_progress && (img_type != E2IMAGE_RAW)) { - fprintf(stderr, _("The -p option only supported " - "in raw mode\n")); + fprintf(stderr, "%s", + _("The -p option only supported in raw mode\n")); 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); - ext2fs_close (fs); + ext2fs_close_free(&fs); if (check) - printf(_("%d blocks already contained the data to be copied.\n"), + printf(_("%d blocks already contained the data to be copied\n"), skipped_blocks); out: