version 1.1.1.11, 2018/04/24 18:24:09
|
version 1.1.1.12, 2018/04/24 18:34:02
|
Line 23
|
Line 23
|
*/ |
*/ |
#include "qemu-common.h" |
#include "qemu-common.h" |
#include "qemu-option.h" |
#include "qemu-option.h" |
|
#include "qemu-error.h" |
#include "osdep.h" |
#include "osdep.h" |
|
#include "sysemu.h" |
#include "block_int.h" |
#include "block_int.h" |
#include <stdio.h> |
#include <stdio.h> |
|
|
Line 39 typedef struct img_cmd_t {
|
Line 41 typedef struct img_cmd_t {
|
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */ |
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */ |
#define BDRV_O_FLAGS BDRV_O_CACHE_WB |
#define BDRV_O_FLAGS BDRV_O_CACHE_WB |
|
|
static void error(const char *fmt, ...) |
|
{ |
|
va_list ap; |
|
va_start(ap, fmt); |
|
fprintf(stderr, "qemu-img: "); |
|
vfprintf(stderr, fmt, ap); |
|
fprintf(stderr, "\n"); |
|
va_end(ap); |
|
} |
|
|
|
static void format_print(void *opaque, const char *name) |
static void format_print(void *opaque, const char *name) |
{ |
{ |
printf(" %s", name); |
printf(" %s", name); |
Line 187 static int read_password(char *buf, int
|
Line 179 static int read_password(char *buf, int
|
} |
} |
#endif |
#endif |
|
|
|
static int print_block_option_help(const char *filename, const char *fmt) |
|
{ |
|
BlockDriver *drv, *proto_drv; |
|
QEMUOptionParameter *create_options = NULL; |
|
|
|
/* Find driver and parse its options */ |
|
drv = bdrv_find_format(fmt); |
|
if (!drv) { |
|
error_report("Unknown file format '%s'", fmt); |
|
return 1; |
|
} |
|
|
|
proto_drv = bdrv_find_protocol(filename); |
|
if (!proto_drv) { |
|
error_report("Unknown protocol '%s'", filename); |
|
return 1; |
|
} |
|
|
|
create_options = append_option_parameters(create_options, |
|
drv->create_options); |
|
create_options = append_option_parameters(create_options, |
|
proto_drv->create_options); |
|
print_option_help(create_options); |
|
free_option_parameters(create_options); |
|
return 0; |
|
} |
|
|
static BlockDriverState *bdrv_new_open(const char *filename, |
static BlockDriverState *bdrv_new_open(const char *filename, |
const char *fmt, |
const char *fmt, |
int flags) |
int flags) |
Line 194 static BlockDriverState *bdrv_new_open(c
|
Line 213 static BlockDriverState *bdrv_new_open(c
|
BlockDriverState *bs; |
BlockDriverState *bs; |
BlockDriver *drv; |
BlockDriver *drv; |
char password[256]; |
char password[256]; |
|
int ret; |
|
|
|
bs = bdrv_new("image"); |
|
|
bs = bdrv_new(""); |
|
if (!bs) { |
|
error("Not enough memory"); |
|
goto fail; |
|
} |
|
if (fmt) { |
if (fmt) { |
drv = bdrv_find_format(fmt); |
drv = bdrv_find_format(fmt); |
if (!drv) { |
if (!drv) { |
error("Unknown file format '%s'", fmt); |
error_report("Unknown file format '%s'", fmt); |
goto fail; |
goto fail; |
} |
} |
} else { |
} else { |
drv = NULL; |
drv = NULL; |
} |
} |
if (bdrv_open(bs, filename, flags, drv) < 0) { |
|
error("Could not open '%s'", filename); |
ret = bdrv_open(bs, filename, flags, drv); |
|
if (ret < 0) { |
|
error_report("Could not open '%s': %s", filename, strerror(-ret)); |
goto fail; |
goto fail; |
} |
} |
|
|
if (bdrv_is_encrypted(bs)) { |
if (bdrv_is_encrypted(bs)) { |
printf("Disk image '%s' is encrypted.\n", filename); |
printf("Disk image '%s' is encrypted.\n", filename); |
if (read_password(password, sizeof(password)) < 0) { |
if (read_password(password, sizeof(password)) < 0) { |
error("No password given"); |
error_report("No password given"); |
goto fail; |
goto fail; |
} |
} |
if (bdrv_set_key(bs, password) < 0) { |
if (bdrv_set_key(bs, password) < 0) { |
error("invalid password"); |
error_report("invalid password"); |
goto fail; |
goto fail; |
} |
} |
} |
} |
Line 233 fail:
|
Line 253 fail:
|
} |
} |
|
|
static int add_old_style_options(const char *fmt, QEMUOptionParameter *list, |
static int add_old_style_options(const char *fmt, QEMUOptionParameter *list, |
int flags, const char *base_filename, const char *base_fmt) |
const char *base_filename, |
|
const char *base_fmt) |
{ |
{ |
if (flags & BLOCK_FLAG_ENCRYPT) { |
|
if (set_option_parameter(list, BLOCK_OPT_ENCRYPT, "on")) { |
|
error("Encryption not supported for file format '%s'", fmt); |
|
return -1; |
|
} |
|
} |
|
if (flags & BLOCK_FLAG_COMPAT6) { |
|
if (set_option_parameter(list, BLOCK_OPT_COMPAT6, "on")) { |
|
error("VMDK version 6 not supported for file format '%s'", fmt); |
|
return -1; |
|
} |
|
} |
|
|
|
if (base_filename) { |
if (base_filename) { |
if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) { |
if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) { |
error("Backing file not supported for file format '%s'", fmt); |
error_report("Backing file not supported for file format '%s'", |
|
fmt); |
return -1; |
return -1; |
} |
} |
} |
} |
if (base_fmt) { |
if (base_fmt) { |
if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) { |
if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) { |
error("Backing file format not supported for file format '%s'", fmt); |
error_report("Backing file format not supported for file " |
|
"format '%s'", fmt); |
return -1; |
return -1; |
} |
} |
} |
} |
Line 265 static int add_old_style_options(const c
|
Line 275 static int add_old_style_options(const c
|
|
|
static int img_create(int argc, char **argv) |
static int img_create(int argc, char **argv) |
{ |
{ |
int c, ret = 0, flags; |
int c, ret = 0; |
|
uint64_t img_size = -1; |
const char *fmt = "raw"; |
const char *fmt = "raw"; |
const char *base_fmt = NULL; |
const char *base_fmt = NULL; |
const char *filename; |
const char *filename; |
const char *base_filename = NULL; |
const char *base_filename = NULL; |
BlockDriver *drv, *proto_drv; |
|
QEMUOptionParameter *param = NULL, *create_options = NULL; |
|
char *options = NULL; |
char *options = NULL; |
|
|
flags = 0; |
|
for(;;) { |
for(;;) { |
c = getopt(argc, argv, "F:b:f:he6o:"); |
c = getopt(argc, argv, "F:b:f:he6o:"); |
if (c == -1) |
if (c == -1) { |
break; |
break; |
|
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
break; |
break; |
Line 293 static int img_create(int argc, char **a
|
Line 303 static int img_create(int argc, char **a
|
fmt = optarg; |
fmt = optarg; |
break; |
break; |
case 'e': |
case 'e': |
flags |= BLOCK_FLAG_ENCRYPT; |
error_report("qemu-img: option -e is deprecated, please use \'-o " |
break; |
"encryption\' instead!"); |
|
return 1; |
case '6': |
case '6': |
flags |= BLOCK_FLAG_COMPAT6; |
error_report("qemu-img: option -6 is deprecated, please use \'-o " |
break; |
"compat6\' instead!"); |
|
return 1; |
case 'o': |
case 'o': |
options = optarg; |
options = optarg; |
break; |
break; |
Line 305 static int img_create(int argc, char **a
|
Line 317 static int img_create(int argc, char **a
|
} |
} |
|
|
/* Get the filename */ |
/* Get the filename */ |
if (optind >= argc) |
if (optind >= argc) { |
help(); |
help(); |
filename = argv[optind++]; |
|
|
|
/* Find driver and parse its options */ |
|
drv = bdrv_find_format(fmt); |
|
if (!drv) { |
|
error("Unknown file format '%s'", fmt); |
|
return 1; |
|
} |
|
|
|
proto_drv = bdrv_find_protocol(filename); |
|
if (!proto_drv) { |
|
error("Unknown protocol '%s'", filename); |
|
return 1; |
|
} |
} |
|
filename = argv[optind++]; |
|
|
create_options = append_option_parameters(create_options, |
/* Get image size, if specified */ |
drv->create_options); |
if (optind < argc) { |
create_options = append_option_parameters(create_options, |
int64_t sval; |
proto_drv->create_options); |
sval = strtosz_suffix(argv[optind++], NULL, STRTOSZ_DEFSUFFIX_B); |
|
if (sval < 0) { |
if (options && !strcmp(options, "?")) { |
error_report("Invalid image size specified! You may use k, M, G or " |
print_option_help(create_options); |
"T suffixes for "); |
goto out; |
error_report("kilobytes, megabytes, gigabytes and terabytes."); |
} |
|
|
|
/* Create parameter list with default values */ |
|
param = parse_option_parameters("", create_options, param); |
|
set_option_parameter_int(param, BLOCK_OPT_SIZE, -1); |
|
|
|
/* Parse -o options */ |
|
if (options) { |
|
param = parse_option_parameters(options, create_options, param); |
|
if (param == NULL) { |
|
error("Invalid options for file format '%s'.", fmt); |
|
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
|
img_size = (uint64_t)sval; |
} |
} |
|
|
/* Add size to parameters */ |
if (options && !strcmp(options, "?")) { |
if (optind < argc) { |
ret = print_block_option_help(filename, fmt); |
set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]); |
|
} |
|
|
|
/* Add old-style options to parameters */ |
|
ret = add_old_style_options(fmt, param, flags, base_filename, base_fmt); |
|
if (ret < 0) { |
|
goto out; |
goto out; |
} |
} |
|
|
// The size for the image must always be specified, with one exception: |
ret = bdrv_img_create(filename, fmt, base_filename, base_fmt, |
// If we are using a backing file, we can obtain the size from there |
options, img_size, BDRV_O_FLAGS); |
if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) { |
|
|
|
QEMUOptionParameter *backing_file = |
|
get_option_parameter(param, BLOCK_OPT_BACKING_FILE); |
|
QEMUOptionParameter *backing_fmt = |
|
get_option_parameter(param, BLOCK_OPT_BACKING_FMT); |
|
|
|
if (backing_file && backing_file->value.s) { |
|
BlockDriverState *bs; |
|
uint64_t size; |
|
const char *fmt = NULL; |
|
char buf[32]; |
|
|
|
if (backing_fmt && backing_fmt->value.s) { |
|
if (bdrv_find_format(backing_fmt->value.s)) { |
|
fmt = backing_fmt->value.s; |
|
} else { |
|
error("Unknown backing file format '%s'", |
|
backing_fmt->value.s); |
|
ret = -1; |
|
goto out; |
|
} |
|
} |
|
|
|
bs = bdrv_new_open(backing_file->value.s, fmt, BDRV_O_FLAGS); |
|
if (!bs) { |
|
ret = -1; |
|
goto out; |
|
} |
|
bdrv_get_geometry(bs, &size); |
|
size *= 512; |
|
bdrv_delete(bs); |
|
|
|
snprintf(buf, sizeof(buf), "%" PRId64, size); |
|
set_option_parameter(param, BLOCK_OPT_SIZE, buf); |
|
} else { |
|
error("Image creation needs a size parameter"); |
|
ret = -1; |
|
goto out; |
|
} |
|
} |
|
|
|
printf("Formatting '%s', fmt=%s ", filename, fmt); |
|
print_option_parameters(param); |
|
puts(""); |
|
|
|
ret = bdrv_create(drv, filename, param); |
|
free_option_parameters(create_options); |
|
free_option_parameters(param); |
|
|
|
if (ret < 0) { |
|
if (ret == -ENOTSUP) { |
|
error("Formatting or formatting option not supported for file format '%s'", fmt); |
|
} else if (ret == -EFBIG) { |
|
error("The image size is too large for file format '%s'", fmt); |
|
} else { |
|
error("%s: error while creating %s: %s", filename, fmt, strerror(-ret)); |
|
} |
|
} |
|
out: |
out: |
if (ret) { |
if (ret) { |
return 1; |
return 1; |
Line 443 static int img_check(int argc, char **ar
|
Line 368 static int img_check(int argc, char **ar
|
fmt = NULL; |
fmt = NULL; |
for(;;) { |
for(;;) { |
c = getopt(argc, argv, "f:h"); |
c = getopt(argc, argv, "f:h"); |
if (c == -1) |
if (c == -1) { |
break; |
break; |
|
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
break; |
break; |
Line 454 static int img_check(int argc, char **ar
|
Line 381 static int img_check(int argc, char **ar
|
break; |
break; |
} |
} |
} |
} |
if (optind >= argc) |
if (optind >= argc) { |
help(); |
help(); |
|
} |
filename = argv[optind++]; |
filename = argv[optind++]; |
|
|
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS); |
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS); |
Line 465 static int img_check(int argc, char **ar
|
Line 393 static int img_check(int argc, char **ar
|
ret = bdrv_check(bs, &result); |
ret = bdrv_check(bs, &result); |
|
|
if (ret == -ENOTSUP) { |
if (ret == -ENOTSUP) { |
error("This image format does not support checks"); |
error_report("This image format does not support checks"); |
bdrv_delete(bs); |
bdrv_delete(bs); |
return 1; |
return 1; |
} |
} |
Line 519 static int img_commit(int argc, char **a
|
Line 447 static int img_commit(int argc, char **a
|
fmt = NULL; |
fmt = NULL; |
for(;;) { |
for(;;) { |
c = getopt(argc, argv, "f:h"); |
c = getopt(argc, argv, "f:h"); |
if (c == -1) |
if (c == -1) { |
break; |
break; |
|
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
break; |
break; |
Line 530 static int img_commit(int argc, char **a
|
Line 460 static int img_commit(int argc, char **a
|
break; |
break; |
} |
} |
} |
} |
if (optind >= argc) |
if (optind >= argc) { |
help(); |
help(); |
|
} |
filename = argv[optind++]; |
filename = argv[optind++]; |
|
|
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR); |
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR); |
Line 544 static int img_commit(int argc, char **a
|
Line 475 static int img_commit(int argc, char **a
|
printf("Image committed.\n"); |
printf("Image committed.\n"); |
break; |
break; |
case -ENOENT: |
case -ENOENT: |
error("No disk inserted"); |
error_report("No disk inserted"); |
break; |
break; |
case -EACCES: |
case -EACCES: |
error("Image is read-only"); |
error_report("Image is read-only"); |
break; |
break; |
case -ENOTSUP: |
case -ENOTSUP: |
error("Image is already committed"); |
error_report("Image is already committed"); |
break; |
break; |
default: |
default: |
error("Error while committing image"); |
error_report("Error while committing image"); |
break; |
break; |
} |
} |
|
|
Line 635 static int compare_sectors(const uint8_t
|
Line 566 static int compare_sectors(const uint8_t
|
|
|
static int img_convert(int argc, char **argv) |
static int img_convert(int argc, char **argv) |
{ |
{ |
int c, ret = 0, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors; |
int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors; |
const char *fmt, *out_fmt, *out_baseimg, *out_filename; |
const char *fmt, *out_fmt, *out_baseimg, *out_filename; |
BlockDriver *drv, *proto_drv; |
BlockDriver *drv, *proto_drv; |
BlockDriverState **bs = NULL, *out_bs = NULL; |
BlockDriverState **bs = NULL, *out_bs = NULL; |
Line 645 static int img_convert(int argc, char **
|
Line 576 static int img_convert(int argc, char **
|
const uint8_t *buf1; |
const uint8_t *buf1; |
BlockDriverInfo bdi; |
BlockDriverInfo bdi; |
QEMUOptionParameter *param = NULL, *create_options = NULL; |
QEMUOptionParameter *param = NULL, *create_options = NULL; |
|
QEMUOptionParameter *out_baseimg_param; |
char *options = NULL; |
char *options = NULL; |
|
const char *snapshot_name = NULL; |
|
|
fmt = NULL; |
fmt = NULL; |
out_fmt = "raw"; |
out_fmt = "raw"; |
out_baseimg = NULL; |
out_baseimg = NULL; |
flags = 0; |
compress = 0; |
for(;;) { |
for(;;) { |
c = getopt(argc, argv, "f:O:B:hce6o:"); |
c = getopt(argc, argv, "f:O:B:s:hce6o:"); |
if (c == -1) |
if (c == -1) { |
break; |
break; |
|
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
break; |
break; |
Line 669 static int img_convert(int argc, char **
|
Line 604 static int img_convert(int argc, char **
|
out_baseimg = optarg; |
out_baseimg = optarg; |
break; |
break; |
case 'c': |
case 'c': |
flags |= BLOCK_FLAG_COMPRESS; |
compress = 1; |
break; |
break; |
case 'e': |
case 'e': |
flags |= BLOCK_FLAG_ENCRYPT; |
error_report("qemu-img: option -e is deprecated, please use \'-o " |
break; |
"encryption\' instead!"); |
|
return 1; |
case '6': |
case '6': |
flags |= BLOCK_FLAG_COMPAT6; |
error_report("qemu-img: option -6 is deprecated, please use \'-o " |
break; |
"compat6\' instead!"); |
|
return 1; |
case 'o': |
case 'o': |
options = optarg; |
options = optarg; |
break; |
break; |
|
case 's': |
|
snapshot_name = optarg; |
|
break; |
} |
} |
} |
} |
|
|
bs_n = argc - optind - 1; |
bs_n = argc - optind - 1; |
if (bs_n < 1) help(); |
if (bs_n < 1) { |
|
help(); |
|
} |
|
|
out_filename = argv[argc - 1]; |
out_filename = argv[argc - 1]; |
|
|
|
if (options && !strcmp(options, "?")) { |
|
ret = print_block_option_help(out_filename, out_fmt); |
|
goto out; |
|
} |
|
|
if (bs_n > 1 && out_baseimg) { |
if (bs_n > 1 && out_baseimg) { |
error("-B makes no sense when concatenating multiple input images"); |
error_report("-B makes no sense when concatenating multiple input " |
return 1; |
"images"); |
|
ret = -1; |
|
goto out; |
} |
} |
|
|
bs = calloc(bs_n, sizeof(BlockDriverState *)); |
bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *)); |
if (!bs) { |
|
error("Out of memory"); |
|
return 1; |
|
} |
|
|
|
total_sectors = 0; |
total_sectors = 0; |
for (bs_i = 0; bs_i < bs_n; bs_i++) { |
for (bs_i = 0; bs_i < bs_n; bs_i++) { |
bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS); |
bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS); |
if (!bs[bs_i]) { |
if (!bs[bs_i]) { |
error("Could not open '%s'", argv[optind + bs_i]); |
error_report("Could not open '%s'", argv[optind + bs_i]); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 711 static int img_convert(int argc, char **
|
Line 656 static int img_convert(int argc, char **
|
total_sectors += bs_sectors; |
total_sectors += bs_sectors; |
} |
} |
|
|
|
if (snapshot_name != NULL) { |
|
if (bs_n > 1) { |
|
error_report("No support for concatenating multiple snapshot\n"); |
|
ret = -1; |
|
goto out; |
|
} |
|
if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) { |
|
error_report("Failed to load snapshot\n"); |
|
ret = -1; |
|
goto out; |
|
} |
|
} |
|
|
/* Find driver and parse its options */ |
/* Find driver and parse its options */ |
drv = bdrv_find_format(out_fmt); |
drv = bdrv_find_format(out_fmt); |
if (!drv) { |
if (!drv) { |
error("Unknown file format '%s'", out_fmt); |
error_report("Unknown file format '%s'", out_fmt); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
|
|
proto_drv = bdrv_find_protocol(out_filename); |
proto_drv = bdrv_find_protocol(out_filename); |
if (!proto_drv) { |
if (!proto_drv) { |
error("Unknown protocol '%s'", out_filename); |
error_report("Unknown protocol '%s'", out_filename); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 730 static int img_convert(int argc, char **
|
Line 688 static int img_convert(int argc, char **
|
drv->create_options); |
drv->create_options); |
create_options = append_option_parameters(create_options, |
create_options = append_option_parameters(create_options, |
proto_drv->create_options); |
proto_drv->create_options); |
if (options && !strcmp(options, "?")) { |
|
print_option_help(create_options); |
|
goto out; |
|
} |
|
|
|
if (options) { |
if (options) { |
param = parse_option_parameters(options, create_options, param); |
param = parse_option_parameters(options, create_options, param); |
if (param == NULL) { |
if (param == NULL) { |
error("Invalid options for file format '%s'.", out_fmt); |
error_report("Invalid options for file format '%s'.", out_fmt); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 747 static int img_convert(int argc, char **
|
Line 701 static int img_convert(int argc, char **
|
} |
} |
|
|
set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512); |
set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512); |
ret = add_old_style_options(out_fmt, param, flags, out_baseimg, NULL); |
ret = add_old_style_options(out_fmt, param, out_baseimg, NULL); |
if (ret < 0) { |
if (ret < 0) { |
goto out; |
goto out; |
} |
} |
|
|
|
/* Get backing file name if -o backing_file was used */ |
|
out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); |
|
if (out_baseimg_param) { |
|
out_baseimg = out_baseimg_param->value.s; |
|
} |
|
|
/* Check if compression is supported */ |
/* Check if compression is supported */ |
if (flags & BLOCK_FLAG_COMPRESS) { |
if (compress) { |
QEMUOptionParameter *encryption = |
QEMUOptionParameter *encryption = |
get_option_parameter(param, BLOCK_OPT_ENCRYPT); |
get_option_parameter(param, BLOCK_OPT_ENCRYPT); |
|
|
if (!drv->bdrv_write_compressed) { |
if (!drv->bdrv_write_compressed) { |
error("Compression not supported for this file format"); |
error_report("Compression not supported for this file format"); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
|
|
if (encryption && encryption->value.n) { |
if (encryption && encryption->value.n) { |
error("Compression and encryption not supported at the same time"); |
error_report("Compression and encryption not supported at " |
|
"the same time"); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 774 static int img_convert(int argc, char **
|
Line 735 static int img_convert(int argc, char **
|
ret = bdrv_create(drv, out_filename, param); |
ret = bdrv_create(drv, out_filename, param); |
if (ret < 0) { |
if (ret < 0) { |
if (ret == -ENOTSUP) { |
if (ret == -ENOTSUP) { |
error("Formatting not supported for file format '%s'", out_fmt); |
error_report("Formatting not supported for file format '%s'", |
|
out_fmt); |
} else if (ret == -EFBIG) { |
} else if (ret == -EFBIG) { |
error("The image size is too large for file format '%s'", out_fmt); |
error_report("The image size is too large for file format '%s'", |
|
out_fmt); |
} else { |
} else { |
error("%s: error while converting %s: %s", out_filename, out_fmt, strerror(-ret)); |
error_report("%s: error while converting %s: %s", |
|
out_filename, out_fmt, strerror(-ret)); |
} |
} |
goto out; |
goto out; |
} |
} |
Line 795 static int img_convert(int argc, char **
|
Line 759 static int img_convert(int argc, char **
|
bdrv_get_geometry(bs[0], &bs_sectors); |
bdrv_get_geometry(bs[0], &bs_sectors); |
buf = qemu_malloc(IO_BUF_SIZE); |
buf = qemu_malloc(IO_BUF_SIZE); |
|
|
if (flags & BLOCK_FLAG_COMPRESS) { |
if (compress) { |
ret = bdrv_get_info(out_bs, &bdi); |
ret = bdrv_get_info(out_bs, &bdi); |
if (ret < 0) { |
if (ret < 0) { |
error("could not get block driver info"); |
error_report("could not get block driver info"); |
goto out; |
goto out; |
} |
} |
cluster_size = bdi.cluster_size; |
cluster_size = bdi.cluster_size; |
if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) { |
if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) { |
error("invalid cluster size"); |
error_report("invalid cluster size"); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 844 static int img_convert(int argc, char **
|
Line 808 static int img_convert(int argc, char **
|
|
|
ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow); |
ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow); |
if (ret < 0) { |
if (ret < 0) { |
error("error while reading"); |
error_report("error while reading"); |
goto out; |
goto out; |
} |
} |
|
|
Line 855 static int img_convert(int argc, char **
|
Line 819 static int img_convert(int argc, char **
|
} |
} |
assert (remainder == 0); |
assert (remainder == 0); |
|
|
if (n < cluster_sectors) |
if (n < cluster_sectors) { |
memset(buf + n * 512, 0, cluster_size - n * 512); |
memset(buf + n * 512, 0, cluster_size - n * 512); |
|
} |
if (is_not_zero(buf, cluster_size)) { |
if (is_not_zero(buf, cluster_size)) { |
ret = bdrv_write_compressed(out_bs, sector_num, buf, |
ret = bdrv_write_compressed(out_bs, sector_num, buf, |
cluster_sectors); |
cluster_sectors); |
if (ret != 0) { |
if (ret != 0) { |
error("error while compressing sector %" PRId64, |
error_report("error while compressing sector %" PRId64, |
sector_num); |
sector_num); |
goto out; |
goto out; |
} |
} |
Line 876 static int img_convert(int argc, char **
|
Line 841 static int img_convert(int argc, char **
|
sector_num = 0; // total number of sectors converted so far |
sector_num = 0; // total number of sectors converted so far |
for(;;) { |
for(;;) { |
nb_sectors = total_sectors - sector_num; |
nb_sectors = total_sectors - sector_num; |
if (nb_sectors <= 0) |
if (nb_sectors <= 0) { |
break; |
break; |
if (nb_sectors >= (IO_BUF_SIZE / 512)) |
} |
|
if (nb_sectors >= (IO_BUF_SIZE / 512)) { |
n = (IO_BUF_SIZE / 512); |
n = (IO_BUF_SIZE / 512); |
else |
} else { |
n = nb_sectors; |
n = nb_sectors; |
|
} |
|
|
while (sector_num - bs_offset >= bs_sectors) { |
while (sector_num - bs_offset >= bs_sectors) { |
bs_i ++; |
bs_i ++; |
Line 893 static int img_convert(int argc, char **
|
Line 860 static int img_convert(int argc, char **
|
sector_num, bs_i, bs_offset, bs_sectors); */ |
sector_num, bs_i, bs_offset, bs_sectors); */ |
} |
} |
|
|
if (n > bs_offset + bs_sectors - sector_num) |
if (n > bs_offset + bs_sectors - sector_num) { |
n = bs_offset + bs_sectors - sector_num; |
n = bs_offset + bs_sectors - sector_num; |
|
} |
|
|
if (has_zero_init) { |
if (has_zero_init) { |
/* If the output image is being created as a copy on write image, |
/* If the output image is being created as a copy on write image, |
Line 917 static int img_convert(int argc, char **
|
Line 885 static int img_convert(int argc, char **
|
|
|
ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n); |
ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n); |
if (ret < 0) { |
if (ret < 0) { |
error("error while reading"); |
error_report("error while reading"); |
goto out; |
goto out; |
} |
} |
/* NOTE: at the same time we convert, we do not write zero |
/* NOTE: at the same time we convert, we do not write zero |
Line 936 static int img_convert(int argc, char **
|
Line 904 static int img_convert(int argc, char **
|
is_allocated_sectors(buf1, n, &n1)) { |
is_allocated_sectors(buf1, n, &n1)) { |
ret = bdrv_write(out_bs, sector_num, buf1, n1); |
ret = bdrv_write(out_bs, sector_num, buf1, n1); |
if (ret < 0) { |
if (ret < 0) { |
error("error while writing"); |
error_report("error while writing"); |
goto out; |
goto out; |
} |
} |
} |
} |
Line 953 out:
|
Line 921 out:
|
if (out_bs) { |
if (out_bs) { |
bdrv_delete(out_bs); |
bdrv_delete(out_bs); |
} |
} |
for (bs_i = 0; bs_i < bs_n; bs_i++) { |
if (bs) { |
if (bs[bs_i]) { |
for (bs_i = 0; bs_i < bs_n; bs_i++) { |
bdrv_delete(bs[bs_i]); |
if (bs[bs_i]) { |
|
bdrv_delete(bs[bs_i]); |
|
} |
} |
} |
|
qemu_free(bs); |
} |
} |
free(bs); |
|
if (ret) { |
if (ret) { |
return 1; |
return 1; |
} |
} |
Line 1028 static int img_info(int argc, char **arg
|
Line 998 static int img_info(int argc, char **arg
|
fmt = NULL; |
fmt = NULL; |
for(;;) { |
for(;;) { |
c = getopt(argc, argv, "f:h"); |
c = getopt(argc, argv, "f:h"); |
if (c == -1) |
if (c == -1) { |
break; |
break; |
|
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
break; |
break; |
Line 1039 static int img_info(int argc, char **arg
|
Line 1011 static int img_info(int argc, char **arg
|
break; |
break; |
} |
} |
} |
} |
if (optind >= argc) |
if (optind >= argc) { |
help(); |
help(); |
|
} |
filename = argv[optind++]; |
filename = argv[optind++]; |
|
|
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING); |
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING); |
Line 1051 static int img_info(int argc, char **arg
|
Line 1024 static int img_info(int argc, char **arg
|
bdrv_get_geometry(bs, &total_sectors); |
bdrv_get_geometry(bs, &total_sectors); |
get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512); |
get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512); |
allocated_size = get_allocated_file_size(filename); |
allocated_size = get_allocated_file_size(filename); |
if (allocated_size < 0) |
if (allocated_size < 0) { |
snprintf(dsize_buf, sizeof(dsize_buf), "unavailable"); |
snprintf(dsize_buf, sizeof(dsize_buf), "unavailable"); |
else |
} else { |
get_human_readable_size(dsize_buf, sizeof(dsize_buf), |
get_human_readable_size(dsize_buf, sizeof(dsize_buf), |
allocated_size); |
allocated_size); |
|
} |
printf("image: %s\n" |
printf("image: %s\n" |
"file format: %s\n" |
"file format: %s\n" |
"virtual size: %s (%" PRId64 " bytes)\n" |
"virtual size: %s (%" PRId64 " bytes)\n" |
Line 1063 static int img_info(int argc, char **arg
|
Line 1037 static int img_info(int argc, char **arg
|
filename, fmt_name, size_buf, |
filename, fmt_name, size_buf, |
(total_sectors * 512), |
(total_sectors * 512), |
dsize_buf); |
dsize_buf); |
if (bdrv_is_encrypted(bs)) |
if (bdrv_is_encrypted(bs)) { |
printf("encrypted: yes\n"); |
printf("encrypted: yes\n"); |
|
} |
if (bdrv_get_info(bs, &bdi) >= 0) { |
if (bdrv_get_info(bs, &bdi) >= 0) { |
if (bdi.cluster_size != 0) |
if (bdi.cluster_size != 0) { |
printf("cluster_size: %d\n", bdi.cluster_size); |
printf("cluster_size: %d\n", bdi.cluster_size); |
|
} |
} |
} |
bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename)); |
bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename)); |
if (backing_filename[0] != '\0') { |
if (backing_filename[0] != '\0') { |
Line 1096 static int img_snapshot(int argc, char *
|
Line 1072 static int img_snapshot(int argc, char *
|
int action = 0; |
int action = 0; |
qemu_timeval tv; |
qemu_timeval tv; |
|
|
bdrv_oflags = BDRV_O_RDWR; |
bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR; |
/* Parse commandline parameters */ |
/* Parse commandline parameters */ |
for(;;) { |
for(;;) { |
c = getopt(argc, argv, "la:c:d:h"); |
c = getopt(argc, argv, "la:c:d:h"); |
if (c == -1) |
if (c == -1) { |
break; |
break; |
|
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
return 0; |
return 0; |
Line 1141 static int img_snapshot(int argc, char *
|
Line 1119 static int img_snapshot(int argc, char *
|
} |
} |
} |
} |
|
|
if (optind >= argc) |
if (optind >= argc) { |
help(); |
help(); |
|
} |
filename = argv[optind++]; |
filename = argv[optind++]; |
|
|
/* Open the image */ |
/* Open the image */ |
Line 1166 static int img_snapshot(int argc, char *
|
Line 1145 static int img_snapshot(int argc, char *
|
sn.date_nsec = tv.tv_usec * 1000; |
sn.date_nsec = tv.tv_usec * 1000; |
|
|
ret = bdrv_snapshot_create(bs, &sn); |
ret = bdrv_snapshot_create(bs, &sn); |
if (ret) |
if (ret) { |
error("Could not create snapshot '%s': %d (%s)", |
error_report("Could not create snapshot '%s': %d (%s)", |
snapshot_name, ret, strerror(-ret)); |
snapshot_name, ret, strerror(-ret)); |
|
} |
break; |
break; |
|
|
case SNAPSHOT_APPLY: |
case SNAPSHOT_APPLY: |
ret = bdrv_snapshot_goto(bs, snapshot_name); |
ret = bdrv_snapshot_goto(bs, snapshot_name); |
if (ret) |
if (ret) { |
error("Could not apply snapshot '%s': %d (%s)", |
error_report("Could not apply snapshot '%s': %d (%s)", |
snapshot_name, ret, strerror(-ret)); |
snapshot_name, ret, strerror(-ret)); |
|
} |
break; |
break; |
|
|
case SNAPSHOT_DELETE: |
case SNAPSHOT_DELETE: |
ret = bdrv_snapshot_delete(bs, snapshot_name); |
ret = bdrv_snapshot_delete(bs, snapshot_name); |
if (ret) |
if (ret) { |
error("Could not delete snapshot '%s': %d (%s)", |
error_report("Could not delete snapshot '%s': %d (%s)", |
snapshot_name, ret, strerror(-ret)); |
snapshot_name, ret, strerror(-ret)); |
|
} |
break; |
break; |
} |
} |
|
|
Line 1210 static int img_rebase(int argc, char **a
|
Line 1192 static int img_rebase(int argc, char **a
|
|
|
for(;;) { |
for(;;) { |
c = getopt(argc, argv, "uhf:F:b:"); |
c = getopt(argc, argv, "uhf:F:b:"); |
if (c == -1) |
if (c == -1) { |
break; |
break; |
|
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
return 0; |
return 0; |
Line 1231 static int img_rebase(int argc, char **a
|
Line 1215 static int img_rebase(int argc, char **a
|
} |
} |
} |
} |
|
|
if ((optind >= argc) || !out_baseimg) |
if ((optind >= argc) || !out_baseimg) { |
help(); |
help(); |
|
} |
filename = argv[optind++]; |
filename = argv[optind++]; |
|
|
/* |
/* |
Line 1254 static int img_rebase(int argc, char **a
|
Line 1239 static int img_rebase(int argc, char **a
|
if (!unsafe && bs->backing_format[0] != '\0') { |
if (!unsafe && bs->backing_format[0] != '\0') { |
old_backing_drv = bdrv_find_format(bs->backing_format); |
old_backing_drv = bdrv_find_format(bs->backing_format); |
if (old_backing_drv == NULL) { |
if (old_backing_drv == NULL) { |
error("Invalid format name: '%s'", bs->backing_format); |
error_report("Invalid format name: '%s'", bs->backing_format); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 1263 static int img_rebase(int argc, char **a
|
Line 1248 static int img_rebase(int argc, char **a
|
if (out_basefmt != NULL) { |
if (out_basefmt != NULL) { |
new_backing_drv = bdrv_find_format(out_basefmt); |
new_backing_drv = bdrv_find_format(out_basefmt); |
if (new_backing_drv == NULL) { |
if (new_backing_drv == NULL) { |
error("Invalid format name: '%s'", out_basefmt); |
error_report("Invalid format name: '%s'", out_basefmt); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 1282 static int img_rebase(int argc, char **a
|
Line 1267 static int img_rebase(int argc, char **a
|
ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS, |
ret = bdrv_open(bs_old_backing, backing_name, BDRV_O_FLAGS, |
old_backing_drv); |
old_backing_drv); |
if (ret) { |
if (ret) { |
error("Could not open old backing file '%s'", backing_name); |
error_report("Could not open old backing file '%s'", backing_name); |
goto out; |
goto out; |
} |
} |
|
|
Line 1290 static int img_rebase(int argc, char **a
|
Line 1275 static int img_rebase(int argc, char **a
|
ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS, |
ret = bdrv_open(bs_new_backing, out_baseimg, BDRV_O_FLAGS, |
new_backing_drv); |
new_backing_drv); |
if (ret) { |
if (ret) { |
error("Could not open new backing file '%s'", out_baseimg); |
error_report("Could not open new backing file '%s'", out_baseimg); |
goto out; |
goto out; |
} |
} |
} |
} |
Line 1334 static int img_rebase(int argc, char **a
|
Line 1319 static int img_rebase(int argc, char **a
|
/* Read old and new backing file */ |
/* Read old and new backing file */ |
ret = bdrv_read(bs_old_backing, sector, buf_old, n); |
ret = bdrv_read(bs_old_backing, sector, buf_old, n); |
if (ret < 0) { |
if (ret < 0) { |
error("error while reading from old backing file"); |
error_report("error while reading from old backing file"); |
goto out; |
goto out; |
} |
} |
ret = bdrv_read(bs_new_backing, sector, buf_new, n); |
ret = bdrv_read(bs_new_backing, sector, buf_new, n); |
if (ret < 0) { |
if (ret < 0) { |
error("error while reading from new backing file"); |
error_report("error while reading from new backing file"); |
goto out; |
goto out; |
} |
} |
|
|
Line 1355 static int img_rebase(int argc, char **a
|
Line 1340 static int img_rebase(int argc, char **a
|
ret = bdrv_write(bs, sector + written, |
ret = bdrv_write(bs, sector + written, |
buf_old + written * 512, pnum); |
buf_old + written * 512, pnum); |
if (ret < 0) { |
if (ret < 0) { |
error("Error while writing to COW image: %s", |
error_report("Error while writing to COW image: %s", |
strerror(-ret)); |
strerror(-ret)); |
goto out; |
goto out; |
} |
} |
Line 1376 static int img_rebase(int argc, char **a
|
Line 1361 static int img_rebase(int argc, char **a
|
*/ |
*/ |
ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt); |
ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt); |
if (ret == -ENOSPC) { |
if (ret == -ENOSPC) { |
error("Could not change the backing file to '%s': No space left in " |
error_report("Could not change the backing file to '%s': No " |
"the file header", out_baseimg); |
"space left in the file header", out_baseimg); |
} else if (ret < 0) { |
} else if (ret < 0) { |
error("Could not change the backing file to '%s': %s", |
error_report("Could not change the backing file to '%s': %s", |
out_baseimg, strerror(-ret)); |
out_baseimg, strerror(-ret)); |
} |
} |
|
|
Line 1408 static int img_resize(int argc, char **a
|
Line 1393 static int img_resize(int argc, char **a
|
int c, ret, relative; |
int c, ret, relative; |
const char *filename, *fmt, *size; |
const char *filename, *fmt, *size; |
int64_t n, total_size; |
int64_t n, total_size; |
BlockDriverState *bs; |
BlockDriverState *bs = NULL; |
QEMUOptionParameter *param; |
QEMUOptionParameter *param; |
QEMUOptionParameter resize_options[] = { |
QEMUOptionParameter resize_options[] = { |
{ |
{ |
Line 1426 static int img_resize(int argc, char **a
|
Line 1411 static int img_resize(int argc, char **a
|
break; |
break; |
} |
} |
switch(c) { |
switch(c) { |
|
case '?': |
case 'h': |
case 'h': |
help(); |
help(); |
break; |
break; |
Line 1459 static int img_resize(int argc, char **a
|
Line 1445 static int img_resize(int argc, char **a
|
param = parse_option_parameters("", resize_options, NULL); |
param = parse_option_parameters("", resize_options, NULL); |
if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) { |
if (set_option_parameter(param, BLOCK_OPT_SIZE, size)) { |
/* Error message already printed when size parsing fails */ |
/* Error message already printed when size parsing fails */ |
exit(1); |
ret = -1; |
|
goto out; |
} |
} |
n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n; |
n = get_option_parameter(param, BLOCK_OPT_SIZE)->value.n; |
free_option_parameters(param); |
free_option_parameters(param); |
|
|
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR); |
bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR); |
if (!bs) { |
if (!bs) { |
return 1; |
ret = -1; |
|
goto out; |
} |
} |
|
|
if (relative) { |
if (relative) { |
Line 1475 static int img_resize(int argc, char **a
|
Line 1463 static int img_resize(int argc, char **a
|
total_size = n; |
total_size = n; |
} |
} |
if (total_size <= 0) { |
if (total_size <= 0) { |
error("New image size must be positive"); |
error_report("New image size must be positive"); |
ret = -1; |
ret = -1; |
goto out; |
goto out; |
} |
} |
Line 1486 static int img_resize(int argc, char **a
|
Line 1474 static int img_resize(int argc, char **a
|
printf("Image resized.\n"); |
printf("Image resized.\n"); |
break; |
break; |
case -ENOTSUP: |
case -ENOTSUP: |
error("This image format does not support resize"); |
error_report("This image format does not support resize"); |
break; |
break; |
case -EACCES: |
case -EACCES: |
error("Image is read-only"); |
error_report("Image is read-only"); |
break; |
break; |
default: |
default: |
error("Error resizing image (%d)", -ret); |
error_report("Error resizing image (%d)", -ret); |
break; |
break; |
} |
} |
out: |
out: |
bdrv_delete(bs); |
if (bs) { |
|
bdrv_delete(bs); |
|
} |
if (ret) { |
if (ret) { |
return 1; |
return 1; |
} |
} |
Line 1517 int main(int argc, char **argv)
|
Line 1507 int main(int argc, char **argv)
|
const img_cmd_t *cmd; |
const img_cmd_t *cmd; |
const char *cmdname; |
const char *cmdname; |
|
|
|
error_set_progname(argv[0]); |
|
|
bdrv_init(); |
bdrv_init(); |
if (argc < 2) |
if (argc < 2) |
help(); |
help(); |