@@ -395,6 +395,7 @@ typedef struct CreateCo {
BlockDriver *drv;
char *filename;
QEMUOptionParameter *options;
+ QemuOpts *opts;
int ret;
Error *err;
} CreateCo;
@@ -407,7 +408,10 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
CreateCo *cco = opaque;
assert(cco->drv);
- ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
+ if (cco->drv->bdrv_create2)
+ ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err);
+ else
+ ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
if (error_is_set(&local_err)) {
error_propagate(&cco->err, local_err);
}
@@ -415,7 +419,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
}
int bdrv_create(BlockDriver *drv, const char* filename,
- QEMUOptionParameter *options, Error **errp)
+ QEMUOptionParameter *options, QemuOpts *opts, Error **errp)
{
int ret;
@@ -424,11 +428,12 @@ int bdrv_create(BlockDriver *drv, const char* filename,
.drv = drv,
.filename = g_strdup(filename),
.options = options,
+ .opts = opts,
.ret = NOT_DONE,
.err = NULL,
};
- if (!drv->bdrv_create) {
+ if (!drv->bdrv_create && !drv->bdrv_create2) {
error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
ret = -ENOTSUP;
goto out;
@@ -460,7 +465,7 @@ out:
}
int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
- Error **errp)
+ QemuOpts *opts, Error **errp)
{
BlockDriver *drv;
Error *local_err = NULL;
@@ -472,7 +477,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
return -ENOENT;
}
- ret = bdrv_create(drv, filename, options, &local_err);
+ ret = bdrv_create(drv, filename, options, opts, &local_err);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
}
@@ -1053,7 +1058,8 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
BlockDriverState *bs1;
int64_t total_size;
BlockDriver *bdrv_qcow2;
- QEMUOptionParameter *create_options;
+ QEMUOptionParameter *create_options = NULL;
+ QemuOpts *opts = NULL;
QDict *snapshot_options;
/* if snapshot, we create a temporary backing file and open it
@@ -1080,13 +1086,18 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
}
bdrv_qcow2 = bdrv_find_format("qcow2");
- create_options = parse_option_parameters("", bdrv_qcow2->create_options,
- NULL);
-
- set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
+ if (bdrv_qcow2->bdrv_create2) {
+ opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0, &error_abort);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
+ } else {
+ create_options =
+ parse_option_parameters("", bdrv_qcow2->create_options, NULL);
+ set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
+ }
- ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
+ ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, opts, &local_err);
free_option_parameters(create_options);
+ qemu_opts_del(opts);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create temporary overlay "
"'%s': %s", tmp_filename,
@@ -4712,7 +4723,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
Error **errp, bool quiet)
{
QEMUOptionParameter *param = NULL, *create_options = NULL;
- QEMUOptionParameter *backing_fmt, *backing_file, *size;
+ QemuOptsList *create_opts = NULL;
+ QemuOpts *opts = NULL;
BlockDriver *drv, *proto_drv;
BlockDriver *backing_drv = NULL;
Error *local_err = NULL;
@@ -4731,125 +4743,246 @@ void bdrv_img_create(const char *filename, const char *fmt,
return;
}
- create_options = append_option_parameters(create_options,
- drv->create_options);
- create_options = append_option_parameters(create_options,
- proto_drv->create_options);
+ if (drv->bdrv_create2) {
+ const char *backing_fmt, *backing_file;
+ int64_t size;
- /* Create parameter list with default values */
- param = parse_option_parameters("", create_options, param);
+ create_opts = qemu_opts_append(create_opts, drv->create_opts);
+ create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
+ /* Create parameter list with default values */
+ opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
- set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
- /* Parse -o options */
- if (options) {
- param = parse_option_parameters(options, create_options, param);
- if (param == NULL) {
- error_setg(errp, "Invalid options for file format '%s'.", fmt);
- goto out;
+ /* Parse -o options */
+ if (options) {
+ if (qemu_opts_do_parse(opts, options, NULL) != 0) {
+ error_setg(errp, "Invalid options for file format '%s'.", fmt);
+ goto out;
+ }
}
- }
- if (base_filename) {
- if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
- base_filename)) {
- error_setg(errp, "Backing file not supported for file format '%s'",
- fmt);
- goto out;
+ if (base_filename) {
+ if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) {
+ error_setg(errp, "Backing file not supported for file format '%s'",
+ fmt);
+ goto out;
+ }
}
- }
- if (base_fmt) {
- if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
- error_setg(errp, "Backing file format not supported for file "
- "format '%s'", fmt);
- goto out;
+ if (base_fmt) {
+ if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+ error_setg(errp, "Backing file format not supported for file "
+ "format '%s'", fmt);
+ goto out;
+ }
}
- }
- backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
- if (backing_file && backing_file->value.s) {
- if (!strcmp(filename, backing_file->value.s)) {
- error_setg(errp, "Error: Trying to create an image with the "
- "same filename as the backing file");
- goto out;
+ backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+ if (backing_file) {
+ if (!strcmp(filename, backing_file)) {
+ error_setg(errp, "Error: Trying to create an image with the "
+ "same filename as the backing file");
+ goto out;
+ }
}
- }
- backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
- if (backing_fmt && backing_fmt->value.s) {
- backing_drv = bdrv_find_format(backing_fmt->value.s);
- if (!backing_drv) {
- error_setg(errp, "Unknown backing file format '%s'",
- backing_fmt->value.s);
- goto out;
+ backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
+ if (backing_fmt) {
+ backing_drv = bdrv_find_format(backing_fmt);
+ if (!backing_drv) {
+ error_setg(errp, "Unknown backing file format '%s'",
+ backing_fmt);
+ goto out;
+ }
+ }
+
+ // The size for the image must always be specified, with one exception:
+ // If we are using a backing file, we can obtain the size from there
+ size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
+ if (size == -1) {
+ if (backing_file) {
+ BlockDriverState *bs;
+ uint64_t size;
+ char buf[32];
+ int back_flags;
+
+ /* backing files always opened read-only */
+ back_flags =
+ flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+
+ bs = bdrv_new("");
+
+ ret = bdrv_open(bs, backing_file, NULL, back_flags,
+ backing_drv, &local_err);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Could not open '%s': %s",
+ backing_file,
+ error_get_pretty(local_err));
+ error_free(local_err);
+ local_err = NULL;
+ bdrv_unref(bs);
+ goto out;
+ }
+ bdrv_get_geometry(bs, &size);
+ size *= 512;
+
+ snprintf(buf, sizeof(buf), "%" PRId64, size);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size);
+
+ bdrv_unref(bs);
+ } else {
+ error_setg(errp, "Image creation needs a size parameter");
+ goto out;
+ }
+ }
+
+ if (!quiet) {
+ printf("Formatting '%s', fmt=%s ", filename, fmt);
+ qemu_opts_print(opts);
+ puts("");
+ }
+
+ ret = bdrv_create(drv, filename, NULL, opts, &local_err);
+ if (ret == -EFBIG) {
+ /* This is generally a better message than whatever the driver would
+ * deliver (especially because of the cluster_size_hint), since that
+ * is most probably not much different from "image too large". */
+ const char *cluster_size_hint = "";
+ if (qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, 0)) {
+ cluster_size_hint = " (try using a larger cluster size)";
+ }
+ error_setg(errp, "The image size is too large for file format '%s'"
+ "%s", fmt, cluster_size_hint);
+ error_free(local_err);
+ local_err = NULL;
}
- }
- // The size for the image must always be specified, with one exception:
- // If we are using a backing file, we can obtain the size from there
- size = get_option_parameter(param, BLOCK_OPT_SIZE);
- if (size && size->value.n == -1) {
+ } else {
+ QEMUOptionParameter *backing_fmt, *backing_file, *size;
+
+ create_options = append_option_parameters(create_options,
+ drv->create_options);
+ create_options = append_option_parameters(create_options,
+ proto_drv->create_options);
+
+ /* Create parameter list with default values */
+ param = parse_option_parameters("", create_options, param);
+
+ set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
+
+ /* Parse -o options */
+ if (options) {
+ param = parse_option_parameters(options, create_options, param);
+ if (param == NULL) {
+ error_setg(errp, "Invalid options for file format '%s'.", fmt);
+ goto out;
+ }
+ }
+
+ if (base_filename) {
+ if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
+ base_filename)) {
+ error_setg(errp, "Backing file not supported for file format '%s'",
+ fmt);
+ goto out;
+ }
+ }
+
+ if (base_fmt) {
+ if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+ error_setg(errp, "Backing file format not supported for file "
+ "format '%s'", fmt);
+ goto out;
+ }
+ }
+
+ backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
if (backing_file && backing_file->value.s) {
- BlockDriverState *bs;
- uint64_t size;
- char buf[32];
- int back_flags;
+ if (!strcmp(filename, backing_file->value.s)) {
+ error_setg(errp, "Error: Trying to create an image with the "
+ "same filename as the backing file");
+ goto out;
+ }
+ }
- /* backing files always opened read-only */
- back_flags =
- flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+ backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
+ if (backing_fmt && backing_fmt->value.s) {
+ backing_drv = bdrv_find_format(backing_fmt->value.s);
+ if (!backing_drv) {
+ error_setg(errp, "Unknown backing file format '%s'",
+ backing_fmt->value.s);
+ goto out;
+ }
+ }
- bs = bdrv_new("");
+ // The size for the image must always be specified, with one exception:
+ // If we are using a backing file, we can obtain the size from there
+ size = get_option_parameter(param, BLOCK_OPT_SIZE);
+ if (size && size->value.n == -1) {
+ if (backing_file && backing_file->value.s) {
+ BlockDriverState *bs;
+ uint64_t size;
+ char buf[32];
+ int back_flags;
+
+ /* backing files always opened read-only */
+ back_flags =
+ flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+
+ bs = bdrv_new("");
+
+ ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
+ backing_drv, &local_err);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Could not open '%s': %s",
+ backing_file->value.s,
+ error_get_pretty(local_err));
+ error_free(local_err);
+ local_err = NULL;
+ bdrv_unref(bs);
+ goto out;
+ }
+ bdrv_get_geometry(bs, &size);
+ size *= 512;
+
+ snprintf(buf, sizeof(buf), "%" PRId64, size);
+ set_option_parameter(param, BLOCK_OPT_SIZE, buf);
- ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
- backing_drv, &local_err);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "Could not open '%s': %s",
- backing_file->value.s,
- error_get_pretty(local_err));
- error_free(local_err);
- local_err = NULL;
bdrv_unref(bs);
+ } else {
+ error_setg(errp, "Image creation needs a size parameter");
goto out;
}
- bdrv_get_geometry(bs, &size);
- size *= 512;
-
- snprintf(buf, sizeof(buf), "%" PRId64, size);
- set_option_parameter(param, BLOCK_OPT_SIZE, buf);
+ }
- bdrv_unref(bs);
- } else {
- error_setg(errp, "Image creation needs a size parameter");
- goto out;
+ if (!quiet) {
+ printf("Formatting '%s', fmt=%s ", filename, fmt);
+ print_option_parameters(param);
+ puts("");
}
- }
- if (!quiet) {
- printf("Formatting '%s', fmt=%s ", filename, fmt);
- print_option_parameters(param);
- puts("");
- }
- ret = bdrv_create(drv, filename, param, &local_err);
- if (ret == -EFBIG) {
- /* This is generally a better message than whatever the driver would
- * deliver (especially because of the cluster_size_hint), since that
- * is most probably not much different from "image too large". */
- const char *cluster_size_hint = "";
- if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
- cluster_size_hint = " (try using a larger cluster size)";
+ ret = bdrv_create(drv, filename, param, NULL, &local_err);
+ if (ret == -EFBIG) {
+ /* This is generally a better message than whatever the driver would
+ * deliver (especially because of the cluster_size_hint), since that
+ * is most probably not much different from "image too large". */
+ const char *cluster_size_hint = "";
+ if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
+ cluster_size_hint = " (try using a larger cluster size)";
+ }
+ error_setg(errp, "The image size is too large for file format '%s'"
+ "%s", fmt, cluster_size_hint);
+ error_free(local_err);
+ local_err = NULL;
}
- error_setg(errp, "The image size is too large for file format '%s'"
- "%s", fmt, cluster_size_hint);
- error_free(local_err);
- local_err = NULL;
- }
+ }
out:
free_option_parameters(create_options);
free_option_parameters(param);
-
+ qemu_opts_del(opts);
+ qemu_opts_free(create_opts);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
}
@@ -344,7 +344,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
options++;
}
- ret = bdrv_create_file(filename, options, &local_err);
+ ret = bdrv_create_file(filename, options, NULL, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
@@ -684,7 +684,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
options++;
}
- ret = bdrv_create_file(filename, options, &local_err);
+ ret = bdrv_create_file(filename, options, NULL, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
@@ -1477,7 +1477,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
Error *local_err = NULL;
int ret;
- ret = bdrv_create_file(filename, options, &local_err);
+ ret = bdrv_create_file(filename, options, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
@@ -556,7 +556,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
int ret = 0;
BlockDriverState *bs = NULL;
- ret = bdrv_create_file(filename, NULL, &local_err);
+ ret = bdrv_create_file(filename, NULL, NULL, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
@@ -139,7 +139,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
Error *local_err = NULL;
int ret;
- ret = bdrv_create_file(filename, options, &local_err);
+ ret = bdrv_create_file(filename, options, NULL, &local_err);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
}
@@ -1791,7 +1791,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX :
block_size;
- ret = bdrv_create_file(filename, options, &local_err);
+ ret = bdrv_create_file(filename, options, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto exit;
@@ -1463,7 +1463,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
uint32_t *gd_buf = NULL;
int gd_buf_size;
- ret = bdrv_create_file(filename, NULL, &local_err);
+ ret = bdrv_create_file(filename, NULL, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto exit;
@@ -1801,7 +1801,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
if (!split && !flat) {
desc_offset = 0x200;
} else {
- ret = bdrv_create_file(filename, options, &local_err);
+ ret = bdrv_create_file(filename, options, NULL, &local_err);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create image file");
goto exit;
@@ -2929,7 +2929,7 @@ static int enable_write_target(BDRVVVFATState *s)
set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
- ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, &local_err);
+ ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, NULL, &local_err);
if (ret < 0) {
qerror_report_err(local_err);
error_free(local_err);
@@ -174,9 +174,9 @@ BlockDriver *bdrv_find_format(const char *format_name);
BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
bool readonly);
int bdrv_create(BlockDriver *drv, const char* filename,
- QEMUOptionParameter *options, Error **errp);
+ QEMUOptionParameter *options, QemuOpts *opts, Error **errp);
int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
- Error **errp);
+ QemuOpts *opts, Error **errp);
BlockDriverState *bdrv_new(const char *device_name);
void bdrv_make_anon(BlockDriverState *bs);
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
@@ -105,6 +105,8 @@ struct BlockDriver {
void (*bdrv_rebind)(BlockDriverState *bs);
int (*bdrv_create)(const char *filename, QEMUOptionParameter *options,
Error **errp);
+ int (*bdrv_create2)(const char *filename, QemuOpts *opts,
+ Error **errp);
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
int (*bdrv_make_empty)(BlockDriverState *bs);
/* aio */
@@ -204,7 +206,7 @@ struct BlockDriver {
/* List of options for creating images, terminated by name == NULL */
QEMUOptionParameter *create_options;
-
+ QemuOptsList *create_opts;
/*
* Returns 0 for completed check, -errno for internal errors.
@@ -242,6 +242,7 @@ static int print_block_option_help(const char *filename, const char *fmt)
{
BlockDriver *drv, *proto_drv;
QEMUOptionParameter *create_options = NULL;
+ QemuOptsList *create_opts = NULL;
/* Find driver and parse its options */
drv = bdrv_find_format(fmt);
@@ -256,12 +257,19 @@ static int print_block_option_help(const char *filename, const char *fmt)
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);
+ if (drv->bdrv_create2) {
+ create_opts = qemu_opts_append(create_opts, drv->create_opts);
+ create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
+ qemu_opts_print_help(create_opts);
+ } else {
+ 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);
+ qemu_opts_free(create_opts);
return 0;
}
@@ -317,18 +325,21 @@ fail:
}
static int add_old_style_options(const char *fmt, QEMUOptionParameter *list,
+ QemuOpts *opts,
const char *base_filename,
const char *base_fmt)
{
if (base_filename) {
- if (set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
+ if ((opts && qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) ||
+ (list && set_option_parameter(list, BLOCK_OPT_BACKING_FILE, base_filename))) {
error_report("Backing file not supported for file format '%s'",
fmt);
return -1;
}
}
if (base_fmt) {
- if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+ if ((opts && qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) ||
+ (list && set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt))) {
error_report("Backing file format not supported for file "
"format '%s'", fmt);
return -1;
@@ -1142,7 +1153,8 @@ static int img_convert(int argc, char **argv)
const uint8_t *buf1;
BlockDriverInfo bdi;
QEMUOptionParameter *param = NULL, *create_options = NULL;
- QEMUOptionParameter *out_baseimg_param;
+ QemuOpts *opts = NULL;
+ QemuOptsList *create_opts = NULL;
char *options = NULL;
const char *snapshot_name = NULL;
int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
@@ -1312,67 +1324,125 @@ static int img_convert(int argc, char **argv)
goto out;
}
- create_options = append_option_parameters(create_options,
- drv->create_options);
- create_options = append_option_parameters(create_options,
- proto_drv->create_options);
+ if (drv->bdrv_create2) {
+ const char *out_baseimg_param;
- if (options) {
- param = parse_option_parameters(options, create_options, param);
- if (param == NULL) {
+ create_opts = qemu_opts_append(create_opts, drv->create_opts);
+ create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
+ opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+ if (options && qemu_opts_do_parse(opts, options, NULL)) {
error_report("Invalid options for file format '%s'.", out_fmt);
ret = -1;
goto out;
}
- } else {
- param = parse_option_parameters("", create_options, param);
- }
- set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
- ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);
- if (ret < 0) {
- goto out;
- }
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512);
+ ret = add_old_style_options(out_fmt, NULL, opts, out_baseimg, NULL);
+ if (ret < 0) {
+ 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;
- }
+ /* Get backing file name if -o backing_file was used */
+ out_baseimg_param = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+ if (out_baseimg_param) {
+ out_baseimg = out_baseimg_param;
+ }
- /* Check if compression is supported */
- if (compress) {
- QEMUOptionParameter *encryption =
- get_option_parameter(param, BLOCK_OPT_ENCRYPT);
- QEMUOptionParameter *preallocation =
- get_option_parameter(param, BLOCK_OPT_PREALLOC);
+ /* Check if compression is supported */
+ if (compress) {
+ bool encryption =
+ qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, false);
+ const char *preallocation =
+ qemu_opt_get(opts, BLOCK_OPT_PREALLOC);
- if (!drv->bdrv_write_compressed) {
- error_report("Compression not supported for this file format");
- ret = -1;
- goto out;
+ if (!drv->bdrv_write_compressed) {
+ error_report("Compression not supported for this file format");
+ ret = -1;
+ goto out;
+ }
+
+ if (encryption) {
+ error_report("Compression and encryption not supported at "
+ "the same time");
+ ret = -1;
+ goto out;
+ }
+
+ if (preallocation
+ && strcmp(preallocation, "off"))
+ {
+ error_report("Compression and preallocation not supported at "
+ "the same time");
+ ret = -1;
+ goto out;
+ }
}
- if (encryption && encryption->value.n) {
- error_report("Compression and encryption not supported at "
- "the same time");
- ret = -1;
- goto out;
+ } else {
+ QEMUOptionParameter *out_baseimg_param;
+
+ create_options = append_option_parameters(create_options,
+ drv->create_options);
+ create_options = append_option_parameters(create_options,
+ proto_drv->create_options);
+
+ if (options) {
+ param = parse_option_parameters(options, create_options, param);
+ if (param == NULL) {
+ error_report("Invalid options for file format '%s'.", out_fmt);
+ ret = -1;
+ goto out;
+ }
+ } else {
+ param = parse_option_parameters("", create_options, param);
}
- if (preallocation && preallocation->value.s
- && strcmp(preallocation->value.s, "off"))
- {
- error_report("Compression and preallocation not supported at "
- "the same time");
- ret = -1;
+ set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
+ ret = add_old_style_options(out_fmt, param, NULL, out_baseimg, NULL);
+ if (ret < 0) {
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 */
+ if (compress) {
+ QEMUOptionParameter *encryption =
+ get_option_parameter(param, BLOCK_OPT_ENCRYPT);
+ QEMUOptionParameter *preallocation =
+ get_option_parameter(param, BLOCK_OPT_PREALLOC);
+
+ if (!drv->bdrv_write_compressed) {
+ error_report("Compression not supported for this file format");
+ ret = -1;
+ goto out;
+ }
+
+ if (encryption && encryption->value.n) {
+ error_report("Compression and encryption not supported at "
+ "the same time");
+ ret = -1;
+ goto out;
+ }
+
+ if (preallocation && preallocation->value.s
+ && strcmp(preallocation->value.s, "off"))
+ {
+ error_report("Compression and preallocation not supported at "
+ "the same time");
+ ret = -1;
+ goto out;
+ }
+ }
}
if (!skip_create) {
/* Create the new image */
- ret = bdrv_create(drv, out_filename, param, &local_err);
+ ret = bdrv_create(drv, out_filename, param, opts, &local_err);
if (ret < 0) {
error_report("%s: error while converting %s: %s",
out_filename, out_fmt, error_get_pretty(local_err));
@@ -1638,6 +1708,8 @@ out:
qemu_progress_end();
free_option_parameters(create_options);
free_option_parameters(param);
+ qemu_opts_free(create_opts);
+ qemu_opts_del(opts);
qemu_vfree(buf);
if (sn_opts) {
qemu_opts_del(sn_opts);