From b25c9dff3599892a16f824b5df643e0fc1acbfc1 Mon Sep 17 00:00:00 2001 From: Stefan Weil Date: Tue, 29 Apr 2014 08:21:16 +0200 Subject: [PATCH 01/39] configure: Enable dead code (lzo, snappy, quorum) Those options were not enabled by default, even when the build environment would have supported them, so the corresponding code was not compiled in normal test builds like on build bots. [Building quorum by default "broke" qemu-iotests ./check 081. It turns out the 081.out master output was just bitrotted. Fix this by updating the error message. --Stefan] Signed-off-by: Stefan Weil Reviewed-by: Qiao Nuohan Reviewed-by: Benoit Canet Reviewed-by: Stefan Hajnoczi Signed-off-by: Stefan Hajnoczi --- configure | 39 +++++++++++++++++++++++--------------- tests/qemu-iotests/081.out | 2 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/configure b/configure index dfbe75ee75..57d3ad89d7 100755 --- a/configure +++ b/configure @@ -311,8 +311,8 @@ libusb="" usb_redir="" glx="" zlib="yes" -lzo="no" -snappy="no" +lzo="" +snappy="" guest_agent="" guest_agent_with_vss="no" vss_win32_sdk="" @@ -333,7 +333,7 @@ vte="" tpm="no" libssh2="" vhdx="" -quorum="no" +quorum="" # parse CC options first for opt do @@ -1050,8 +1050,12 @@ for opt do ;; --disable-zlib-test) zlib="no" ;; + --disable-lzo) lzo="no" + ;; --enable-lzo) lzo="yes" ;; + --disable-snappy) snappy="no" + ;; --enable-snappy) snappy="yes" ;; --enable-guest-agent) guest_agent="yes" @@ -1749,13 +1753,14 @@ if test "$lzo" != "no" ; then int main(void) { lzo_version(); return 0; } EOF if compile_prog "" "-llzo2" ; then - : + libs_softmmu="$libs_softmmu -llzo2" + lzo="yes" else - error_exit "lzo check failed" \ - "Make sure to have the lzo libs and headers installed." + if test "$lzo" = "yes"; then + feature_not_found "liblzo2" "Install liblzo2 devel" + fi + lzo="no" fi - - libs_softmmu="$libs_softmmu -llzo2" fi ########################################## @@ -1767,13 +1772,14 @@ if test "$snappy" != "no" ; then int main(void) { snappy_max_compressed_length(4096); return 0; } EOF if compile_prog "" "-lsnappy" ; then - : + libs_softmmu="$libs_softmmu -lsnappy" + snappy="yes" else - error_exit "snappy check failed" \ - "Make sure to have the snappy libs and headers installed." + if test "$snappy" = "yes"; then + feature_not_found "libsnappy" "Install libsnappy devel" + fi + snappy="no" fi - - libs_softmmu="$libs_softmmu -lsnappy" fi ########################################## @@ -2219,9 +2225,12 @@ if compile_prog "$quorum_tls_cflags" "$quorum_tls_libs" ; then libs_softmmu="$quorum_tls_libs $libs_softmmu" libs_tools="$quorum_tls_libs $libs_softmmu" QEMU_CFLAGS="$QEMU_CFLAGS $quorum_tls_cflags" + quorum="yes" else - echo "gnutls > 2.10.0 required to compile Quorum" - exit 1 + if test "$quorum" = "yes"; then + feature_not_found "gnutls" "gnutls > 2.10.0 required to compile Quorum" + fi + quorum="no" fi fi diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out index 84aeb0c730..2241cec148 100644 --- a/tests/qemu-iotests/081.out +++ b/tests/qemu-iotests/081.out @@ -45,5 +45,5 @@ wrote 10485760/10485760 bytes at offset 0 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) == checking that quorum is broken == -qemu-io: can't open device (null): Could not read image for determining its format: Input/output error +qemu-io: can't open: Could not read image for determining its format: Input/output error *** done From f7047c2daf760385edf83df10be4259bea190e75 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 6 Jun 2014 18:25:12 +0200 Subject: [PATCH 02/39] block: Drop superfluous conditionals around g_free() Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Stefan Hajnoczi --- block/curl.c | 9 +++------ block/iscsi.c | 4 +--- hw/block/onenand.c | 4 +--- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/block/curl.c b/block/curl.c index 8c84141ced..79ff2f1e41 100644 --- a/block/curl.c +++ b/block/curl.c @@ -440,10 +440,8 @@ static void curl_detach_aio_context(BlockDriverState *bs) curl_easy_cleanup(s->states[i].curl); s->states[i].curl = NULL; } - if (s->states[i].orig_buf) { - g_free(s->states[i].orig_buf); - s->states[i].orig_buf = NULL; - } + g_free(s->states[i].orig_buf); + s->states[i].orig_buf = NULL; } if (s->multi) { curl_multi_cleanup(s->multi); @@ -638,8 +636,7 @@ static void curl_readv_bh_cb(void *p) acb->end = (acb->nb_sectors * SECTOR_SIZE); state->buf_off = 0; - if (state->orig_buf) - g_free(state->orig_buf); + g_free(state->orig_buf); state->buf_start = start; state->buf_len = acb->end + s->readahead_size; end = MIN(start + state->buf_len, s->len) - 1; diff --git a/block/iscsi.c b/block/iscsi.c index 877b877cf2..38bfdb61a2 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1434,9 +1434,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags, out: qemu_opts_del(opts); - if (initiator_name != NULL) { - g_free(initiator_name); - } + g_free(initiator_name); if (iscsi_url != NULL) { iscsi_destroy_url(iscsi_url); } diff --git a/hw/block/onenand.c b/hw/block/onenand.c index 60d5311d04..5388122eb8 100644 --- a/hw/block/onenand.c +++ b/hw/block/onenand.c @@ -335,9 +335,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn, dp, 1) < 0; } } - if (dp) { - g_free(dp); - } + g_free(dp); } return result; } From bcf831585751508bddf4ef6823f2295d850509b9 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 6 Jun 2014 15:21:48 +0200 Subject: [PATCH 03/39] blockdev: Move 'serial' option to drive_init() It is not available with blockdev-add. Signed-off-by: Kevin Wolf Signed-off-by: Stefan Hajnoczi --- blockdev.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/blockdev.c b/blockdev.c index 4cbcc56b5e..0505f9d846 100644 --- a/blockdev.c +++ b/blockdev.c @@ -329,7 +329,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, Error **errp) { const char *buf; - const char *serial; int ro = 0; int bdrv_flags = 0; int on_read_error, on_write_error; @@ -371,8 +370,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, ro = qemu_opt_get_bool(opts, "read-only", 0); copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", false); - serial = qemu_opt_get(opts, "serial"); - if ((buf = qemu_opt_get(opts, "discard")) != NULL) { if (bdrv_parse_discard_flags(buf, &bdrv_flags) != 0) { error_setg(errp, "invalid discard option"); @@ -501,9 +498,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, dinfo->bdrv->read_only = ro; dinfo->bdrv->detect_zeroes = detect_zeroes; dinfo->refcount = 1; - if (serial != NULL) { - dinfo->serial = g_strdup(serial); - } QTAILQ_INSERT_TAIL(&drives, dinfo, next); bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error); @@ -629,6 +623,10 @@ QemuOptsList qemu_legacy_drive_opts = { .name = "addr", .type = QEMU_OPT_STRING, .help = "pci address (virtio only)", + },{ + .name = "serial", + .type = QEMU_OPT_STRING, + .help = "disk serial number", },{ .name = "file", .type = QEMU_OPT_STRING, @@ -672,6 +670,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type) const char *werror, *rerror; bool read_only = false; bool copy_on_read; + const char *serial; const char *filename; Error *local_err = NULL; @@ -875,6 +874,9 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type) goto fail; } + /* Serial number */ + serial = qemu_opt_get(legacy_opts, "serial"); + /* no id supplied -> create one */ if (qemu_opts_id(all_opts) == NULL) { char *new_id; @@ -965,6 +967,8 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type) dinfo->unit = unit_id; dinfo->devaddr = devaddr; + dinfo->serial = g_strdup(serial); + switch(type) { case IF_IDE: case IF_SCSI: @@ -2437,10 +2441,6 @@ QemuOptsList qemu_common_drive_opts = { .name = "format", .type = QEMU_OPT_STRING, .help = "disk format (raw, qcow2, ...)", - },{ - .name = "serial", - .type = QEMU_OPT_STRING, - .help = "disk serial number", },{ .name = "rerror", .type = QEMU_OPT_STRING, From 60e19e06a4a28935c94e39d40c80193759af88ce Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 6 Jun 2014 14:50:58 +0200 Subject: [PATCH 04/39] blockdev: Rename drive_init(), drive_uninit() to drive_new(), drive_del() "Init" and "uninit" suggest the functions don't allocate / free storage. But they do. Signed-off-by: Markus Armbruster Reviewed-by: Benoit Canet Signed-off-by: Stefan Hajnoczi --- blockdev.c | 14 +++++++------- device-hotplug.c | 2 +- hw/usb/dev-storage.c | 2 +- include/sysemu/blockdev.h | 4 ++-- vl.c | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/blockdev.c b/blockdev.c index 0505f9d846..0ed03b770f 100644 --- a/blockdev.c +++ b/blockdev.c @@ -213,7 +213,7 @@ static void bdrv_format_print(void *opaque, const char *name) error_printf(" %s", name); } -static void drive_uninit(DriveInfo *dinfo) +static void drive_del(DriveInfo *dinfo) { if (dinfo->opts) { qemu_opts_del(dinfo->opts); @@ -230,7 +230,7 @@ void drive_put_ref(DriveInfo *dinfo) { assert(dinfo->refcount); if (--dinfo->refcount == 0) { - drive_uninit(dinfo); + drive_del(dinfo); } } @@ -656,7 +656,7 @@ QemuOptsList qemu_legacy_drive_opts = { }, }; -DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type) +DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) { const char *value; DriveInfo *dinfo = NULL; @@ -1801,7 +1801,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT); } else { - drive_uninit(drive_get_by_blockdev(bs)); + drive_del(drive_get_by_blockdev(bs)); } return 0; @@ -2344,9 +2344,9 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) goto fail; } - /* TODO Sort it out in raw-posix and drive_init: Reject aio=native with + /* TODO Sort it out in raw-posix and drive_new(): Reject aio=native with * cache.direct=false instead of silently switching to aio=threads, except - * if called from drive_init. + * when called from drive_new(). * * For now, simply forbidding the combination for all drivers will do. */ if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) { @@ -2378,7 +2378,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) } if (bdrv_key_required(dinfo->bdrv)) { - drive_uninit(dinfo); + drive_del(dinfo); error_setg(errp, "blockdev-add doesn't support encrypted devices"); goto fail; } diff --git a/device-hotplug.c b/device-hotplug.c index eecb08e2b1..fc09d10fdb 100644 --- a/device-hotplug.c +++ b/device-hotplug.c @@ -40,7 +40,7 @@ DriveInfo *add_init_drive(const char *optstr) return NULL; mc = MACHINE_GET_CLASS(current_machine); - dinfo = drive_init(opts, mc->block_default_type); + dinfo = drive_new(opts, mc->block_default_type); if (!dinfo) { qemu_opts_del(opts); return NULL; diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index e919100637..ae4efcbd2d 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -691,7 +691,7 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename) qemu_opt_set(opts, "if", "none"); /* create host drive */ - dinfo = drive_init(opts, 0); + dinfo = drive_new(opts, 0); if (!dinfo) { qemu_opts_del(opts); return NULL; diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index 134712b500..0fdbd689c1 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -37,7 +37,7 @@ struct DriveInfo { int bus; int unit; int auto_del; /* see blockdev_mark_auto_del() */ - bool enable_auto_del; /* Only for legacy drive_init() */ + bool enable_auto_del; /* Only for legacy drive_new() */ int media_cd; int cyls, heads, secs, trans; QemuOpts *opts; @@ -57,7 +57,7 @@ DriveInfo *drive_get_by_blockdev(BlockDriverState *bs); QemuOpts *drive_def(const char *optstr); QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file, const char *optstr); -DriveInfo *drive_init(QemuOpts *arg, BlockInterfaceType block_default_type); +DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type); /* device-hotplug */ diff --git a/vl.c b/vl.c index ac0e3d7e83..be69c7f346 100644 --- a/vl.c +++ b/vl.c @@ -1074,7 +1074,7 @@ static int drive_init_func(QemuOpts *opts, void *opaque) { BlockInterfaceType *block_default_type = opaque; - return drive_init(opts, *block_default_type) == NULL; + return drive_new(opts, *block_default_type) == NULL; } static int drive_enable_snapshot(QemuOpts *opts, void *opaque) @@ -1098,7 +1098,7 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type, if (snapshot) { drive_enable_snapshot(opts, NULL); } - if (!drive_init(opts, type)) { + if (!drive_new(opts, type)) { exit(1); } } From ae60e8e3783a66463d0736f3a48da9a66fd5cbd3 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 6 Jun 2014 14:50:59 +0200 Subject: [PATCH 05/39] blockdev: Remove unused DriveInfo reference count It's always one since commit fa510eb dropped the last drive_get_ref(). Signed-off-by: Markus Armbruster Reviewed-by: Benoit Canet Signed-off-by: Stefan Hajnoczi --- blockdev.c | 18 ++---------------- device-hotplug.c | 2 +- hw/ide/piix.c | 2 +- include/sysemu/blockdev.h | 4 +--- 4 files changed, 5 insertions(+), 21 deletions(-) diff --git a/blockdev.c b/blockdev.c index 0ed03b770f..9b0f8ac45e 100644 --- a/blockdev.c +++ b/blockdev.c @@ -106,7 +106,7 @@ void blockdev_auto_del(BlockDriverState *bs) DriveInfo *dinfo = drive_get_by_blockdev(bs); if (dinfo && dinfo->auto_del) { - drive_put_ref(dinfo); + drive_del(dinfo); } } @@ -213,7 +213,7 @@ static void bdrv_format_print(void *opaque, const char *name) error_printf(" %s", name); } -static void drive_del(DriveInfo *dinfo) +void drive_del(DriveInfo *dinfo) { if (dinfo->opts) { qemu_opts_del(dinfo->opts); @@ -226,19 +226,6 @@ static void drive_del(DriveInfo *dinfo) g_free(dinfo); } -void drive_put_ref(DriveInfo *dinfo) -{ - assert(dinfo->refcount); - if (--dinfo->refcount == 0) { - drive_del(dinfo); - } -} - -void drive_get_ref(DriveInfo *dinfo) -{ - dinfo->refcount++; -} - typedef struct { QEMUBH *bh; BlockDriverState *bs; @@ -497,7 +484,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0; dinfo->bdrv->read_only = ro; dinfo->bdrv->detect_zeroes = detect_zeroes; - dinfo->refcount = 1; QTAILQ_INSERT_TAIL(&drives, dinfo, next); bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error); diff --git a/device-hotplug.c b/device-hotplug.c index fc09d10fdb..e6a1ffb9fa 100644 --- a/device-hotplug.c +++ b/device-hotplug.c @@ -76,6 +76,6 @@ void drive_hot_add(Monitor *mon, const QDict *qdict) err: if (dinfo) { - drive_put_ref(dinfo); + drive_del(dinfo); } } diff --git a/hw/ide/piix.c b/hw/ide/piix.c index 40757eb001..8651726f52 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -184,7 +184,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) } bdrv_close(di->bdrv); pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; - drive_put_ref(di); + drive_del(di); } } qdev_reset_all(DEVICE(dev)); diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index 0fdbd689c1..23a5d10c68 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -43,21 +43,19 @@ struct DriveInfo { QemuOpts *opts; char *serial; QTAILQ_ENTRY(DriveInfo) next; - int refcount; }; DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); DriveInfo *drive_get_by_index(BlockInterfaceType type, int index); int drive_get_max_bus(BlockInterfaceType type); DriveInfo *drive_get_next(BlockInterfaceType type); -void drive_get_ref(DriveInfo *dinfo); -void drive_put_ref(DriveInfo *dinfo); DriveInfo *drive_get_by_blockdev(BlockDriverState *bs); QemuOpts *drive_def(const char *optstr); QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file, const char *optstr); DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type); +void drive_del(DriveInfo *dinfo); /* device-hotplug */ From a2c0fe2fd26e3e10753660019da9366f7b19c286 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Tue, 10 Jun 2014 09:42:47 +0200 Subject: [PATCH 06/39] block/nfs: fix potential segfault on early callback it will happen in the future that the callback of a libnfs call directly invokes the callback. In this case we end up in a segfault because the NFSRPC is gone when we the BH is scheduled. Signed-off-by: Peter Lieven Signed-off-by: Stefan Hajnoczi --- block/nfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/block/nfs.c b/block/nfs.c index bd9177f3ae..e282f8de37 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -95,6 +95,7 @@ static void nfs_co_init_task(NFSClient *client, NFSRPC *task) static void nfs_co_generic_bh_cb(void *opaque) { NFSRPC *task = opaque; + task->complete = 1; qemu_bh_delete(task->bh); qemu_coroutine_enter(task->co, NULL); } @@ -104,7 +105,6 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, void *private_data) { NFSRPC *task = private_data; - task->complete = 1; task->ret = ret; if (task->ret > 0 && task->iov) { if (task->ret <= task->iov->size) { @@ -123,6 +123,8 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, task->bh = aio_bh_new(task->client->aio_context, nfs_co_generic_bh_cb, task); qemu_bh_schedule(task->bh); + } else { + task->complete = 1; } } From 5e89db7641fdf61f066119e4d8864ad7be1e32f0 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:40 +0800 Subject: [PATCH 07/39] QemuOpts: move find_desc_by_name ahead for later calling Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- util/qemu-option.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/util/qemu-option.c b/util/qemu-option.c index 324e4c59f7..c188c5ce6c 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -173,6 +173,20 @@ static void parse_option_number(const char *name, const char *value, } } +static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc, + const char *name) +{ + int i; + + for (i = 0; desc[i].name != NULL; i++) { + if (strcmp(desc[i].name, name) == 0) { + return &desc[i]; + } + } + + return NULL; +} + void parse_option_size(const char *name, const char *value, uint64_t *ret, Error **errp) { @@ -637,20 +651,6 @@ static bool opts_accepts_any(const QemuOpts *opts) return opts->list->desc[0].name == NULL; } -static const QemuOptDesc *find_desc_by_name(const QemuOptDesc *desc, - const char *name) -{ - int i; - - for (i = 0; desc[i].name != NULL; i++) { - if (strcmp(desc[i].name, name) == 0) { - return &desc[i]; - } - } - - return NULL; -} - int qemu_opt_unset(QemuOpts *opts, const char *name) { QemuOpt *opt = qemu_opt_find(opts, name); From e67905426bf3cf811d31c87789c1c7e986849d66 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:41 +0800 Subject: [PATCH 08/39] QemuOpts: repurpose qemu_opts_print to replace print_option_parameters Currently this function is not used anywhere. In later patches, it will replace print_option_parameters. To avoid print info changes, change qemu_opts_print from fprintf stderr to printf, and remove last printf. Signed-off-by: Chunyan Liu Reviewed-by: Eric Blake Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 2 +- util/qemu-option.c | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index 8c0ac3485e..1077b69851 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -156,7 +156,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict); void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp); typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque); -int qemu_opts_print(QemuOpts *opts, void *dummy); +void qemu_opts_print(QemuOpts *opts); int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, int abort_on_failure); diff --git a/util/qemu-option.c b/util/qemu-option.c index c188c5ce6c..2c467918be 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -895,17 +895,15 @@ void qemu_opts_del(QemuOpts *opts) g_free(opts); } -int qemu_opts_print(QemuOpts *opts, void *dummy) +void qemu_opts_print(QemuOpts *opts) { QemuOpt *opt; - fprintf(stderr, "%s: %s:", opts->list->name, - opts->id ? opts->id : ""); + printf("%s: %s:", opts->list->name, + opts->id ? opts->id : ""); QTAILQ_FOREACH(opt, &opts->head, next) { - fprintf(stderr, " %s=\"%s\"", opt->name, opt->str); + printf(" %s=\"%s\"", opt->name, opt->str); } - fprintf(stderr, "\n"); - return 0; } static int opts_do_parse(QemuOpts *opts, const char *params, From 09722032e15669e653991923613761602c745fa0 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:42 +0800 Subject: [PATCH 09/39] QemuOpts: add def_value_str to QemuOptDesc Add def_value_str (default value) to QemuOptDesc, to replace function of the default value in QEMUOptionParameter. Improve qemu_opts_get_* functions: if find opt, return opt->str; otherwise, if desc->def_value_str is set, return desc->def_value_str; otherwise, return input defval. Improve qemu_opts_print: if option is set, print opt->str; otherwise, if desc->def_value_str is set, print it. Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Reviewed-by: Eric Blake Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 1 + util/qemu-option.c | 56 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index 1077b69851..c3b0a917d9 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -99,6 +99,7 @@ typedef struct QemuOptDesc { const char *name; enum QemuOptType type; const char *help; + const char *def_value_str; } QemuOptDesc; struct QemuOptsList { diff --git a/util/qemu-option.c b/util/qemu-option.c index 2c467918be..5af39a2f18 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -570,6 +570,13 @@ static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) const char *qemu_opt_get(QemuOpts *opts, const char *name) { QemuOpt *opt = qemu_opt_find(opts, name); + + if (!opt) { + const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); + if (desc && desc->def_value_str) { + return desc->def_value_str; + } + } return opt ? opt->str : NULL; } @@ -589,8 +596,13 @@ bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval) { QemuOpt *opt = qemu_opt_find(opts, name); - if (opt == NULL) + if (opt == NULL) { + const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); + if (desc && desc->def_value_str) { + parse_option_bool(name, desc->def_value_str, &defval, &error_abort); + } return defval; + } assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL); return opt->value.boolean; } @@ -599,8 +611,14 @@ uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval) { QemuOpt *opt = qemu_opt_find(opts, name); - if (opt == NULL) + if (opt == NULL) { + const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); + if (desc && desc->def_value_str) { + parse_option_number(name, desc->def_value_str, &defval, + &error_abort); + } return defval; + } assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER); return opt->value.uint; } @@ -609,8 +627,13 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval) { QemuOpt *opt = qemu_opt_find(opts, name); - if (opt == NULL) + if (opt == NULL) { + const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); + if (desc && desc->def_value_str) { + parse_option_size(name, desc->def_value_str, &defval, &error_abort); + } return defval; + } assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE); return opt->value.uint; } @@ -898,11 +921,30 @@ void qemu_opts_del(QemuOpts *opts) void qemu_opts_print(QemuOpts *opts) { QemuOpt *opt; + QemuOptDesc *desc = opts->list->desc; - printf("%s: %s:", opts->list->name, - opts->id ? opts->id : ""); - QTAILQ_FOREACH(opt, &opts->head, next) { - printf(" %s=\"%s\"", opt->name, opt->str); + if (desc[0].name == NULL) { + QTAILQ_FOREACH(opt, &opts->head, next) { + printf("%s=\"%s\" ", opt->name, opt->str); + } + return; + } + for (; desc && desc->name; desc++) { + const char *value; + QemuOpt *opt = qemu_opt_find(opts, desc->name); + + value = opt ? opt->str : desc->def_value_str; + if (!value) { + continue; + } + if (desc->type == QEMU_OPT_STRING) { + printf("%s='%s' ", desc->name, value); + } else if ((desc->type == QEMU_OPT_SIZE || + desc->type == QEMU_OPT_NUMBER) && opt) { + printf("%s=%" PRId64 " ", desc->name, opt->value.uint); + } else { + printf("%s=%s ", desc->name, value); + } } } From e36af94f868fe5b897c4903126e11fdf25fa4739 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:43 +0800 Subject: [PATCH 10/39] qapi: output def_value_str when query command line options Change qapi interfaces to output the newly added def_value_str when querying command line options. Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Leandro Dorileo Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- qapi-schema.json | 5 ++++- qmp-commands.hx | 2 ++ util/qemu-config.c | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/qapi-schema.json b/qapi-schema.json index 14b498b442..dc2abe479e 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2855,12 +2855,15 @@ # # @help: #optional human readable text string, not suitable for parsing. # +# @default: #optional default value string (since 2.1) +# # Since 1.5 ## { 'type': 'CommandLineParameterInfo', 'data': { 'name': 'str', 'type': 'CommandLineParameterType', - '*help': 'str' } } + '*help': 'str', + '*default': 'str' } } ## # @CommandLineOptionInfo: diff --git a/qmp-commands.hx b/qmp-commands.hx index d8aa4edabe..d6bb0f483f 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2898,6 +2898,8 @@ Each array entry contains the following: or 'size') - "help": human readable description of the parameter (json-string, optional) + - "default": default value string for the parameter + (json-string, optional) Example: diff --git a/util/qemu-config.c b/util/qemu-config.c index f4e4f38749..ba375c0148 100644 --- a/util/qemu-config.c +++ b/util/qemu-config.c @@ -82,6 +82,10 @@ static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc) info->has_help = true; info->help = g_strdup(desc[i].help); } + if (desc[i].def_value_str) { + info->has_q_default = true; + info->q_default = g_strdup(desc[i].def_value_str); + } entry = g_malloc0(sizeof(*entry)); entry->value = info; From dc8622f2bf9174cd42932ad86bcc98c6f7c98832 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:44 +0800 Subject: [PATCH 11/39] QemuOpts: change opt->name|str from (const char *) to (char *) qemu_opt_del() already assumes that all QemuOpt instances contain malloc'd name and value; but it had to cast away const because opts_start_struct() was doing its own thing and using static storage instead. By using the correct type and malloced strings everywhere, the usage of this struct becomes clearer. Reviewed-by: Eric Blake Reviewed-by: Leandro Dorileo Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- include/qemu/option_int.h | 4 ++-- qapi/opts-visitor.c | 10 +++++++--- util/qemu-option.c | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/include/qemu/option_int.h b/include/qemu/option_int.h index 8212fa4a48..6432c1a8c9 100644 --- a/include/qemu/option_int.h +++ b/include/qemu/option_int.h @@ -30,8 +30,8 @@ #include "qemu/error-report.h" struct QemuOpt { - const char *name; - const char *str; + char *name; + char *str; const QemuOptDesc *desc; union { diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index 16382e7a65..f2ad6d729a 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -143,8 +143,8 @@ opts_start_struct(Visitor *v, void **obj, const char *kind, if (ov->opts_root->id != NULL) { ov->fake_id_opt = g_malloc0(sizeof *ov->fake_id_opt); - ov->fake_id_opt->name = "id"; - ov->fake_id_opt->str = ov->opts_root->id; + ov->fake_id_opt->name = g_strdup("id"); + ov->fake_id_opt->str = g_strdup(ov->opts_root->id); opts_visitor_insert(ov->unprocessed_opts, ov->fake_id_opt); } } @@ -177,7 +177,11 @@ opts_end_struct(Visitor *v, Error **errp) } g_hash_table_destroy(ov->unprocessed_opts); ov->unprocessed_opts = NULL; - g_free(ov->fake_id_opt); + if (ov->fake_id_opt) { + g_free(ov->fake_id_opt->name); + g_free(ov->fake_id_opt->str); + g_free(ov->fake_id_opt); + } ov->fake_id_opt = NULL; } diff --git a/util/qemu-option.c b/util/qemu-option.c index 5af39a2f18..d4fd7b5f35 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -664,8 +664,8 @@ static void qemu_opt_parse(QemuOpt *opt, Error **errp) static void qemu_opt_del(QemuOpt *opt) { QTAILQ_REMOVE(&opt->opts->head, opt, next); - g_free((/* !const */ char*)opt->name); - g_free((/* !const */ char*)opt->str); + g_free(opt->name); + g_free(opt->str); g_free(opt); } From fc345512c59da62eb2dde3f0a51137a2f848c589 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:45 +0800 Subject: [PATCH 12/39] QemuOpts: move qemu_opt_del ahead for later calling In later patch, qemu_opt_get_del functions will be added, they will first get the option value, then call qemu_opt_del to remove the option from opt list. To prepare for that purpose, move qemu_opt_del ahead first. Reviewed-by: Eric Blake Reviewed-by: Leandro Dorileo Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- util/qemu-option.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/util/qemu-option.c b/util/qemu-option.c index d4fd7b5f35..71244836c3 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -567,6 +567,14 @@ static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) return NULL; } +static void qemu_opt_del(QemuOpt *opt) +{ + QTAILQ_REMOVE(&opt->opts->head, opt, next); + g_free(opt->name); + g_free(opt->str); + g_free(opt); +} + const char *qemu_opt_get(QemuOpts *opts, const char *name) { QemuOpt *opt = qemu_opt_find(opts, name); @@ -661,14 +669,6 @@ static void qemu_opt_parse(QemuOpt *opt, Error **errp) } } -static void qemu_opt_del(QemuOpt *opt) -{ - QTAILQ_REMOVE(&opt->opts->head, opt, next); - g_free(opt->name); - g_free(opt->str); - g_free(opt); -} - static bool opts_accepts_any(const QemuOpts *opts) { return opts->list->desc[0].name == NULL; From 782730b0bcde44eef8eb5b2d4200eff318ec77cd Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:46 +0800 Subject: [PATCH 13/39] QemuOpts: add qemu_opt_get_*_del functions for replace work Add qemu_opt_get_del, qemu_opt_get_bool_del, qemu_opt_get_number_del and qemu_opt_get_size_del to replace the same handling of QEMUOptionParameter (get and delete). Several drivers are coded to parse a known subset of options, then remove them from the list before handing all remaining options to a second driver for further option processing. get_*_del makes it easier to retrieve a known option (or its default) and remove it from the list all in one action. Share common helper function: For qemu_opt_get_bool/size/number, they and their get_*_del counterpart could share most of the code except whether or not deleting the opt from option list, so generate common helper functions. For qemu_opt_get and qemu_opt_get_del, keep code duplication, since 1. qemu_opt_get_del returns malloc'd memory while qemu_opt_get returns in-place memory 2. qemu_opt_get_del returns (char *), qemu_opt_get returns (const char *), and could not change to (char *), since in one case, it will return desc->def_value_str, which is (const char *). Reviewed-by: Eric Blake Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 6 ++ util/qemu-option.c | 129 +++++++++++++++++++++++++++++++++++------- 2 files changed, 116 insertions(+), 19 deletions(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index c3b0a917d9..6653e4300b 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -111,6 +111,7 @@ struct QemuOptsList { }; const char *qemu_opt_get(QemuOpts *opts, const char *name); +char *qemu_opt_get_del(QemuOpts *opts, const char *name); /** * qemu_opt_has_help_opt: * @opts: options to search for a help request @@ -126,6 +127,11 @@ bool qemu_opt_has_help_opt(QemuOpts *opts); bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval); uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval); uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval); +bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval); +uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name, + uint64_t defval); +uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name, + uint64_t defval); int qemu_opt_unset(QemuOpts *opts, const char *name); int qemu_opt_set(QemuOpts *opts, const char *name, const char *value); void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value, diff --git a/util/qemu-option.c b/util/qemu-option.c index 71244836c3..a7330c6321 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -575,6 +575,20 @@ static void qemu_opt_del(QemuOpt *opt) g_free(opt); } +/* qemu_opt_set allows many settings for the same option. + * This function deletes all settings for an option. + */ +static void qemu_opt_del_all(QemuOpts *opts, const char *name) +{ + QemuOpt *opt, *next_opt; + + QTAILQ_FOREACH_SAFE(opt, &opts->head, next, next_opt) { + if (!strcmp(opt->name, name)) { + qemu_opt_del(opt); + } + } +} + const char *qemu_opt_get(QemuOpts *opts, const char *name) { QemuOpt *opt = qemu_opt_find(opts, name); @@ -588,6 +602,34 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name) return opt ? opt->str : NULL; } +/* Get a known option (or its default) and remove it from the list + * all in one action. Return a malloced string of the option value. + * Result must be freed by caller with g_free(). + */ +char *qemu_opt_get_del(QemuOpts *opts, const char *name) +{ + QemuOpt *opt; + const QemuOptDesc *desc; + char *str = NULL; + + if (opts == NULL) { + return NULL; + } + + opt = qemu_opt_find(opts, name); + if (!opt) { + desc = find_desc_by_name(opts->list->desc, name); + if (desc && desc->def_value_str) { + str = g_strdup(desc->def_value_str); + } + return str; + } + str = opt->str; + opt->str = NULL; + qemu_opt_del_all(opts, name); + return str; +} + bool qemu_opt_has_help_opt(QemuOpts *opts) { QemuOpt *opt; @@ -600,50 +642,99 @@ bool qemu_opt_has_help_opt(QemuOpts *opts) return false; } -bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval) +static bool qemu_opt_get_bool_helper(QemuOpts *opts, const char *name, + bool defval, bool del) { QemuOpt *opt = qemu_opt_find(opts, name); + bool ret = defval; if (opt == NULL) { const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); if (desc && desc->def_value_str) { - parse_option_bool(name, desc->def_value_str, &defval, &error_abort); + parse_option_bool(name, desc->def_value_str, &ret, &error_abort); } - return defval; + return ret; } assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL); - return opt->value.boolean; + ret = opt->value.boolean; + if (del) { + qemu_opt_del_all(opts, name); + } + return ret; +} + +bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval) +{ + return qemu_opt_get_bool_helper(opts, name, defval, false); +} + +bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval) +{ + return qemu_opt_get_bool_helper(opts, name, defval, true); +} + +static uint64_t qemu_opt_get_number_helper(QemuOpts *opts, const char *name, + uint64_t defval, bool del) +{ + QemuOpt *opt = qemu_opt_find(opts, name); + uint64_t ret = defval; + + if (opt == NULL) { + const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); + if (desc && desc->def_value_str) { + parse_option_number(name, desc->def_value_str, &ret, &error_abort); + } + return ret; + } + assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER); + ret = opt->value.uint; + if (del) { + qemu_opt_del_all(opts, name); + } + return ret; } uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval) +{ + return qemu_opt_get_number_helper(opts, name, defval, false); +} + +uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name, + uint64_t defval) +{ + return qemu_opt_get_number_helper(opts, name, defval, true); +} + +static uint64_t qemu_opt_get_size_helper(QemuOpts *opts, const char *name, + uint64_t defval, bool del) { QemuOpt *opt = qemu_opt_find(opts, name); + uint64_t ret = defval; if (opt == NULL) { const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); if (desc && desc->def_value_str) { - parse_option_number(name, desc->def_value_str, &defval, - &error_abort); + parse_option_size(name, desc->def_value_str, &ret, &error_abort); } - return defval; + return ret; } - assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER); - return opt->value.uint; + assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE); + ret = opt->value.uint; + if (del) { + qemu_opt_del_all(opts, name); + } + return ret; } uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval) { - QemuOpt *opt = qemu_opt_find(opts, name); + return qemu_opt_get_size_helper(opts, name, defval, false); +} - if (opt == NULL) { - const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); - if (desc && desc->def_value_str) { - parse_option_size(name, desc->def_value_str, &defval, &error_abort); - } - return defval; - } - assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE); - return opt->value.uint; +uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name, + uint64_t defval) +{ + return qemu_opt_get_size_helper(opts, name, defval, true); } static void qemu_opt_parse(QemuOpt *opt, Error **errp) From 504189a96fdee5916073858f0e60f33e0275454a Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:47 +0800 Subject: [PATCH 14/39] QemuOpts: add qemu_opts_print_help to replace print_option_help print_option_help takes QEMUOptionParameter as parameter, add qemu_opts_print_help to take QemuOptsList as parameter for later replace work. Reviewed-by: Eric Blake Reviewed-by: Leandro Dorileo Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 1 + util/qemu-option.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/qemu/option.h b/include/qemu/option.h index 6653e4300b..fbf5dc2275 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -166,5 +166,6 @@ typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque); void qemu_opts_print(QemuOpts *opts); int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, int abort_on_failure); +void qemu_opts_print_help(QemuOptsList *list); #endif diff --git a/util/qemu-option.c b/util/qemu-option.c index a7330c6321..cd03eb43c4 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -553,6 +553,19 @@ void print_option_help(QEMUOptionParameter *list) } } +void qemu_opts_print_help(QemuOptsList *list) +{ + QemuOptDesc *desc; + + assert(list); + desc = list->desc; + printf("Supported options:\n"); + while (desc && desc->name) { + printf("%-16s %s\n", desc->name, + desc->help ? desc->help : "No description available"); + desc++; + } +} /* ------------------------------------------------------------------ */ static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) From 8559e45e51edd22dd48d54cce8b0521e6339f3e9 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:48 +0800 Subject: [PATCH 15/39] QemuOpts: add conversion between QEMUOptionParameter to QemuOpts Add two temp conversion functions between QEMUOptionParameter to QemuOpts, so that next patch can use it. It will simplify later patch for easier review. And will be finally removed after all backend drivers switch to QemuOpts. Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Leandro Dorileo Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 9 +++ util/qemu-option.c | 153 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/include/qemu/option.h b/include/qemu/option.h index fbf5dc2275..e98e8efbc1 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -103,6 +103,12 @@ typedef struct QemuOptDesc { } QemuOptDesc; struct QemuOptsList { + /* FIXME: Temp used for QEMUOptionParamter->QemuOpts conversion to + * indicate the need to free memory. Will remove after all drivers + * switch to QemuOpts. + */ + bool allocated; + const char *name; const char *implied_opt_name; bool merge_lists; /* Merge multiple uses of option into a single list? */ @@ -167,5 +173,8 @@ void qemu_opts_print(QemuOpts *opts); int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, int abort_on_failure); void qemu_opts_print_help(QemuOptsList *list); +void qemu_opts_free(QemuOptsList *list); +QEMUOptionParameter *opts_to_params(QemuOpts *opts); +QemuOptsList *params_to_opts(QEMUOptionParameter *list); #endif diff --git a/util/qemu-option.c b/util/qemu-option.c index cd03eb43c4..3c5484b978 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -1346,3 +1346,156 @@ int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, loc_pop(&loc); return rc; } + +static size_t count_opts_list(QemuOptsList *list) +{ + QemuOptDesc *desc = NULL; + size_t num_opts = 0; + + if (!list) { + return 0; + } + + desc = list->desc; + while (desc && desc->name) { + num_opts++; + desc++; + } + + return num_opts; +} + +/* Convert QEMUOptionParameter to QemuOpts + * FIXME: this function will be removed after all drivers + * switch to QemuOpts + */ +QemuOptsList *params_to_opts(QEMUOptionParameter *list) +{ + QemuOptsList *opts = NULL; + size_t num_opts, i = 0; + + if (!list) { + return NULL; + } + + num_opts = count_option_parameters(list); + opts = g_malloc0(sizeof(QemuOptsList) + + (num_opts + 1) * sizeof(QemuOptDesc)); + QTAILQ_INIT(&opts->head); + /* (const char *) members will point to malloced space and need to free */ + opts->allocated = true; + + while (list && list->name) { + opts->desc[i].name = g_strdup(list->name); + opts->desc[i].help = g_strdup(list->help); + switch (list->type) { + case OPT_FLAG: + opts->desc[i].type = QEMU_OPT_BOOL; + opts->desc[i].def_value_str = + g_strdup(list->value.n ? "on" : "off"); + break; + + case OPT_NUMBER: + opts->desc[i].type = QEMU_OPT_NUMBER; + if (list->value.n) { + opts->desc[i].def_value_str = + g_strdup_printf("%" PRIu64, list->value.n); + } + break; + + case OPT_SIZE: + opts->desc[i].type = QEMU_OPT_SIZE; + if (list->value.n) { + opts->desc[i].def_value_str = + g_strdup_printf("%" PRIu64, list->value.n); + } + break; + + case OPT_STRING: + opts->desc[i].type = QEMU_OPT_STRING; + opts->desc[i].def_value_str = g_strdup(list->value.s); + break; + } + + i++; + list++; + } + + return opts; +} + +/* convert QemuOpts to QEMUOptionParameter + * Note: result QEMUOptionParameter has shorter lifetime than + * input QemuOpts. + * FIXME: this function will be removed after all drivers + * switch to QemuOpts + */ +QEMUOptionParameter *opts_to_params(QemuOpts *opts) +{ + QEMUOptionParameter *dest = NULL; + QemuOptDesc *desc; + size_t num_opts, i = 0; + const char *tmp; + + if (!opts || !opts->list || !opts->list->desc) { + return NULL; + } + assert(!opts_accepts_any(opts)); + + num_opts = count_opts_list(opts->list); + dest = g_malloc0((num_opts + 1) * sizeof(QEMUOptionParameter)); + + desc = opts->list->desc; + while (desc && desc->name) { + dest[i].name = desc->name; + dest[i].help = desc->help; + dest[i].assigned = qemu_opt_find(opts, desc->name) ? true : false; + switch (desc->type) { + case QEMU_OPT_STRING: + dest[i].type = OPT_STRING; + tmp = qemu_opt_get(opts, desc->name); + dest[i].value.s = g_strdup(tmp); + break; + + case QEMU_OPT_BOOL: + dest[i].type = OPT_FLAG; + dest[i].value.n = qemu_opt_get_bool(opts, desc->name, 0) ? 1 : 0; + break; + + case QEMU_OPT_NUMBER: + dest[i].type = OPT_NUMBER; + dest[i].value.n = qemu_opt_get_number(opts, desc->name, 0); + break; + + case QEMU_OPT_SIZE: + dest[i].type = OPT_SIZE; + dest[i].value.n = qemu_opt_get_size(opts, desc->name, 0); + break; + } + + i++; + desc++; + } + + return dest; +} + +void qemu_opts_free(QemuOptsList *list) +{ + /* List members point to new malloced space and need to be freed. + * FIXME: + * Introduced for QEMUOptionParamter->QemuOpts conversion. + * Will remove after all drivers switch to QemuOpts. + */ + if (list && list->allocated) { + QemuOptDesc *desc = list->desc; + while (desc && desc->name) { + g_free((char *)desc->name); + g_free((char *)desc->help); + g_free((char *)desc->def_value_str); + desc++; + } + } + + g_free(list); +} From a1097a2614c3ff772e450454417bb1b51d6a01bc Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:49 +0800 Subject: [PATCH 16/39] QemuOpts: add qemu_opts_append to replace append_option_parameters For later merge .create_opts of drv and proto_drv in qemu-img commands. Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Leandro Dorileo Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 5 ++++ util/qemu-option.c | 67 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/include/qemu/option.h b/include/qemu/option.h index e98e8efbc1..44d9961c88 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -176,5 +176,10 @@ void qemu_opts_print_help(QemuOptsList *list); void qemu_opts_free(QemuOptsList *list); QEMUOptionParameter *opts_to_params(QemuOpts *opts); QemuOptsList *params_to_opts(QEMUOptionParameter *list); +/* FIXME: will remove QEMUOptionParameter after all drivers switch to QemuOpts. + */ +QemuOptsList *qemu_opts_append(QemuOptsList *dst, + QemuOptsList *list, + QEMUOptionParameter *param); #endif diff --git a/util/qemu-option.c b/util/qemu-option.c index 3c5484b978..6acfb0eb41 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -1499,3 +1499,70 @@ void qemu_opts_free(QemuOptsList *list) g_free(list); } + +/* Realloc dst option list and append options either from an option list (list) + * or a QEMUOptionParameter (param) to it. dst could be NULL or a malloced list. + * FIXME: will remove QEMUOptionParameter after all drivers switch to QemuOpts. + */ +QemuOptsList *qemu_opts_append(QemuOptsList *dst, + QemuOptsList *list, + QEMUOptionParameter *param) +{ + size_t num_opts, num_dst_opts; + QemuOptDesc *desc; + bool need_init = false; + + assert(!(list && param)); + if (!param && !list) { + return dst; + } + + if (param) { + list = params_to_opts(param); + } + + /* If dst is NULL, after realloc, some area of dst should be initialized + * before adding options to it. + */ + if (!dst) { + need_init = true; + } + + num_opts = count_opts_list(dst); + num_dst_opts = num_opts; + num_opts += count_opts_list(list); + dst = g_realloc(dst, sizeof(QemuOptsList) + + (num_opts + 1) * sizeof(QemuOptDesc)); + if (need_init) { + dst->name = NULL; + dst->implied_opt_name = NULL; + QTAILQ_INIT(&dst->head); + dst->allocated = true; + dst->merge_lists = false; + } + dst->desc[num_dst_opts].name = NULL; + + /* (const char *) members of result dst are malloced, need free. */ + assert(dst->allocated); + /* append list->desc to dst->desc */ + if (list) { + desc = list->desc; + while (desc && desc->name) { + if (find_desc_by_name(dst->desc, desc->name) == NULL) { + dst->desc[num_dst_opts].name = g_strdup(desc->name); + dst->desc[num_dst_opts].type = desc->type; + dst->desc[num_dst_opts].help = g_strdup(desc->help); + dst->desc[num_dst_opts].def_value_str = + g_strdup(desc->def_value_str); + num_dst_opts++; + dst->desc[num_dst_opts].name = NULL; + } + desc++; + } + } + + if (param) { + qemu_opts_free(list); + } + return dst; +} From 4782183da39ec988b8290bbc0289c9f50ba33ea4 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:50 +0800 Subject: [PATCH 17/39] QemuOpts: check NULL input for qemu_opts_del To simplify later using of qemu_opts_del, accept NULL input. Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Leandro Dorileo Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- util/qemu-option.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util/qemu-option.c b/util/qemu-option.c index 6acfb0eb41..40e1ff384a 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -1011,6 +1011,10 @@ void qemu_opts_del(QemuOpts *opts) { QemuOpt *opt; + if (opts == NULL) { + return; + } + for (;;) { opt = QTAILQ_FIRST(&opts->head); if (opt == NULL) From 83d0521a1e35989b0cb7235aef48455fedda3ca4 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:51 +0800 Subject: [PATCH 18/39] change block layer to support both QemuOpts and QEMUOptionParamter Change block layer to support both QemuOpts and QEMUOptionParameter. After this patch, it will change backend drivers one by one. At the end, QEMUOptionParameter will be removed and only QemuOpts is kept. Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Reviewed-by: Eric Blake Signed-off-by: Stefan Hajnoczi --- block.c | 160 +++++++++++++++++++++++++------------ block/cow.c | 2 +- block/qcow.c | 2 +- block/qcow2.c | 2 +- block/qed.c | 2 +- block/raw_bsd.c | 2 +- block/vhdx.c | 2 +- block/vmdk.c | 4 +- block/vvfat.c | 2 +- include/block/block.h | 7 +- include/block/block_int.h | 13 ++- qemu-img.c | 96 +++++++++++----------- tests/qemu-iotests/049.out | 2 +- tests/qemu-iotests/061.out | 2 +- 14 files changed, 184 insertions(+), 114 deletions(-) diff --git a/block.c b/block.c index 17f763db79..3dd2194515 100644 --- a/block.c +++ b/block.c @@ -329,6 +329,13 @@ void bdrv_register(BlockDriver *bdrv) } } + if (bdrv->bdrv_create) { + assert(!bdrv->bdrv_create2 && !bdrv->create_opts); + assert(!bdrv->bdrv_amend_options2); + } else if (bdrv->bdrv_create2) { + assert(!bdrv->bdrv_create && !bdrv->create_options); + assert(!bdrv->bdrv_amend_options); + } QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); } @@ -425,6 +432,7 @@ typedef struct CreateCo { BlockDriver *drv; char *filename; QEMUOptionParameter *options; + QemuOpts *opts; int ret; Error *err; } CreateCo; @@ -436,8 +444,28 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque) CreateCo *cco = opaque; assert(cco->drv); + assert(!(cco->options && cco->opts)); - ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err); + if (cco->drv->bdrv_create2) { + QemuOptsList *opts_list = NULL; + if (cco->options) { + opts_list = params_to_opts(cco->options); + cco->opts = qemu_opts_create(opts_list, NULL, 0, &error_abort); + } + ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err); + if (cco->options) { + qemu_opts_del(cco->opts); + qemu_opts_free(opts_list); + } + } else { + if (cco->opts) { + cco->options = opts_to_params(cco->opts); + } + ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err); + if (cco->opts) { + free_option_parameters(cco->options); + } + } if (local_err) { error_propagate(&cco->err, local_err); } @@ -445,7 +473,8 @@ 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; @@ -454,11 +483,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; @@ -490,7 +520,7 @@ out: } int bdrv_create_file(const char* filename, QEMUOptionParameter *options, - Error **errp) + QemuOpts *opts, Error **errp) { BlockDriver *drv; Error *local_err = NULL; @@ -502,7 +532,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 (local_err) { error_propagate(errp, local_err); } @@ -1247,7 +1277,8 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) char *tmp_filename = g_malloc0(PATH_MAX + 1); int64_t total_size; BlockDriver *bdrv_qcow2; - QEMUOptionParameter *create_options; + QemuOptsList *create_opts = NULL; + QemuOpts *opts = NULL; QDict *snapshot_options; BlockDriverState *bs_snapshot; Error *local_err; @@ -1272,13 +1303,20 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) } 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); - - ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err); - free_option_parameters(create_options); + assert(!(bdrv_qcow2->create_options && bdrv_qcow2->create_opts)); + if (bdrv_qcow2->create_options) { + create_opts = params_to_opts(bdrv_qcow2->create_options); + } else { + create_opts = bdrv_qcow2->create_opts; + } + opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size); + ret = bdrv_create(bdrv_qcow2, tmp_filename, NULL, opts, &local_err); + qemu_opts_del(opts); + if (bdrv_qcow2->create_options) { + qemu_opts_free(create_opts); + } if (ret < 0) { error_setg_errno(errp, -ret, "Could not create temporary overlay " "'%s': %s", tmp_filename, @@ -5519,8 +5557,10 @@ void bdrv_img_create(const char *filename, const char *fmt, char *options, uint64_t img_size, int flags, Error **errp, bool quiet) { - QEMUOptionParameter *param = NULL, *create_options = NULL; - QEMUOptionParameter *backing_fmt, *backing_file, *size; + QemuOptsList *create_opts = NULL; + QemuOpts *opts = NULL; + const char *backing_fmt, *backing_file; + int64_t size; BlockDriver *drv, *proto_drv; BlockDriver *backing_drv = NULL; Error *local_err = NULL; @@ -5539,28 +5579,25 @@ 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); + create_opts = qemu_opts_append(create_opts, drv->create_opts, + drv->create_options); + create_opts = qemu_opts_append(create_opts, proto_drv->create_opts, + 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); + opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); + 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); + 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)) { + 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; @@ -5568,37 +5605,37 @@ void bdrv_img_create(const char *filename, const char *fmt, } if (base_fmt) { - if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, 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)) { + 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); + 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->value.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 = get_option_parameter(param, BLOCK_OPT_SIZE); - if (size && size->value.n == -1) { - if (backing_file && backing_file->value.s) { + size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0); + if (size == -1) { + if (backing_file) { BlockDriverState *bs; uint64_t size; char buf[32]; @@ -5609,11 +5646,11 @@ void bdrv_img_create(const char *filename, const char *fmt, flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); bs = NULL; - ret = bdrv_open(&bs, backing_file->value.s, NULL, NULL, back_flags, + ret = bdrv_open(&bs, backing_file, NULL, NULL, back_flags, backing_drv, &local_err); if (ret < 0) { error_setg_errno(errp, -ret, "Could not open '%s': %s", - backing_file->value.s, + backing_file, error_get_pretty(local_err)); error_free(local_err); local_err = NULL; @@ -5623,7 +5660,7 @@ void bdrv_img_create(const char *filename, const char *fmt, size *= 512; snprintf(buf, sizeof(buf), "%" PRId64, size); - set_option_parameter(param, BLOCK_OPT_SIZE, buf); + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size); bdrv_unref(bs); } else { @@ -5634,16 +5671,18 @@ void bdrv_img_create(const char *filename, const char *fmt, if (!quiet) { printf("Formatting '%s', fmt=%s ", filename, fmt); - print_option_parameters(param); + qemu_opts_print(opts); puts(""); } - ret = bdrv_create(drv, filename, param, &local_err); + + 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 (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) { + 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'" @@ -5653,9 +5692,8 @@ void bdrv_img_create(const char *filename, const char *fmt, } out: - free_option_parameters(create_options); - free_option_parameters(param); - + qemu_opts_del(opts); + qemu_opts_free(create_opts); if (local_err) { error_propagate(errp, local_err); } @@ -5731,12 +5769,36 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs, notifier_with_return_list_add(&bs->before_write_notifiers, notifier); } -int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options) +int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options, + QemuOpts *opts) { - if (bs->drv->bdrv_amend_options == NULL) { + int ret; + assert(!(options && opts)); + + if (!bs->drv->bdrv_amend_options && !bs->drv->bdrv_amend_options2) { return -ENOTSUP; } - return bs->drv->bdrv_amend_options(bs, options); + if (bs->drv->bdrv_amend_options2) { + QemuOptsList *opts_list = NULL; + if (options) { + opts_list = params_to_opts(options); + opts = qemu_opts_create(opts_list, NULL, 0, &error_abort); + } + ret = bs->drv->bdrv_amend_options2(bs, opts); + if (options) { + qemu_opts_del(opts); + qemu_opts_free(opts_list); + } + } else { + if (opts) { + options = opts_to_params(opts); + } + ret = bs->drv->bdrv_amend_options(bs, options); + if (opts) { + free_option_parameters(options); + } + } + return ret; } /* This function will be called by the bdrv_recurse_is_first_non_filter method diff --git a/block/cow.c b/block/cow.c index 164759f3a3..7e610249f0 100644 --- a/block/cow.c +++ b/block/cow.c @@ -345,7 +345,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) { error_propagate(errp, local_err); return ret; diff --git a/block/qcow.c b/block/qcow.c index 7fd57d744a..32651ebc24 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -718,7 +718,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) { error_propagate(errp, local_err); return ret; diff --git a/block/qcow2.c b/block/qcow2.c index a54d2ba897..6b95a7f3bd 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1626,7 +1626,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; diff --git a/block/qed.c b/block/qed.c index 79f5bd392a..9826ad8022 100644 --- a/block/qed.c +++ b/block/qed.c @@ -586,7 +586,7 @@ static int qed_create(const char *filename, uint32_t cluster_size, int ret = 0; BlockDriverState *bs; - 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); return ret; diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 01ea692a46..9ae5fc21d4 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -145,7 +145,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 (local_err) { error_propagate(errp, local_err); } diff --git a/block/vhdx.c b/block/vhdx.c index 353c74d35f..ca7d533948 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1803,7 +1803,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; diff --git a/block/vmdk.c b/block/vmdk.c index b8a476278a..b653f5ecef 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1539,7 +1539,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; @@ -1879,7 +1879,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_propagate(errp, local_err); goto exit; diff --git a/block/vvfat.c b/block/vvfat.c index 3cda19f2f3..d895582030 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2930,7 +2930,7 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp) 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, errp); + ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, NULL, errp); free_option_parameters(options); if (ret < 0) { goto err; diff --git a/include/block/block.h b/include/block/block.h index 7d86e29cf4..4312b8176e 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -204,9 +204,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, Error **errp); void bdrv_make_anon(BlockDriverState *bs); void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old); @@ -312,7 +312,8 @@ typedef enum { int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix); -int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options); +int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options, + QemuOpts *opts); /* external snapshots */ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, diff --git a/include/block/block_int.h b/include/block/block_int.h index 8d58334c1d..8a77d79f41 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -118,6 +118,8 @@ struct BlockDriver { void (*bdrv_rebind)(BlockDriverState *bs); int (*bdrv_create)(const char *filename, QEMUOptionParameter *options, Error **errp); + /* FIXME: will remove the duplicate and rename back to bdrv_create later */ + 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 */ @@ -217,7 +219,12 @@ struct BlockDriver { /* List of options for creating images, terminated by name == NULL */ QEMUOptionParameter *create_options; - + /* FIXME: will replace create_options. + * These two fields are mutually exclusive. At most one is non-NULL. + * create_options should only be set with bdrv_create, and create_opts + * should only be set with bdrv_create2. + */ + QemuOptsList *create_opts; /* * Returns 0 for completed check, -errno for internal errors. @@ -228,6 +235,10 @@ struct BlockDriver { int (*bdrv_amend_options)(BlockDriverState *bs, QEMUOptionParameter *options); + /* FIXME: will remove the duplicate and rename back to + * bdrv_amend_options later + */ + int (*bdrv_amend_options2)(BlockDriverState *bs, QemuOpts *opts); void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event); diff --git a/qemu-img.c b/qemu-img.c index aa89ba21fd..8acdcca8bf 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -271,7 +271,7 @@ static int read_password(char *buf, int buf_size) 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); @@ -280,22 +280,21 @@ 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_opts = qemu_opts_append(create_opts, drv->create_opts, + drv->create_options); if (filename) { proto_drv = bdrv_find_protocol(filename, true); if (!proto_drv) { error_report("Unknown protocol '%s'", filename); - free_option_parameters(create_options); + qemu_opts_free(create_opts); return 1; } - create_options = append_option_parameters(create_options, - proto_drv->create_options); + create_opts = qemu_opts_append(create_opts, proto_drv->create_opts, + proto_drv->create_options); } - print_option_help(create_options); - free_option_parameters(create_options); + qemu_opts_print_help(create_opts); + qemu_opts_free(create_opts); return 0; } @@ -349,19 +348,19 @@ fail: return NULL; } -static int add_old_style_options(const char *fmt, QEMUOptionParameter *list, +static int add_old_style_options(const char *fmt, 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 (qemu_opt_set(opts, 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 (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) { error_report("Backing file format not supported for file " "format '%s'", fmt); return -1; @@ -1191,8 +1190,9 @@ static int img_convert(int argc, char **argv) size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE; const uint8_t *buf1; BlockDriverInfo bdi; - QEMUOptionParameter *param = NULL, *create_options = NULL; - QEMUOptionParameter *out_baseimg_param; + QemuOpts *opts = NULL; + QemuOptsList *create_opts = NULL; + const char *out_baseimg_param; char *options = NULL; const char *snapshot_name = NULL; int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */ @@ -1381,40 +1381,36 @@ 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); + create_opts = qemu_opts_append(create_opts, drv->create_opts, + drv->create_options); + create_opts = qemu_opts_append(create_opts, proto_drv->create_opts, + 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); + 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; } - set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512); - ret = add_old_style_options(out_fmt, param, out_baseimg, NULL); + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512); + ret = add_old_style_options(out_fmt, 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); + out_baseimg_param = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE); if (out_baseimg_param) { - out_baseimg = out_baseimg_param->value.s; + 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); + 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"); @@ -1422,15 +1418,15 @@ static int img_convert(int argc, char **argv) goto out; } - if (encryption && encryption->value.n) { + if (encryption) { 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")) + if (preallocation + && strcmp(preallocation, "off")) { error_report("Compression and preallocation not supported at " "the same time"); @@ -1441,7 +1437,7 @@ static int img_convert(int argc, char **argv) if (!skip_create) { /* Create the new image */ - ret = bdrv_create(drv, out_filename, param, &local_err); + ret = bdrv_create(drv, out_filename, NULL, opts, &local_err); if (ret < 0) { error_report("%s: error while converting %s: %s", out_filename, out_fmt, error_get_pretty(local_err)); @@ -1706,8 +1702,8 @@ out: qemu_progress_print(100, 0); } qemu_progress_end(); - free_option_parameters(create_options); - free_option_parameters(param); + qemu_opts_del(opts); + qemu_opts_free(create_opts); qemu_vfree(buf); if (sn_opts) { qemu_opts_del(sn_opts); @@ -2698,7 +2694,8 @@ static int img_amend(int argc, char **argv) { int c, ret = 0; char *options = NULL; - QEMUOptionParameter *create_options = NULL, *options_param = NULL; + QemuOptsList *create_opts = NULL; + QemuOpts *opts = NULL; const char *fmt = NULL, *filename; bool quiet = false; BlockDriverState *bs = NULL; @@ -2769,17 +2766,16 @@ static int img_amend(int argc, char **argv) goto out; } - create_options = append_option_parameters(create_options, - bs->drv->create_options); - options_param = parse_option_parameters(options, create_options, - options_param); - if (options_param == NULL) { + create_opts = qemu_opts_append(create_opts, bs->drv->create_opts, + bs->drv->create_options); + 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'", fmt); ret = -1; goto out; } - ret = bdrv_amend_options(bs, options_param); + ret = bdrv_amend_options(bs, NULL, opts); if (ret < 0) { error_report("Error while amending options: %s", strerror(-ret)); goto out; @@ -2789,8 +2785,8 @@ out: if (bs) { bdrv_unref(bs); } - free_option_parameters(create_options); - free_option_parameters(options_param); + qemu_opts_del(opts); + qemu_opts_free(create_opts); g_free(options); if (ret) { diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out index ceb23289fd..71ca44d76b 100644 --- a/tests/qemu-iotests/049.out +++ b/tests/qemu-iotests/049.out @@ -120,7 +120,7 @@ qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes. qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2 qemu-img: Parameter 'size' expects a size -qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'. +qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2' == Check correct interpretation of suffixes for cluster size == diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out index 4027e0077e..e3724700b9 100644 --- a/tests/qemu-iotests/061.out +++ b/tests/qemu-iotests/061.out @@ -281,7 +281,7 @@ Lazy refcounts only supported with compatibility level 1.1 and above (use compat qemu-img: Error while amending options: Invalid argument Unknown compatibility level 0.42. qemu-img: Error while amending options: Invalid argument -Unknown option 'foo' +qemu-img: Invalid parameter 'foo' qemu-img: Invalid options for file format 'qcow2' Changing the cluster size is not supported. qemu-img: Error while amending options: Operation not supported From facdbb0272402618b6ca3b306a933e56dc4085c5 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:52 +0800 Subject: [PATCH 19/39] vvfat.c: handle cross_driver's create_options and create_opts vvfat shares create options of qcow driver. To avoid vvfat breaking when qcow driver changes from QEMUOptionParameter to QemuOpts, let it able to handle both cases. Signed-off-by: Chunyan Liu Reviewed-by: Eric Blake Signed-off-by: Stefan Hajnoczi --- block/vvfat.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/block/vvfat.c b/block/vvfat.c index d895582030..b1ab195334 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2910,8 +2910,9 @@ static BlockDriver vvfat_write_target = { static int enable_write_target(BDRVVVFATState *s, Error **errp) { - BlockDriver *bdrv_qcow; - QEMUOptionParameter *options; + BlockDriver *bdrv_qcow = NULL; + QemuOptsList *create_opts = NULL; + QemuOpts *opts = NULL; int ret; int size = sector2cluster(s, s->sector_count); s->used_clusters = calloc(size, 1); @@ -2926,12 +2927,21 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp) } bdrv_qcow = bdrv_find_format("qcow"); - options = parse_option_parameters("", bdrv_qcow->create_options, NULL); - set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512); - set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:"); + assert(!(bdrv_qcow->create_opts && bdrv_qcow->create_options)); + if (bdrv_qcow->create_options) { + create_opts = params_to_opts(bdrv_qcow->create_options); + } else { + create_opts = bdrv_qcow->create_opts; + } + opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512); + qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:"); - ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, NULL, errp); - free_option_parameters(options); + ret = bdrv_create(bdrv_qcow, s->qcow_filename, NULL, opts, errp); + qemu_opts_del(opts); + if (bdrv_qcow->create_options) { + qemu_opts_free(create_opts); + } if (ret < 0) { goto err; } From 25814e89871b4462638b290a4b17212526a01af3 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:53 +0800 Subject: [PATCH 20/39] cow.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/cow.c | 54 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/block/cow.c b/block/cow.c index 7e610249f0..af8575334a 100644 --- a/block/cow.c +++ b/block/cow.c @@ -324,31 +324,24 @@ static void cow_close(BlockDriverState *bs) { } -static int cow_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int cow_create(const char *filename, QemuOpts *opts, Error **errp) { struct cow_header_v2 cow_header; struct stat st; int64_t image_sectors = 0; - const char *image_filename = NULL; + char *image_filename = NULL; Error *local_err = NULL; int ret; BlockDriverState *cow_bs; /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - image_sectors = options->value.n / 512; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { - image_filename = options->value.s; - } - options++; - } + image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; + image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); - ret = bdrv_create_file(filename, options, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); - return ret; + goto exit; } cow_bs = NULL; @@ -356,7 +349,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); if (ret < 0) { error_propagate(errp, local_err); - return ret; + goto exit; } memset(&cow_header, 0, sizeof(cow_header)); @@ -389,22 +382,27 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, } exit: + g_free(image_filename); bdrv_unref(cow_bs); return ret; } -static QEMUOptionParameter cow_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_BACKING_FILE, - .type = OPT_STRING, - .help = "File name of a base image" - }, - { NULL } +static QemuOptsList cow_create_opts = { + .name = "cow-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(cow_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_BACKING_FILE, + .type = QEMU_OPT_STRING, + .help = "File name of a base image" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_cow = { @@ -414,14 +412,14 @@ static BlockDriver bdrv_cow = { .bdrv_probe = cow_probe, .bdrv_open = cow_open, .bdrv_close = cow_close, - .bdrv_create = cow_create, + .bdrv_create2 = cow_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_read = cow_co_read, .bdrv_write = cow_co_write, .bdrv_co_get_block_status = cow_co_get_block_status, - .create_options = cow_create_options, + .create_opts = &cow_create_opts, }; static void bdrv_cow_init(void) From 90c772de56a810265c52fd55ca384b01ab74e35d Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:54 +0800 Subject: [PATCH 21/39] gluster.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/gluster.c | 81 +++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/block/gluster.c b/block/gluster.c index 114689e441..5ff282bd74 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -478,13 +478,14 @@ static inline int qemu_gluster_zerofill(struct glfs_fd *fd, int64_t offset, #endif static int qemu_gluster_create(const char *filename, - QEMUOptionParameter *options, Error **errp) + QemuOpts *opts, Error **errp) { struct glfs *glfs; struct glfs_fd *fd; int ret = 0; int prealloc = 0; int64_t total_size = 0; + char *tmp = NULL; GlusterConf *gconf = g_malloc0(sizeof(GlusterConf)); glfs = qemu_gluster_init(gconf, filename, errp); @@ -493,24 +494,21 @@ static int qemu_gluster_create(const char *filename, goto out; } - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - total_size = options->value.n / BDRV_SECTOR_SIZE; - } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { - if (!options->value.s || !strcmp(options->value.s, "off")) { - prealloc = 0; - } else if (!strcmp(options->value.s, "full") && - gluster_supports_zerofill()) { - prealloc = 1; - } else { - error_setg(errp, "Invalid preallocation mode: '%s'" - " or GlusterFS doesn't support zerofill API", - options->value.s); - ret = -EINVAL; - goto out; - } - } - options++; + total_size = + qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; + + tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); + if (!tmp || !strcmp(tmp, "off")) { + prealloc = 0; + } else if (!strcmp(tmp, "full") && + gluster_supports_zerofill()) { + prealloc = 1; + } else { + error_setg(errp, "Invalid preallocation mode: '%s'" + " or GlusterFS doesn't support zerofill API", + tmp); + ret = -EINVAL; + goto out; } fd = glfs_creat(glfs, gconf->image, @@ -532,6 +530,7 @@ static int qemu_gluster_create(const char *filename, } } out: + g_free(tmp); qemu_gluster_gconf_free(gconf); if (glfs) { glfs_fini(glfs); @@ -698,18 +697,22 @@ static int qemu_gluster_has_zero_init(BlockDriverState *bs) return 0; } -static QEMUOptionParameter qemu_gluster_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_PREALLOC, - .type = OPT_STRING, - .help = "Preallocation mode (allowed values: off, full)" - }, - { NULL } +static QemuOptsList qemu_gluster_create_opts = { + .name = "qemu-gluster-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_PREALLOC, + .type = QEMU_OPT_STRING, + .help = "Preallocation mode (allowed values: off, full)" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_gluster = { @@ -722,7 +725,7 @@ static BlockDriver bdrv_gluster = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create = qemu_gluster_create, + .bdrv_create2 = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, @@ -736,7 +739,7 @@ static BlockDriver bdrv_gluster = { #ifdef CONFIG_GLUSTERFS_ZEROFILL .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, #endif - .create_options = qemu_gluster_create_options, + .create_opts = &qemu_gluster_create_opts, }; static BlockDriver bdrv_gluster_tcp = { @@ -749,7 +752,7 @@ static BlockDriver bdrv_gluster_tcp = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create = qemu_gluster_create, + .bdrv_create2 = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, @@ -763,7 +766,7 @@ static BlockDriver bdrv_gluster_tcp = { #ifdef CONFIG_GLUSTERFS_ZEROFILL .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, #endif - .create_options = qemu_gluster_create_options, + .create_opts = &qemu_gluster_create_opts, }; static BlockDriver bdrv_gluster_unix = { @@ -776,7 +779,7 @@ static BlockDriver bdrv_gluster_unix = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create = qemu_gluster_create, + .bdrv_create2 = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, @@ -790,7 +793,7 @@ static BlockDriver bdrv_gluster_unix = { #ifdef CONFIG_GLUSTERFS_ZEROFILL .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, #endif - .create_options = qemu_gluster_create_options, + .create_opts = &qemu_gluster_create_opts, }; static BlockDriver bdrv_gluster_rdma = { @@ -803,7 +806,7 @@ static BlockDriver bdrv_gluster_rdma = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create = qemu_gluster_create, + .bdrv_create2 = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, @@ -817,7 +820,7 @@ static BlockDriver bdrv_gluster_rdma = { #ifdef CONFIG_GLUSTERFS_ZEROFILL .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes, #endif - .create_options = qemu_gluster_create_options, + .create_opts = &qemu_gluster_create_opts, }; static void bdrv_gluster_init(void) From a59479e3f3dc4da005735b603b2770902556fe7a Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:55 +0800 Subject: [PATCH 22/39] iscsi.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/iscsi.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 38bfdb61a2..626b7df7fd 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1530,8 +1530,7 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset) return 0; } -static int iscsi_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp) { int ret = 0; int64_t total_size = 0; @@ -1542,13 +1541,8 @@ static int iscsi_create(const char *filename, QEMUOptionParameter *options, bs = bdrv_new("", &error_abort); /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, "size")) { - total_size = options->value.n / BDRV_SECTOR_SIZE; - } - options++; - } - + total_size = + qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; bs->opaque = g_malloc0(sizeof(struct IscsiLun)); iscsilun = bs->opaque; @@ -1590,13 +1584,17 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return 0; } -static QEMUOptionParameter iscsi_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { NULL } +static QemuOptsList iscsi_create_opts = { + .name = "iscsi-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_iscsi = { @@ -1607,8 +1605,8 @@ static BlockDriver bdrv_iscsi = { .bdrv_needs_filename = true, .bdrv_file_open = iscsi_open, .bdrv_close = iscsi_close, - .bdrv_create = iscsi_create, - .create_options = iscsi_create_options, + .bdrv_create2 = iscsi_create, + .create_opts = &iscsi_create_opts, .bdrv_reopen_prepare = iscsi_reopen_prepare, .bdrv_getlength = iscsi_getlength, From 98c10b810a83a0f52b4b5a14a8a36ce0622cb01f Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:56 +0800 Subject: [PATCH 23/39] nfs.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/nfs.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/block/nfs.c b/block/nfs.c index e282f8de37..35e5008ead 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -391,8 +391,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags, return 0; } -static int nfs_file_create(const char *url, QEMUOptionParameter *options, - Error **errp) +static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp) { int ret = 0; int64_t total_size = 0; @@ -401,12 +400,7 @@ static int nfs_file_create(const char *url, QEMUOptionParameter *options, client->aio_context = qemu_get_aio_context(); /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, "size")) { - total_size = options->value.n; - } - options++; - } + total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); ret = nfs_client_open(client, url, O_CREAT, errp); if (ret < 0) { @@ -463,7 +457,7 @@ static BlockDriver bdrv_nfs = { .bdrv_file_open = nfs_file_open, .bdrv_close = nfs_file_close, - .bdrv_create = nfs_file_create, + .bdrv_create2 = nfs_file_create, .bdrv_co_readv = nfs_co_readv, .bdrv_co_writev = nfs_co_writev, From 16d12159e207a167bd4f417fbd199736ad2da2d0 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:57 +0800 Subject: [PATCH 24/39] qcow.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/qcow.c | 72 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/block/qcow.c b/block/qcow.c index 32651ebc24..bcacfb852f 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -693,35 +693,29 @@ static void qcow_close(BlockDriverState *bs) error_free(s->migration_blocker); } -static int qcow_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) { int header_size, backing_filename_len, l1_size, shift, i; QCowHeader header; uint8_t *tmp; int64_t total_size = 0; - const char *backing_file = NULL; + char *backing_file = NULL; int flags = 0; Error *local_err = NULL; int ret; BlockDriverState *qcow_bs; /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - total_size = options->value.n / 512; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { - backing_file = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) { - flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0; - } - options++; + total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; + backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); + if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { + flags |= BLOCK_FLAG_ENCRYPT; } - ret = bdrv_create_file(filename, options, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); - return ret; + goto cleanup; } qcow_bs = NULL; @@ -729,7 +723,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); if (ret < 0) { error_propagate(errp, local_err); - return ret; + goto cleanup; } ret = bdrv_truncate(qcow_bs, 0); @@ -800,6 +794,8 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, ret = 0; exit: bdrv_unref(qcow_bs); +cleanup: + g_free(backing_file); return ret; } @@ -912,24 +908,28 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return 0; } - -static QEMUOptionParameter qcow_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_BACKING_FILE, - .type = OPT_STRING, - .help = "File name of a base image" - }, - { - .name = BLOCK_OPT_ENCRYPT, - .type = OPT_FLAG, - .help = "Encrypt the image" - }, - { NULL } +static QemuOptsList qcow_create_opts = { + .name = "qcow-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(qcow_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_BACKING_FILE, + .type = QEMU_OPT_STRING, + .help = "File name of a base image" + }, + { + .name = BLOCK_OPT_ENCRYPT, + .type = QEMU_OPT_BOOL, + .help = "Encrypt the image", + .def_value_str = "off" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_qcow = { @@ -938,8 +938,8 @@ static BlockDriver bdrv_qcow = { .bdrv_probe = qcow_probe, .bdrv_open = qcow_open, .bdrv_close = qcow_close, - .bdrv_reopen_prepare = qcow_reopen_prepare, - .bdrv_create = qcow_create, + .bdrv_reopen_prepare = qcow_reopen_prepare, + .bdrv_create2 = qcow_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_readv = qcow_co_readv, @@ -951,7 +951,7 @@ static BlockDriver bdrv_qcow = { .bdrv_write_compressed = qcow_write_compressed, .bdrv_get_info = qcow_get_info, - .create_options = qcow_create_options, + .create_opts = &qcow_create_opts, }; static void bdrv_qcow_init(void) From 74c3c19765c1abf202561af20dfc8f52d9cff808 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:58 +0800 Subject: [PATCH 25/39] QemuOpts: export qemu_opt_find Export qemu_opt_find for qcow2 driver using it. After replacing QEMUOptionParameter with QemuOpts, qcow2 driver will use qemu_opt_find to judge if an option is explicitly set, to replace the usage of .assigned in QEMUOptionParameter. Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 1 + util/qemu-option.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index 44d9961c88..34552678c3 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -130,6 +130,7 @@ char *qemu_opt_get_del(QemuOpts *opts, const char *name); * Returns: true if @opts includes 'help' or equivalent. */ bool qemu_opt_has_help_opt(QemuOpts *opts); +QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name); bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval); uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval); uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval); diff --git a/util/qemu-option.c b/util/qemu-option.c index 40e1ff384a..0d9d3ec889 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -568,7 +568,7 @@ void qemu_opts_print_help(QemuOptsList *list) } /* ------------------------------------------------------------------ */ -static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) +QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name) { QemuOpt *opt; From 1bd0e2d1c40ef1dbe717728197071e931abe22a4 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:20:59 +0800 Subject: [PATCH 26/39] qcow2.c: replace QEMUOptionParameter with QemuOpts Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/qcow2.c | 261 +++++++++++++++++++++++++++----------------------- 1 file changed, 139 insertions(+), 122 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 6b95a7f3bd..7150df66d6 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -31,6 +31,7 @@ #include "qapi/qmp/qerror.h" #include "qapi/qmp/qbool.h" #include "trace.h" +#include "qemu/option_int.h" /* Differences with QCOW: @@ -1594,7 +1595,7 @@ static int preallocate(BlockDriverState *bs) static int qcow2_create2(const char *filename, int64_t total_size, const char *backing_file, const char *backing_format, int flags, size_t cluster_size, int prealloc, - QEMUOptionParameter *options, int version, + QemuOpts *opts, int version, Error **errp) { /* Calculate cluster_bits */ @@ -1626,7 +1627,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, Error *local_err = NULL; int ret; - ret = bdrv_create_file(filename, options, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); return ret; @@ -1762,11 +1763,11 @@ out: return ret; } -static int qcow2_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) { - const char *backing_file = NULL; - const char *backing_fmt = NULL; + char *backing_file = NULL; + char *backing_fmt = NULL; + char *buf = NULL; uint64_t sectors = 0; int flags = 0; size_t cluster_size = DEFAULT_CLUSTER_SIZE; @@ -1776,64 +1777,66 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options, int ret; /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - sectors = options->value.n / 512; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { - backing_file = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) { - backing_fmt = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) { - flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0; - } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { - if (options->value.n) { - cluster_size = options->value.n; - } - } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { - if (!options->value.s || !strcmp(options->value.s, "off")) { - prealloc = 0; - } else if (!strcmp(options->value.s, "metadata")) { - prealloc = 1; - } else { - error_setg(errp, "Invalid preallocation mode: '%s'", - options->value.s); - return -EINVAL; - } - } else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) { - if (!options->value.s) { - /* keep the default */ - } else if (!strcmp(options->value.s, "0.10")) { - version = 2; - } else if (!strcmp(options->value.s, "1.1")) { - version = 3; - } else { - error_setg(errp, "Invalid compatibility level: '%s'", - options->value.s); - return -EINVAL; - } - } else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) { - flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0; - } - options++; + sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; + backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); + backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); + if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { + flags |= BLOCK_FLAG_ENCRYPT; + } + cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, + DEFAULT_CLUSTER_SIZE); + buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); + if (!buf || !strcmp(buf, "off")) { + prealloc = 0; + } else if (!strcmp(buf, "metadata")) { + prealloc = 1; + } else { + error_setg(errp, "Invalid preallocation mode: '%s'", buf); + ret = -EINVAL; + goto finish; + } + g_free(buf); + buf = qemu_opt_get_del(opts, BLOCK_OPT_COMPAT_LEVEL); + if (!buf) { + /* keep the default */ + } else if (!strcmp(buf, "0.10")) { + version = 2; + } else if (!strcmp(buf, "1.1")) { + version = 3; + } else { + error_setg(errp, "Invalid compatibility level: '%s'", buf); + ret = -EINVAL; + goto finish; + } + + if (qemu_opt_get_bool_del(opts, BLOCK_OPT_LAZY_REFCOUNTS, false)) { + flags |= BLOCK_FLAG_LAZY_REFCOUNTS; } if (backing_file && prealloc) { error_setg(errp, "Backing file and preallocation cannot be used at " "the same time"); - return -EINVAL; + ret = -EINVAL; + goto finish; } if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) { error_setg(errp, "Lazy refcounts only supported with compatibility " "level 1.1 and above (use compat=1.1 or greater)"); - return -EINVAL; + ret = -EINVAL; + goto finish; } ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags, - cluster_size, prealloc, options, version, &local_err); + cluster_size, prealloc, opts, version, &local_err); if (local_err) { error_propagate(errp, local_err); } + +finish: + g_free(backing_file); + g_free(backing_fmt); + g_free(buf); return ret; } @@ -2198,64 +2201,72 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version) return 0; } -static int qcow2_amend_options(BlockDriverState *bs, - QEMUOptionParameter *options) +static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts) { BDRVQcowState *s = bs->opaque; int old_version = s->qcow_version, new_version = old_version; uint64_t new_size = 0; const char *backing_file = NULL, *backing_format = NULL; bool lazy_refcounts = s->use_lazy_refcounts; + const char *compat = NULL; + uint64_t cluster_size = s->cluster_size; + bool encrypt; int ret; - int i; + QemuOptDesc *desc = opts->list->desc; - for (i = 0; options[i].name; i++) - { - if (!options[i].assigned) { + while (desc && desc->name) { + if (!qemu_opt_find(opts, desc->name)) { /* only change explicitly defined options */ + desc++; continue; } - if (!strcmp(options[i].name, "compat")) { - if (!options[i].value.s) { + if (!strcmp(desc->name, "compat")) { + compat = qemu_opt_get(opts, "compat"); + if (!compat) { /* preserve default */ - } else if (!strcmp(options[i].value.s, "0.10")) { + } else if (!strcmp(compat, "0.10")) { new_version = 2; - } else if (!strcmp(options[i].value.s, "1.1")) { + } else if (!strcmp(compat, "1.1")) { new_version = 3; } else { - fprintf(stderr, "Unknown compatibility level %s.\n", - options[i].value.s); + fprintf(stderr, "Unknown compatibility level %s.\n", compat); return -EINVAL; } - } else if (!strcmp(options[i].name, "preallocation")) { + } else if (!strcmp(desc->name, "preallocation")) { fprintf(stderr, "Cannot change preallocation mode.\n"); return -ENOTSUP; - } else if (!strcmp(options[i].name, "size")) { - new_size = options[i].value.n; - } else if (!strcmp(options[i].name, "backing_file")) { - backing_file = options[i].value.s; - } else if (!strcmp(options[i].name, "backing_fmt")) { - backing_format = options[i].value.s; - } else if (!strcmp(options[i].name, "encryption")) { - if ((options[i].value.n != !!s->crypt_method)) { + } else if (!strcmp(desc->name, "size")) { + new_size = qemu_opt_get_size(opts, "size", 0); + } else if (!strcmp(desc->name, "backing_file")) { + backing_file = qemu_opt_get(opts, "backing_file"); + } else if (!strcmp(desc->name, "backing_fmt")) { + backing_format = qemu_opt_get(opts, "backing_fmt"); + } else if (!strcmp(desc->name, "encryption")) { + encrypt = qemu_opt_get_bool(opts, "encryption", s->crypt_method); + if (encrypt != !!s->crypt_method) { fprintf(stderr, "Changing the encryption flag is not " "supported.\n"); return -ENOTSUP; } - } else if (!strcmp(options[i].name, "cluster_size")) { - if (options[i].value.n != s->cluster_size) { + } else if (!strcmp(desc->name, "cluster_size")) { + cluster_size = qemu_opt_get_size(opts, "cluster_size", + cluster_size); + if (cluster_size != s->cluster_size) { fprintf(stderr, "Changing the cluster size is not " "supported.\n"); return -ENOTSUP; } - } else if (!strcmp(options[i].name, "lazy_refcounts")) { - lazy_refcounts = options[i].value.n; + } else if (!strcmp(desc->name, "lazy_refcounts")) { + lazy_refcounts = qemu_opt_get_bool(opts, "lazy_refcounts", + lazy_refcounts); } else { /* if this assertion fails, this probably means a new option was * added without having it covered here */ assert(false); } + + desc++; } if (new_version != old_version) { @@ -2324,49 +2335,55 @@ static int qcow2_amend_options(BlockDriverState *bs, return 0; } -static QEMUOptionParameter qcow2_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_COMPAT_LEVEL, - .type = OPT_STRING, - .help = "Compatibility level (0.10 or 1.1)" - }, - { - .name = BLOCK_OPT_BACKING_FILE, - .type = OPT_STRING, - .help = "File name of a base image" - }, - { - .name = BLOCK_OPT_BACKING_FMT, - .type = OPT_STRING, - .help = "Image format of the base image" - }, - { - .name = BLOCK_OPT_ENCRYPT, - .type = OPT_FLAG, - .help = "Encrypt the image" - }, - { - .name = BLOCK_OPT_CLUSTER_SIZE, - .type = OPT_SIZE, - .help = "qcow2 cluster size", - .value = { .n = DEFAULT_CLUSTER_SIZE }, - }, - { - .name = BLOCK_OPT_PREALLOC, - .type = OPT_STRING, - .help = "Preallocation mode (allowed values: off, metadata)" - }, - { - .name = BLOCK_OPT_LAZY_REFCOUNTS, - .type = OPT_FLAG, - .help = "Postpone refcount updates", - }, - { NULL } +static QemuOptsList qcow2_create_opts = { + .name = "qcow2-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_COMPAT_LEVEL, + .type = QEMU_OPT_STRING, + .help = "Compatibility level (0.10 or 1.1)" + }, + { + .name = BLOCK_OPT_BACKING_FILE, + .type = QEMU_OPT_STRING, + .help = "File name of a base image" + }, + { + .name = BLOCK_OPT_BACKING_FMT, + .type = QEMU_OPT_STRING, + .help = "Image format of the base image" + }, + { + .name = BLOCK_OPT_ENCRYPT, + .type = QEMU_OPT_BOOL, + .help = "Encrypt the image", + .def_value_str = "off" + }, + { + .name = BLOCK_OPT_CLUSTER_SIZE, + .type = QEMU_OPT_SIZE, + .help = "qcow2 cluster size", + .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) + }, + { + .name = BLOCK_OPT_PREALLOC, + .type = QEMU_OPT_STRING, + .help = "Preallocation mode (allowed values: off, metadata)" + }, + { + .name = BLOCK_OPT_LAZY_REFCOUNTS, + .type = QEMU_OPT_BOOL, + .help = "Postpone refcount updates", + .def_value_str = "off" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_qcow2 = { @@ -2376,7 +2393,7 @@ static BlockDriver bdrv_qcow2 = { .bdrv_open = qcow2_open, .bdrv_close = qcow2_close, .bdrv_reopen_prepare = qcow2_reopen_prepare, - .bdrv_create = qcow2_create, + .bdrv_create2 = qcow2_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = qcow2_co_get_block_status, .bdrv_set_key = qcow2_set_key, @@ -2394,8 +2411,8 @@ static BlockDriver bdrv_qcow2 = { .bdrv_snapshot_goto = qcow2_snapshot_goto, .bdrv_snapshot_delete = qcow2_snapshot_delete, .bdrv_snapshot_list = qcow2_snapshot_list, - .bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp, - .bdrv_get_info = qcow2_get_info, + .bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp, + .bdrv_get_info = qcow2_get_info, .bdrv_get_specific_info = qcow2_get_specific_info, .bdrv_save_vmstate = qcow2_save_vmstate, @@ -2406,9 +2423,9 @@ static BlockDriver bdrv_qcow2 = { .bdrv_refresh_limits = qcow2_refresh_limits, .bdrv_invalidate_cache = qcow2_invalidate_cache, - .create_options = qcow2_create_options, - .bdrv_check = qcow2_check, - .bdrv_amend_options = qcow2_amend_options, + .create_opts = &qcow2_create_opts, + .bdrv_check = qcow2_check, + .bdrv_amend_options2 = qcow2_amend_options, }; static void bdrv_qcow2_init(void) From 7ab74849a5724452b35982a6e7d658c25839f5e5 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:00 +0800 Subject: [PATCH 27/39] qed.c: replace QEMUOptionParameter with QemuOpts One extra change is to define QED_DEFAULT_CLUSTER_SIZE = 65536 instead of 64 * 1024; because: according to existing create_options, "cluster size" has default value = QED_DEFAULT_CLUSTER_SIZE, after switching to create_opts, this has to be stringized and set to .def_value_str. That is, .def_value_str = stringify(QED_DEFAULT_CLUSTER_SIZE), so the QED_DEFAULT_CLUSTER_SIZE could not be a expression. Reviewed-by: Stefan Hajnoczi Reviewed-by: Eric Blake Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/qed.c | 112 +++++++++++++++++++++++++++------------------------- block/qed.h | 3 +- 2 files changed, 60 insertions(+), 55 deletions(-) diff --git a/block/qed.c b/block/qed.c index 9826ad8022..7c4276e97c 100644 --- a/block/qed.c +++ b/block/qed.c @@ -641,55 +641,53 @@ out: return ret; } -static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int bdrv_qed_create(const char *filename, QemuOpts *opts, Error **errp) { uint64_t image_size = 0; uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE; uint32_t table_size = QED_DEFAULT_TABLE_SIZE; - const char *backing_file = NULL; - const char *backing_fmt = NULL; + char *backing_file = NULL; + char *backing_fmt = NULL; + int ret; - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - image_size = options->value.n; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { - backing_file = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) { - backing_fmt = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { - if (options->value.n) { - cluster_size = options->value.n; - } - } else if (!strcmp(options->name, BLOCK_OPT_TABLE_SIZE)) { - if (options->value.n) { - table_size = options->value.n; - } - } - options++; - } + image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); + backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); + backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); + cluster_size = qemu_opt_get_size_del(opts, + BLOCK_OPT_CLUSTER_SIZE, + QED_DEFAULT_CLUSTER_SIZE); + table_size = qemu_opt_get_size_del(opts, BLOCK_OPT_TABLE_SIZE, + QED_DEFAULT_TABLE_SIZE); if (!qed_is_cluster_size_valid(cluster_size)) { error_setg(errp, "QED cluster size must be within range [%u, %u] " "and power of 2", QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE); - return -EINVAL; + ret = -EINVAL; + goto finish; } if (!qed_is_table_size_valid(table_size)) { error_setg(errp, "QED table size must be within range [%u, %u] " "and power of 2", QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE); - return -EINVAL; + ret = -EINVAL; + goto finish; } if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) { error_setg(errp, "QED image size must be a non-zero multiple of " "cluster size and less than %" PRIu64 " bytes", qed_max_image_size(cluster_size, table_size)); - return -EINVAL; + ret = -EINVAL; + goto finish; } - return qed_create(filename, cluster_size, image_size, table_size, - backing_file, backing_fmt, errp); + ret = qed_create(filename, cluster_size, image_size, table_size, + backing_file, backing_fmt, errp); + +finish: + g_free(backing_file); + g_free(backing_fmt); + return ret; } typedef struct { @@ -1616,43 +1614,51 @@ static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result, return qed_check(s, result, !!fix); } -static QEMUOptionParameter qed_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size (in bytes)" - }, { - .name = BLOCK_OPT_BACKING_FILE, - .type = OPT_STRING, - .help = "File name of a base image" - }, { - .name = BLOCK_OPT_BACKING_FMT, - .type = OPT_STRING, - .help = "Image format of the base image" - }, { - .name = BLOCK_OPT_CLUSTER_SIZE, - .type = OPT_SIZE, - .help = "Cluster size (in bytes)", - .value = { .n = QED_DEFAULT_CLUSTER_SIZE }, - }, { - .name = BLOCK_OPT_TABLE_SIZE, - .type = OPT_SIZE, - .help = "L1/L2 table size (in clusters)" - }, - { /* end of list */ } +static QemuOptsList qed_create_opts = { + .name = "qed-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(qed_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_BACKING_FILE, + .type = QEMU_OPT_STRING, + .help = "File name of a base image" + }, + { + .name = BLOCK_OPT_BACKING_FMT, + .type = QEMU_OPT_STRING, + .help = "Image format of the base image" + }, + { + .name = BLOCK_OPT_CLUSTER_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Cluster size (in bytes)", + .def_value_str = stringify(QED_DEFAULT_CLUSTER_SIZE) + }, + { + .name = BLOCK_OPT_TABLE_SIZE, + .type = QEMU_OPT_SIZE, + .help = "L1/L2 table size (in clusters)" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_qed = { .format_name = "qed", .instance_size = sizeof(BDRVQEDState), - .create_options = qed_create_options, + .create_opts = &qed_create_opts, .bdrv_probe = bdrv_qed_probe, .bdrv_rebind = bdrv_qed_rebind, .bdrv_open = bdrv_qed_open, .bdrv_close = bdrv_qed_close, .bdrv_reopen_prepare = bdrv_qed_reopen_prepare, - .bdrv_create = bdrv_qed_create, + .bdrv_create2 = bdrv_qed_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = bdrv_qed_co_get_block_status, .bdrv_aio_readv = bdrv_qed_aio_readv, diff --git a/block/qed.h b/block/qed.h index 5d65bea075..b0247515da 100644 --- a/block/qed.h +++ b/block/qed.h @@ -43,7 +43,7 @@ * * All fields are little-endian on disk. */ - +#define QED_DEFAULT_CLUSTER_SIZE 65536 enum { QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24, @@ -69,7 +69,6 @@ enum { */ QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */ QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024, - QED_DEFAULT_CLUSTER_SIZE = 64 * 1024, /* Allocated clusters are tracked using a 2-level pagetable. Table size is * a multiple of clusters so large maximum image sizes can be supported From 6f482f742dd841b45297fb0e5f3d2c81779253be Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:01 +0800 Subject: [PATCH 28/39] raw-posix.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/raw-posix.c | 59 ++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index c2b30be3d3..c718e49d84 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1273,8 +1273,7 @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs) return (int64_t)st.st_blocks * 512; } -static int raw_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int raw_create(const char *filename, QemuOpts *opts, Error **errp) { int fd; int result = 0; @@ -1283,12 +1282,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, strstart(filename, "file:", &filename); /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - total_size = options->value.n / BDRV_SECTOR_SIZE; - } - options++; - } + total_size = + qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); @@ -1473,13 +1468,17 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return 0; } -static QEMUOptionParameter raw_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { NULL } +static QemuOptsList raw_create_opts = { + .name = "raw-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_file = { @@ -1494,7 +1493,7 @@ static BlockDriver bdrv_file = { .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, .bdrv_close = raw_close, - .bdrv_create = raw_create, + .bdrv_create2 = raw_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = raw_co_get_block_status, .bdrv_co_write_zeroes = raw_co_write_zeroes, @@ -1514,7 +1513,7 @@ static BlockDriver bdrv_file = { .bdrv_detach_aio_context = raw_detach_aio_context, .bdrv_attach_aio_context = raw_attach_aio_context, - .create_options = raw_create_options, + .create_opts = &raw_create_opts, }; /***********************************************/ @@ -1835,7 +1834,7 @@ static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs, return -ENOTSUP; } -static int hdev_create(const char *filename, QEMUOptionParameter *options, +static int hdev_create(const char *filename, QemuOpts *opts, Error **errp) { int fd; @@ -1856,12 +1855,8 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options, (void)has_prefix; /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, "size")) { - total_size = options->value.n / BDRV_SECTOR_SIZE; - } - options++; - } + total_size = + qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE; fd = qemu_open(filename, O_WRONLY | O_BINARY); if (fd < 0) { @@ -1898,8 +1893,8 @@ static BlockDriver bdrv_host_device = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create = hdev_create, - .create_options = raw_create_options, + .bdrv_create2 = hdev_create, + .create_opts = &raw_create_opts, .bdrv_co_write_zeroes = hdev_co_write_zeroes, .bdrv_aio_readv = raw_aio_readv, @@ -2045,8 +2040,8 @@ static BlockDriver bdrv_host_floppy = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create = hdev_create, - .create_options = raw_create_options, + .bdrv_create2 = hdev_create, + .create_opts = &raw_create_opts, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, @@ -2173,8 +2168,8 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create = hdev_create, - .create_options = raw_create_options, + .bdrv_create2 = hdev_create, + .create_opts = &raw_create_opts, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, @@ -2307,8 +2302,8 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create = hdev_create, - .create_options = raw_create_options, + .bdrv_create2 = hdev_create, + .create_opts = &raw_create_opts, .bdrv_aio_readv = raw_aio_readv, .bdrv_aio_writev = raw_aio_writev, From ddef76999396d93b2c7ddfc7e95d5c4bcdeac55a Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:02 +0800 Subject: [PATCH 29/39] raw-win32.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/raw-win32.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/block/raw-win32.c b/block/raw-win32.c index 324e8187f5..a71de70f68 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -503,8 +503,7 @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs) return st.st_size; } -static int raw_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int raw_create(const char *filename, QemuOpts *opts, Error **errp) { int fd; int64_t total_size = 0; @@ -512,12 +511,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, strstart(filename, "file:", &filename); /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - total_size = options->value.n / 512; - } - options++; - } + total_size = + qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); @@ -531,13 +526,18 @@ static int raw_create(const char *filename, QEMUOptionParameter *options, return 0; } -static QEMUOptionParameter raw_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { NULL } + +static QemuOptsList raw_create_opts = { + .name = "raw-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_file = { @@ -546,9 +546,9 @@ static BlockDriver bdrv_file = { .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, .bdrv_parse_filename = raw_parse_filename, - .bdrv_file_open = raw_open, - .bdrv_close = raw_close, - .bdrv_create = raw_create, + .bdrv_file_open = raw_open, + .bdrv_close = raw_close, + .bdrv_create2 = raw_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_aio_readv = raw_aio_readv, @@ -560,7 +560,7 @@ static BlockDriver bdrv_file = { .bdrv_get_allocated_file_size = raw_get_allocated_file_size, - .create_options = raw_create_options, + .create_opts = &raw_create_opts, }; /***********************************************/ From cd3a4cf631644636b098243fd118980100efbe01 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:03 +0800 Subject: [PATCH 30/39] raw_bsd.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/raw_bsd.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 9ae5fc21d4..ee797fd877 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -29,13 +29,17 @@ #include "block/block_int.h" #include "qemu/option.h" -static QEMUOptionParameter raw_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { 0 } +static QemuOptsList raw_create_opts = { + .name = "raw-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { /* end of list */ } + } }; static int raw_reopen_prepare(BDRVReopenState *reopen_state, @@ -139,13 +143,12 @@ static int raw_has_zero_init(BlockDriverState *bs) return bdrv_has_zero_init(bs->file); } -static int raw_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int raw_create(const char *filename, QemuOpts *opts, Error **errp) { Error *local_err = NULL; int ret; - ret = bdrv_create_file(filename, options, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, opts, &local_err); if (local_err) { error_propagate(errp, local_err); } @@ -177,7 +180,7 @@ static BlockDriver bdrv_raw = { .bdrv_reopen_prepare = &raw_reopen_prepare, .bdrv_open = &raw_open, .bdrv_close = &raw_close, - .bdrv_create = &raw_create, + .bdrv_create2 = &raw_create, .bdrv_co_readv = &raw_co_readv, .bdrv_co_writev = &raw_co_writev, .bdrv_co_write_zeroes = &raw_co_write_zeroes, @@ -194,7 +197,7 @@ static BlockDriver bdrv_raw = { .bdrv_lock_medium = &raw_lock_medium, .bdrv_ioctl = &raw_ioctl, .bdrv_aio_ioctl = &raw_aio_ioctl, - .create_options = &raw_create_options[0], + .create_opts = &raw_create_opts, .bdrv_has_zero_init = &raw_has_zero_init }; From bd0cf596fd1200d162e5655adff9c06d40dbdd14 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:04 +0800 Subject: [PATCH 31/39] rbd.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/rbd.c | 63 +++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/block/rbd.c b/block/rbd.c index 93639f783c..e15d3129a5 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -289,8 +289,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf, Error **errp) return ret; } -static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp) { Error *local_err = NULL; int64_t bytes = 0; @@ -315,24 +314,18 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options, } /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - bytes = options->value.n; - } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { - if (options->value.n) { - objsize = options->value.n; - if ((objsize - 1) & objsize) { /* not a power of 2? */ - error_setg(errp, "obj size needs to be power of 2"); - return -EINVAL; - } - if (objsize < 4096) { - error_setg(errp, "obj size too small"); - return -EINVAL; - } - obj_order = ffs(objsize) - 1; - } + bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); + objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0); + if (objsize) { + if ((objsize - 1) & objsize) { /* not a power of 2? */ + error_setg(errp, "obj size needs to be power of 2"); + return -EINVAL; } - options++; + if (objsize < 4096) { + error_setg(errp, "obj size too small"); + return -EINVAL; + } + obj_order = ffs(objsize) - 1; } clientname = qemu_rbd_parse_clientname(conf, clientname_buf); @@ -911,18 +904,22 @@ static BlockDriverAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs, } #endif -static QEMUOptionParameter qemu_rbd_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_CLUSTER_SIZE, - .type = OPT_SIZE, - .help = "RBD object size" - }, - {NULL} +static QemuOptsList qemu_rbd_create_opts = { + .name = "rbd-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(qemu_rbd_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_CLUSTER_SIZE, + .type = QEMU_OPT_SIZE, + .help = "RBD object size" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_rbd = { @@ -931,10 +928,10 @@ static BlockDriver bdrv_rbd = { .bdrv_needs_filename = true, .bdrv_file_open = qemu_rbd_open, .bdrv_close = qemu_rbd_close, - .bdrv_create = qemu_rbd_create, + .bdrv_create2 = qemu_rbd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_get_info = qemu_rbd_getinfo, - .create_options = qemu_rbd_create_options, + .create_opts = &qemu_rbd_create_opts, .bdrv_getlength = qemu_rbd_getlength, .bdrv_truncate = qemu_rbd_truncate, .protocol_name = "rbd", From b222237b7bcddc337625201159d9ddbb096043bf Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:05 +0800 Subject: [PATCH 32/39] sheepdog.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/sheepdog.c | 111 ++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 1fa19399f0..07c467d010 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1670,12 +1670,13 @@ static int parse_redundancy(BDRVSheepdogState *s, const char *opt) return 0; } -static int sd_create(const char *filename, QEMUOptionParameter *options, +static int sd_create(const char *filename, QemuOpts *opts, Error **errp) { int ret = 0; uint32_t vid = 0; char *backing_file = NULL; + char *buf = NULL; BDRVSheepdogState *s; char tag[SD_MAX_VDI_TAG_LEN]; uint32_t snapid; @@ -1694,33 +1695,27 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, goto out; } - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - s->inode.vdi_size = options->value.n; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { - backing_file = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) { - if (!options->value.s || !strcmp(options->value.s, "off")) { - prealloc = false; - } else if (!strcmp(options->value.s, "full")) { - prealloc = true; - } else { - error_setg(errp, "Invalid preallocation mode: '%s'", - options->value.s); - ret = -EINVAL; - goto out; - } - } else if (!strcmp(options->name, BLOCK_OPT_REDUNDANCY)) { - if (options->value.s) { - ret = parse_redundancy(s, options->value.s); - if (ret < 0) { - error_setg(errp, "Invalid redundancy mode: '%s'", - options->value.s); - goto out; - } - } + s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); + backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); + buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); + if (!buf || !strcmp(buf, "off")) { + prealloc = false; + } else if (!strcmp(buf, "full")) { + prealloc = true; + } else { + error_setg(errp, "Invalid preallocation mode: '%s'", buf); + ret = -EINVAL; + goto out; + } + + g_free(buf); + buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY); + if (buf) { + ret = parse_redundancy(s, buf); + if (ret < 0) { + error_setg(errp, "Invalid redundancy mode: '%s'", buf); + goto out; } - options++; } if (s->inode.vdi_size > SD_MAX_VDI_SIZE) { @@ -1770,6 +1765,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options, ret = sd_prealloc(filename, errp); } out: + g_free(backing_file); + g_free(buf); g_free(s); return ret; } @@ -2571,28 +2568,32 @@ static int64_t sd_get_allocated_file_size(BlockDriverState *bs) return size; } -static QEMUOptionParameter sd_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_BACKING_FILE, - .type = OPT_STRING, - .help = "File name of a base image" - }, - { - .name = BLOCK_OPT_PREALLOC, - .type = OPT_STRING, - .help = "Preallocation mode (allowed values: off, full)" - }, - { - .name = BLOCK_OPT_REDUNDANCY, - .type = OPT_STRING, - .help = "Redundancy of the image" - }, - { NULL } +static QemuOptsList sd_create_opts = { + .name = "sheepdog-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(sd_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_BACKING_FILE, + .type = QEMU_OPT_STRING, + .help = "File name of a base image" + }, + { + .name = BLOCK_OPT_PREALLOC, + .type = QEMU_OPT_STRING, + .help = "Preallocation mode (allowed values: off, full)" + }, + { + .name = BLOCK_OPT_REDUNDANCY, + .type = QEMU_OPT_STRING, + .help = "Redundancy of the image" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_sheepdog = { @@ -2602,7 +2603,7 @@ static BlockDriver bdrv_sheepdog = { .bdrv_needs_filename = true, .bdrv_file_open = sd_open, .bdrv_close = sd_close, - .bdrv_create = sd_create, + .bdrv_create2 = sd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, @@ -2625,7 +2626,7 @@ static BlockDriver bdrv_sheepdog = { .bdrv_detach_aio_context = sd_detach_aio_context, .bdrv_attach_aio_context = sd_attach_aio_context, - .create_options = sd_create_options, + .create_opts = &sd_create_opts, }; static BlockDriver bdrv_sheepdog_tcp = { @@ -2635,7 +2636,7 @@ static BlockDriver bdrv_sheepdog_tcp = { .bdrv_needs_filename = true, .bdrv_file_open = sd_open, .bdrv_close = sd_close, - .bdrv_create = sd_create, + .bdrv_create2 = sd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, @@ -2658,7 +2659,7 @@ static BlockDriver bdrv_sheepdog_tcp = { .bdrv_detach_aio_context = sd_detach_aio_context, .bdrv_attach_aio_context = sd_attach_aio_context, - .create_options = sd_create_options, + .create_opts = &sd_create_opts, }; static BlockDriver bdrv_sheepdog_unix = { @@ -2668,7 +2669,7 @@ static BlockDriver bdrv_sheepdog_unix = { .bdrv_needs_filename = true, .bdrv_file_open = sd_open, .bdrv_close = sd_close, - .bdrv_create = sd_create, + .bdrv_create2 = sd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, @@ -2691,7 +2692,7 @@ static BlockDriver bdrv_sheepdog_unix = { .bdrv_detach_aio_context = sd_detach_aio_context, .bdrv_attach_aio_context = sd_attach_aio_context, - .create_options = sd_create_options, + .create_opts = &sd_create_opts, }; static void bdrv_sheepdog_init(void) From 766181fe5789da07ff1fe76986e63f91ccdc2c65 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:06 +0800 Subject: [PATCH 33/39] ssh.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/ssh.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/block/ssh.c b/block/ssh.c index 9779eac2bd..9696c2bc1f 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -675,17 +675,20 @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags, return ret; } -static QEMUOptionParameter ssh_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { NULL } +static QemuOptsList ssh_create_opts = { + .name = "ssh-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { /* end of list */ } + } }; -static int ssh_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int ssh_create(const char *filename, QemuOpts *opts, Error **errp) { int r, ret; int64_t total_size = 0; @@ -697,12 +700,7 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options, ssh_state_init(&s); /* Get desired file size. */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - total_size = options->value.n; - } - options++; - } + total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); DPRINTF("total_size=%" PRIi64, total_size); uri_options = qdict_new(); @@ -1077,14 +1075,14 @@ static BlockDriver bdrv_ssh = { .instance_size = sizeof(BDRVSSHState), .bdrv_parse_filename = ssh_parse_filename, .bdrv_file_open = ssh_file_open, - .bdrv_create = ssh_create, + .bdrv_create2 = ssh_create, .bdrv_close = ssh_close, .bdrv_has_zero_init = ssh_has_zero_init, .bdrv_co_readv = ssh_co_readv, .bdrv_co_writev = ssh_co_writev, .bdrv_getlength = ssh_getlength, .bdrv_co_flush_to_disk = ssh_co_flush, - .create_options = ssh_create_options, + .create_opts = &ssh_create_opts, }; static void bdrv_ssh_init(void) From 004b7f2522368a8cb64bfb18b904acee99e12838 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:07 +0800 Subject: [PATCH 34/39] vdi.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/vdi.c | 73 +++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/block/vdi.c b/block/vdi.c index 1b2be1af7b..31d9b3ce44 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -672,8 +672,7 @@ static int vdi_co_write(BlockDriverState *bs, return ret; } -static int vdi_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) { int fd; int result = 0; @@ -688,25 +687,18 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options, logout("\n"); /* Read out options. */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - bytes = options->value.n; + bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); #if defined(CONFIG_VDI_BLOCK_SIZE) - } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) { - if (options->value.n) { - /* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */ - block_size = options->value.n; - } + /* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */ + block_size = qemu_opt_get_size_del(opts, + BLOCK_OPT_CLUSTER_SIZE, + DEFAULT_CLUSTER_SIZE); #endif #if defined(CONFIG_VDI_STATIC_IMAGE) - } else if (!strcmp(options->name, BLOCK_OPT_STATIC)) { - if (options->value.n) { - image_type = VDI_TYPE_STATIC; - } -#endif - } - options++; + if (qemu_opt_get_bool_del(opts, BLOCK_OPT_STATIC, false)) { + image_type = VDI_TYPE_STATIC; } +#endif if (bytes > VDI_DISK_SIZE_MAX) { result = -ENOTSUP; @@ -801,29 +793,34 @@ static void vdi_close(BlockDriverState *bs) error_free(s->migration_blocker); } -static QEMUOptionParameter vdi_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, +static QemuOptsList vdi_create_opts = { + .name = "vdi-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(vdi_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, #if defined(CONFIG_VDI_BLOCK_SIZE) - { - .name = BLOCK_OPT_CLUSTER_SIZE, - .type = OPT_SIZE, - .help = "VDI cluster (block) size", - .value = { .n = DEFAULT_CLUSTER_SIZE }, - }, + { + .name = BLOCK_OPT_CLUSTER_SIZE, + .type = QEMU_OPT_SIZE, + .help = "VDI cluster (block) size", + .def_value_str = stringify(DEFAULT_CLUSTER_SIZE) + }, #endif #if defined(CONFIG_VDI_STATIC_IMAGE) - { - .name = BLOCK_OPT_STATIC, - .type = OPT_FLAG, - .help = "VDI static (pre-allocated) image" - }, + { + .name = BLOCK_OPT_STATIC, + .type = QEMU_OPT_BOOL, + .help = "VDI static (pre-allocated) image", + .def_value_str = "off" + }, #endif - /* TODO: An additional option to set UUID values might be useful. */ - { NULL } + /* TODO: An additional option to set UUID values might be useful. */ + { /* end of list */ } + } }; static BlockDriver bdrv_vdi = { @@ -833,7 +830,7 @@ static BlockDriver bdrv_vdi = { .bdrv_open = vdi_open, .bdrv_close = vdi_close, .bdrv_reopen_prepare = vdi_reopen_prepare, - .bdrv_create = vdi_create, + .bdrv_create2 = vdi_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = vdi_co_get_block_status, .bdrv_make_empty = vdi_make_empty, @@ -845,7 +842,7 @@ static BlockDriver bdrv_vdi = { .bdrv_get_info = vdi_get_info, - .create_options = vdi_create_options, + .create_opts = &vdi_create_opts, .bdrv_check = vdi_check, }; From 5366092c7acae8d7d5a8188c06933deffdca6e44 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:08 +0800 Subject: [PATCH 35/39] vhdx.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/vhdx.c | 99 +++++++++++++++++++++++++--------------------------- block/vhdx.h | 1 + 2 files changed, 48 insertions(+), 52 deletions(-) diff --git a/block/vhdx.c b/block/vhdx.c index ca7d533948..e36f897953 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1723,8 +1723,7 @@ exit: * .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------. * 1MB */ -static int vhdx_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp) { int ret = 0; uint64_t image_size = (uint64_t) 2 * GiB; @@ -1737,24 +1736,15 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options, gunichar2 *creator = NULL; glong creator_items; BlockDriverState *bs; - const char *type = NULL; + char *type = NULL; VHDXImageType image_type; Error *local_err = NULL; - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - image_size = options->value.n; - } else if (!strcmp(options->name, VHDX_BLOCK_OPT_LOG_SIZE)) { - log_size = options->value.n; - } else if (!strcmp(options->name, VHDX_BLOCK_OPT_BLOCK_SIZE)) { - block_size = options->value.n; - } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) { - type = options->value.s; - } else if (!strcmp(options->name, VHDX_BLOCK_OPT_ZERO)) { - use_zero_blocks = options->value.n != 0; - } - options++; - } + image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); + log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0); + block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0); + type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT); + use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, false); if (image_size > VHDX_MAX_IMAGE_SIZE) { error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB"); @@ -1763,7 +1753,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options, } if (type == NULL) { - type = "dynamic"; + type = g_strdup("dynamic"); } if (!strcmp(type, "dynamic")) { @@ -1803,7 +1793,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, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); goto exit; @@ -1863,6 +1853,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options, delete_and_exit: bdrv_unref(bs); exit: + g_free(type); g_free(creator); return ret; } @@ -1885,37 +1876,41 @@ static int vhdx_check(BlockDriverState *bs, BdrvCheckResult *result, return 0; } -static QEMUOptionParameter vhdx_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size; max of 64TB." - }, - { - .name = VHDX_BLOCK_OPT_LOG_SIZE, - .type = OPT_SIZE, - .value.n = 1 * MiB, - .help = "Log size; min 1MB." - }, - { - .name = VHDX_BLOCK_OPT_BLOCK_SIZE, - .type = OPT_SIZE, - .value.n = 0, - .help = "Block Size; min 1MB, max 256MB. " \ - "0 means auto-calculate based on image size." - }, - { - .name = BLOCK_OPT_SUBFMT, - .type = OPT_STRING, - .help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\ - "Default is 'dynamic'." - }, - { - .name = VHDX_BLOCK_OPT_ZERO, - .type = OPT_FLAG, - .help = "Force use of payload blocks of type 'ZERO'. Non-standard." - }, - { NULL } +static QemuOptsList vhdx_create_opts = { + .name = "vhdx-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(vhdx_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size; max of 64TB." + }, + { + .name = VHDX_BLOCK_OPT_LOG_SIZE, + .type = QEMU_OPT_SIZE, + .def_value_str = stringify(DEFAULT_LOG_SIZE), + .help = "Log size; min 1MB." + }, + { + .name = VHDX_BLOCK_OPT_BLOCK_SIZE, + .type = QEMU_OPT_SIZE, + .def_value_str = stringify(0), + .help = "Block Size; min 1MB, max 256MB. " \ + "0 means auto-calculate based on image size." + }, + { + .name = BLOCK_OPT_SUBFMT, + .type = QEMU_OPT_STRING, + .help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\ + "Default is 'dynamic'." + }, + { + .name = VHDX_BLOCK_OPT_ZERO, + .type = QEMU_OPT_BOOL, + .help = "Force use of payload blocks of type 'ZERO'. Non-standard." + }, + { NULL } + } }; static BlockDriver bdrv_vhdx = { @@ -1927,11 +1922,11 @@ static BlockDriver bdrv_vhdx = { .bdrv_reopen_prepare = vhdx_reopen_prepare, .bdrv_co_readv = vhdx_co_readv, .bdrv_co_writev = vhdx_co_writev, - .bdrv_create = vhdx_create, + .bdrv_create2 = vhdx_create, .bdrv_get_info = vhdx_get_info, .bdrv_check = vhdx_check, - .create_options = vhdx_create_options, + .create_opts = &vhdx_create_opts, }; static void bdrv_vhdx_init(void) diff --git a/block/vhdx.h b/block/vhdx.h index 8103d4c446..5370010c59 100644 --- a/block/vhdx.h +++ b/block/vhdx.h @@ -23,6 +23,7 @@ #define GiB (MiB * 1024) #define TiB ((uint64_t) GiB * 1024) +#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */ /* Structures and fields present in the VHDX file */ /* The header section has the following blocks, From 5820f1da5130e2afdacd6d8886a67cf95ddc5878 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:09 +0800 Subject: [PATCH 36/39] vmdk.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/vmdk.c | 123 ++++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index b653f5ecef..d19f15b7da 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1695,17 +1695,16 @@ static int filename_decompose(const char *filename, char *path, char *prefix, return VMDK_OK; } -static int vmdk_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) { int idx = 0; BlockDriverState *new_bs = NULL; Error *local_err = NULL; char *desc = NULL; int64_t total_size = 0, filesize; - const char *adapter_type = NULL; - const char *backing_file = NULL; - const char *fmt = NULL; + char *adapter_type = NULL; + char *backing_file = NULL; + char *fmt = NULL; int flags = 0; int ret = 0; bool flat, split, compress; @@ -1745,24 +1744,19 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options, goto exit; } /* Read out options */ - while (options && options->name) { - if (!strcmp(options->name, BLOCK_OPT_SIZE)) { - total_size = options->value.n; - } else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) { - adapter_type = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) { - backing_file = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) { - flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0; - } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) { - fmt = options->value.s; - } else if (!strcmp(options->name, BLOCK_OPT_ZEROED_GRAIN)) { - zeroed_grain |= options->value.n; - } - options++; + total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); + adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE); + backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); + if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) { + flags |= BLOCK_FLAG_COMPAT6; } + fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT); + if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) { + zeroed_grain = true; + } + if (!adapter_type) { - adapter_type = "ide"; + adapter_type = g_strdup("ide"); } else if (strcmp(adapter_type, "ide") && strcmp(adapter_type, "buslogic") && strcmp(adapter_type, "lsilogic") && @@ -1778,7 +1772,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options, } if (!fmt) { /* Default format to monolithicSparse */ - fmt = "monolithicSparse"; + fmt = g_strdup("monolithicSparse"); } else if (strcmp(fmt, "monolithicFlat") && strcmp(fmt, "monolithicSparse") && strcmp(fmt, "twoGbMaxExtentSparse") && @@ -1879,7 +1873,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options, if (!split && !flat) { desc_offset = 0x200; } else { - ret = bdrv_create_file(filename, options, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); goto exit; @@ -1909,6 +1903,9 @@ exit: if (new_bs) { bdrv_unref(new_bs); } + g_free(adapter_type); + g_free(backing_file); + g_free(fmt); g_free(desc); g_string_free(ext_desc_lines, true); return ret; @@ -2117,41 +2114,47 @@ static void vmdk_attach_aio_context(BlockDriverState *bs, } } -static QEMUOptionParameter vmdk_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_ADAPTER_TYPE, - .type = OPT_STRING, - .help = "Virtual adapter type, can be one of " - "ide (default), lsilogic, buslogic or legacyESX" - }, - { - .name = BLOCK_OPT_BACKING_FILE, - .type = OPT_STRING, - .help = "File name of a base image" - }, - { - .name = BLOCK_OPT_COMPAT6, - .type = OPT_FLAG, - .help = "VMDK version 6 image" - }, - { - .name = BLOCK_OPT_SUBFMT, - .type = OPT_STRING, - .help = - "VMDK flat extent format, can be one of " - "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} " - }, - { - .name = BLOCK_OPT_ZEROED_GRAIN, - .type = OPT_FLAG, - .help = "Enable efficient zero writes using the zeroed-grain GTE feature" - }, - { NULL } +static QemuOptsList vmdk_create_opts = { + .name = "vmdk-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(vmdk_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_ADAPTER_TYPE, + .type = QEMU_OPT_STRING, + .help = "Virtual adapter type, can be one of " + "ide (default), lsilogic, buslogic or legacyESX" + }, + { + .name = BLOCK_OPT_BACKING_FILE, + .type = QEMU_OPT_STRING, + .help = "File name of a base image" + }, + { + .name = BLOCK_OPT_COMPAT6, + .type = QEMU_OPT_BOOL, + .help = "VMDK version 6 image", + .def_value_str = "off" + }, + { + .name = BLOCK_OPT_SUBFMT, + .type = QEMU_OPT_STRING, + .help = + "VMDK flat extent format, can be one of " + "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} " + }, + { + .name = BLOCK_OPT_ZEROED_GRAIN, + .type = QEMU_OPT_BOOL, + .help = "Enable efficient zero writes " + "using the zeroed-grain GTE feature" + }, + { /* end of list */ } + } }; static BlockDriver bdrv_vmdk = { @@ -2166,7 +2169,7 @@ static BlockDriver bdrv_vmdk = { .bdrv_write_compressed = vmdk_write_compressed, .bdrv_co_write_zeroes = vmdk_co_write_zeroes, .bdrv_close = vmdk_close, - .bdrv_create = vmdk_create, + .bdrv_create2 = vmdk_create, .bdrv_co_flush_to_disk = vmdk_co_flush, .bdrv_co_get_block_status = vmdk_co_get_block_status, .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size, @@ -2177,7 +2180,7 @@ static BlockDriver bdrv_vmdk = { .bdrv_detach_aio_context = vmdk_detach_aio_context, .bdrv_attach_aio_context = vmdk_attach_aio_context, - .create_options = vmdk_create_options, + .create_opts = &vmdk_create_opts, }; static void bdrv_vmdk_init(void) From fec9921f0a331716c898d1f823682de2ecfa3d2a Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:10 +0800 Subject: [PATCH 37/39] vpc.c: replace QEMUOptionParameter with QemuOpts Reviewed-by: Stefan Hajnoczi Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block/vpc.c | 62 +++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/block/vpc.c b/block/vpc.c index 2e25f57230..8ebf424037 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -738,12 +738,11 @@ static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size) return ret; } -static int vpc_create(const char *filename, QEMUOptionParameter *options, - Error **errp) +static int vpc_create(const char *filename, QemuOpts *opts, Error **errp) { uint8_t buf[1024]; VHDFooter *footer = (VHDFooter *) buf; - QEMUOptionParameter *disk_type_param; + char *disk_type_param; int fd, i; uint16_t cyls = 0; uint8_t heads = 0; @@ -754,16 +753,16 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options, int ret = -EIO; /* Read out options */ - total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n; - - disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT); - if (disk_type_param && disk_type_param->value.s) { - if (!strcmp(disk_type_param->value.s, "dynamic")) { + total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0); + disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT); + if (disk_type_param) { + if (!strcmp(disk_type_param, "dynamic")) { disk_type = VHD_DYNAMIC; - } else if (!strcmp(disk_type_param->value.s, "fixed")) { + } else if (!strcmp(disk_type_param, "fixed")) { disk_type = VHD_FIXED; } else { - return -EINVAL; + ret = -EINVAL; + goto out; } } else { disk_type = VHD_DYNAMIC; @@ -772,7 +771,8 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options, /* Create the file */ fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (fd < 0) { - return -EIO; + ret = -EIO; + goto out; } /* @@ -837,8 +837,10 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options, ret = create_fixed_disk(fd, buf, total_size); } - fail: +fail: qemu_close(fd); +out: + g_free(disk_type_param); return ret; } @@ -866,20 +868,24 @@ static void vpc_close(BlockDriverState *bs) error_free(s->migration_blocker); } -static QEMUOptionParameter vpc_create_options[] = { - { - .name = BLOCK_OPT_SIZE, - .type = OPT_SIZE, - .help = "Virtual disk size" - }, - { - .name = BLOCK_OPT_SUBFMT, - .type = OPT_STRING, - .help = - "Type of virtual hard disk format. Supported formats are " - "{dynamic (default) | fixed} " - }, - { NULL } +static QemuOptsList vpc_create_opts = { + .name = "vpc-create-opts", + .head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head), + .desc = { + { + .name = BLOCK_OPT_SIZE, + .type = QEMU_OPT_SIZE, + .help = "Virtual disk size" + }, + { + .name = BLOCK_OPT_SUBFMT, + .type = QEMU_OPT_STRING, + .help = + "Type of virtual hard disk format. Supported formats are " + "{dynamic (default) | fixed} " + }, + { /* end of list */ } + } }; static BlockDriver bdrv_vpc = { @@ -890,14 +896,14 @@ static BlockDriver bdrv_vpc = { .bdrv_open = vpc_open, .bdrv_close = vpc_close, .bdrv_reopen_prepare = vpc_reopen_prepare, - .bdrv_create = vpc_create, + .bdrv_create2 = vpc_create, .bdrv_read = vpc_co_read, .bdrv_write = vpc_co_write, .bdrv_get_info = vpc_get_info, - .create_options = vpc_create_options, + .create_opts = &vpc_create_opts, .bdrv_has_zero_init = vpc_has_zero_init, }; From c282e1fdf7ec9659c7f320123be397477a359d01 Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:11 +0800 Subject: [PATCH 38/39] cleanup QEMUOptionParameter Now that all backend drivers are using QemuOpts, remove all QEMUOptionParameter related codes. Signed-off-by: Dong Xu Wang Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- block.c | 93 ++------- block/cow.c | 4 +- block/gluster.c | 8 +- block/iscsi.c | 2 +- block/nfs.c | 2 +- block/qcow.c | 4 +- block/qcow2.c | 6 +- block/qed.c | 4 +- block/raw-posix.c | 10 +- block/raw-win32.c | 2 +- block/raw_bsd.c | 4 +- block/rbd.c | 2 +- block/sheepdog.c | 6 +- block/ssh.c | 2 +- block/vdi.c | 2 +- block/vhdx.c | 4 +- block/vmdk.c | 6 +- block/vpc.c | 2 +- block/vvfat.c | 14 +- include/block/block.h | 8 +- include/block/block_int.h | 18 +- include/qemu/option.h | 48 +---- qemu-img.c | 19 +- util/qemu-option.c | 427 +------------------------------------- 24 files changed, 67 insertions(+), 630 deletions(-) diff --git a/block.c b/block.c index 3dd2194515..43abe96db6 100644 --- a/block.c +++ b/block.c @@ -329,13 +329,6 @@ void bdrv_register(BlockDriver *bdrv) } } - if (bdrv->bdrv_create) { - assert(!bdrv->bdrv_create2 && !bdrv->create_opts); - assert(!bdrv->bdrv_amend_options2); - } else if (bdrv->bdrv_create2) { - assert(!bdrv->bdrv_create && !bdrv->create_options); - assert(!bdrv->bdrv_amend_options); - } QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list); } @@ -431,7 +424,6 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name, typedef struct CreateCo { BlockDriver *drv; char *filename; - QEMUOptionParameter *options; QemuOpts *opts; int ret; Error *err; @@ -444,28 +436,8 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque) CreateCo *cco = opaque; assert(cco->drv); - assert(!(cco->options && cco->opts)); - if (cco->drv->bdrv_create2) { - QemuOptsList *opts_list = NULL; - if (cco->options) { - opts_list = params_to_opts(cco->options); - cco->opts = qemu_opts_create(opts_list, NULL, 0, &error_abort); - } - ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err); - if (cco->options) { - qemu_opts_del(cco->opts); - qemu_opts_free(opts_list); - } - } else { - if (cco->opts) { - cco->options = opts_to_params(cco->opts); - } - ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err); - if (cco->opts) { - free_option_parameters(cco->options); - } - } + ret = cco->drv->bdrv_create(cco->filename, cco->opts, &local_err); if (local_err) { error_propagate(&cco->err, local_err); } @@ -473,7 +445,6 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque) } int bdrv_create(BlockDriver *drv, const char* filename, - QEMUOptionParameter *options, QemuOpts *opts, Error **errp) { int ret; @@ -482,13 +453,12 @@ int bdrv_create(BlockDriver *drv, const char* filename, CreateCo cco = { .drv = drv, .filename = g_strdup(filename), - .options = options, .opts = opts, .ret = NOT_DONE, .err = NULL, }; - if (!drv->bdrv_create && !drv->bdrv_create2) { + if (!drv->bdrv_create) { error_setg(errp, "Driver '%s' does not support image creation", drv->format_name); ret = -ENOTSUP; goto out; @@ -519,8 +489,7 @@ out: return ret; } -int bdrv_create_file(const char* filename, QEMUOptionParameter *options, - QemuOpts *opts, Error **errp) +int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp) { BlockDriver *drv; Error *local_err = NULL; @@ -532,7 +501,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options, return -ENOENT; } - ret = bdrv_create(drv, filename, options, opts, &local_err); + ret = bdrv_create(drv, filename, opts, &local_err); if (local_err) { error_propagate(errp, local_err); } @@ -1277,7 +1246,6 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) char *tmp_filename = g_malloc0(PATH_MAX + 1); int64_t total_size; BlockDriver *bdrv_qcow2; - QemuOptsList *create_opts = NULL; QemuOpts *opts = NULL; QDict *snapshot_options; BlockDriverState *bs_snapshot; @@ -1303,20 +1271,11 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) } bdrv_qcow2 = bdrv_find_format("qcow2"); - - assert(!(bdrv_qcow2->create_options && bdrv_qcow2->create_opts)); - if (bdrv_qcow2->create_options) { - create_opts = params_to_opts(bdrv_qcow2->create_options); - } else { - create_opts = bdrv_qcow2->create_opts; - } - opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); + opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0, + &error_abort); qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size); - ret = bdrv_create(bdrv_qcow2, tmp_filename, NULL, opts, &local_err); + ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err); qemu_opts_del(opts); - if (bdrv_qcow2->create_options) { - qemu_opts_free(create_opts); - } if (ret < 0) { error_setg_errno(errp, -ret, "Could not create temporary overlay " "'%s': %s", tmp_filename, @@ -5579,10 +5538,8 @@ void bdrv_img_create(const char *filename, const char *fmt, return; } - create_opts = qemu_opts_append(create_opts, drv->create_opts, - drv->create_options); - create_opts = qemu_opts_append(create_opts, proto_drv->create_opts, - proto_drv->create_options); + 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); @@ -5675,7 +5632,7 @@ void bdrv_img_create(const char *filename, const char *fmt, puts(""); } - ret = bdrv_create(drv, filename, NULL, opts, &local_err); + ret = bdrv_create(drv, filename, opts, &local_err); if (ret == -EFBIG) { /* This is generally a better message than whatever the driver would @@ -5769,36 +5726,12 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs, notifier_with_return_list_add(&bs->before_write_notifiers, notifier); } -int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options, - QemuOpts *opts) +int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts) { - int ret; - assert(!(options && opts)); - - if (!bs->drv->bdrv_amend_options && !bs->drv->bdrv_amend_options2) { + if (!bs->drv->bdrv_amend_options) { return -ENOTSUP; } - if (bs->drv->bdrv_amend_options2) { - QemuOptsList *opts_list = NULL; - if (options) { - opts_list = params_to_opts(options); - opts = qemu_opts_create(opts_list, NULL, 0, &error_abort); - } - ret = bs->drv->bdrv_amend_options2(bs, opts); - if (options) { - qemu_opts_del(opts); - qemu_opts_free(opts_list); - } - } else { - if (opts) { - options = opts_to_params(opts); - } - ret = bs->drv->bdrv_amend_options(bs, options); - if (opts) { - free_option_parameters(options); - } - } - return ret; + return bs->drv->bdrv_amend_options(bs, opts); } /* This function will be called by the bdrv_recurse_is_first_non_filter method diff --git a/block/cow.c b/block/cow.c index af8575334a..a05a92cada 100644 --- a/block/cow.c +++ b/block/cow.c @@ -338,7 +338,7 @@ static int cow_create(const char *filename, QemuOpts *opts, Error **errp) image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512; image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); - ret = bdrv_create_file(filename, NULL, opts, &local_err); + ret = bdrv_create_file(filename, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); goto exit; @@ -412,7 +412,7 @@ static BlockDriver bdrv_cow = { .bdrv_probe = cow_probe, .bdrv_open = cow_open, .bdrv_close = cow_close, - .bdrv_create2 = cow_create, + .bdrv_create = cow_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_read = cow_co_read, diff --git a/block/gluster.c b/block/gluster.c index 5ff282bd74..9274dead7d 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -725,7 +725,7 @@ static BlockDriver bdrv_gluster = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create2 = qemu_gluster_create, + .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, @@ -752,7 +752,7 @@ static BlockDriver bdrv_gluster_tcp = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create2 = qemu_gluster_create, + .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, @@ -779,7 +779,7 @@ static BlockDriver bdrv_gluster_unix = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create2 = qemu_gluster_create, + .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, @@ -806,7 +806,7 @@ static BlockDriver bdrv_gluster_rdma = { .bdrv_reopen_commit = qemu_gluster_reopen_commit, .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, - .bdrv_create2 = qemu_gluster_create, + .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, .bdrv_get_allocated_file_size = qemu_gluster_allocated_file_size, .bdrv_truncate = qemu_gluster_truncate, diff --git a/block/iscsi.c b/block/iscsi.c index 626b7df7fd..6f87605e72 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1605,7 +1605,7 @@ static BlockDriver bdrv_iscsi = { .bdrv_needs_filename = true, .bdrv_file_open = iscsi_open, .bdrv_close = iscsi_close, - .bdrv_create2 = iscsi_create, + .bdrv_create = iscsi_create, .create_opts = &iscsi_create_opts, .bdrv_reopen_prepare = iscsi_reopen_prepare, diff --git a/block/nfs.c b/block/nfs.c index 35e5008ead..ec43201817 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -457,7 +457,7 @@ static BlockDriver bdrv_nfs = { .bdrv_file_open = nfs_file_open, .bdrv_close = nfs_file_close, - .bdrv_create2 = nfs_file_create, + .bdrv_create = nfs_file_create, .bdrv_co_readv = nfs_co_readv, .bdrv_co_writev = nfs_co_writev, diff --git a/block/qcow.c b/block/qcow.c index bcacfb852f..1f2bac8a5f 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -712,7 +712,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) flags |= BLOCK_FLAG_ENCRYPT; } - ret = bdrv_create_file(filename, NULL, opts, &local_err); + ret = bdrv_create_file(filename, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); goto cleanup; @@ -939,7 +939,7 @@ static BlockDriver bdrv_qcow = { .bdrv_open = qcow_open, .bdrv_close = qcow_close, .bdrv_reopen_prepare = qcow_reopen_prepare, - .bdrv_create2 = qcow_create, + .bdrv_create = qcow_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_readv = qcow_co_readv, diff --git a/block/qcow2.c b/block/qcow2.c index 7150df66d6..b9d2fa6632 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1627,7 +1627,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, Error *local_err = NULL; int ret; - ret = bdrv_create_file(filename, NULL, opts, &local_err); + ret = bdrv_create_file(filename, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); return ret; @@ -2393,7 +2393,7 @@ static BlockDriver bdrv_qcow2 = { .bdrv_open = qcow2_open, .bdrv_close = qcow2_close, .bdrv_reopen_prepare = qcow2_reopen_prepare, - .bdrv_create2 = qcow2_create, + .bdrv_create = qcow2_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = qcow2_co_get_block_status, .bdrv_set_key = qcow2_set_key, @@ -2425,7 +2425,7 @@ static BlockDriver bdrv_qcow2 = { .create_opts = &qcow2_create_opts, .bdrv_check = qcow2_check, - .bdrv_amend_options2 = qcow2_amend_options, + .bdrv_amend_options = qcow2_amend_options, }; static void bdrv_qcow2_init(void) diff --git a/block/qed.c b/block/qed.c index 7c4276e97c..092e6fb1d2 100644 --- a/block/qed.c +++ b/block/qed.c @@ -586,7 +586,7 @@ static int qed_create(const char *filename, uint32_t cluster_size, int ret = 0; BlockDriverState *bs; - ret = bdrv_create_file(filename, NULL, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, &local_err); if (ret < 0) { error_propagate(errp, local_err); return ret; @@ -1658,7 +1658,7 @@ static BlockDriver bdrv_qed = { .bdrv_open = bdrv_qed_open, .bdrv_close = bdrv_qed_close, .bdrv_reopen_prepare = bdrv_qed_reopen_prepare, - .bdrv_create2 = bdrv_qed_create, + .bdrv_create = bdrv_qed_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = bdrv_qed_co_get_block_status, .bdrv_aio_readv = bdrv_qed_aio_readv, diff --git a/block/raw-posix.c b/block/raw-posix.c index c718e49d84..dacf4fbbc8 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1493,7 +1493,7 @@ static BlockDriver bdrv_file = { .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, .bdrv_close = raw_close, - .bdrv_create2 = raw_create, + .bdrv_create = raw_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = raw_co_get_block_status, .bdrv_co_write_zeroes = raw_co_write_zeroes, @@ -1893,7 +1893,7 @@ static BlockDriver bdrv_host_device = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create2 = hdev_create, + .bdrv_create = hdev_create, .create_opts = &raw_create_opts, .bdrv_co_write_zeroes = hdev_co_write_zeroes, @@ -2040,7 +2040,7 @@ static BlockDriver bdrv_host_floppy = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create2 = hdev_create, + .bdrv_create = hdev_create, .create_opts = &raw_create_opts, .bdrv_aio_readv = raw_aio_readv, @@ -2168,7 +2168,7 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create2 = hdev_create, + .bdrv_create = hdev_create, .create_opts = &raw_create_opts, .bdrv_aio_readv = raw_aio_readv, @@ -2302,7 +2302,7 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_abort = raw_reopen_abort, - .bdrv_create2 = hdev_create, + .bdrv_create = hdev_create, .create_opts = &raw_create_opts, .bdrv_aio_readv = raw_aio_readv, diff --git a/block/raw-win32.c b/block/raw-win32.c index a71de70f68..902eab6100 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -548,7 +548,7 @@ static BlockDriver bdrv_file = { .bdrv_parse_filename = raw_parse_filename, .bdrv_file_open = raw_open, .bdrv_close = raw_close, - .bdrv_create2 = raw_create, + .bdrv_create = raw_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_aio_readv = raw_aio_readv, diff --git a/block/raw_bsd.c b/block/raw_bsd.c index ee797fd877..492f58de69 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -148,7 +148,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) Error *local_err = NULL; int ret; - ret = bdrv_create_file(filename, NULL, opts, &local_err); + ret = bdrv_create_file(filename, opts, &local_err); if (local_err) { error_propagate(errp, local_err); } @@ -180,7 +180,7 @@ static BlockDriver bdrv_raw = { .bdrv_reopen_prepare = &raw_reopen_prepare, .bdrv_open = &raw_open, .bdrv_close = &raw_close, - .bdrv_create2 = &raw_create, + .bdrv_create = &raw_create, .bdrv_co_readv = &raw_co_readv, .bdrv_co_writev = &raw_co_writev, .bdrv_co_write_zeroes = &raw_co_write_zeroes, diff --git a/block/rbd.c b/block/rbd.c index e15d3129a5..2b797d3e8b 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -928,7 +928,7 @@ static BlockDriver bdrv_rbd = { .bdrv_needs_filename = true, .bdrv_file_open = qemu_rbd_open, .bdrv_close = qemu_rbd_close, - .bdrv_create2 = qemu_rbd_create, + .bdrv_create = qemu_rbd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_get_info = qemu_rbd_getinfo, .create_opts = &qemu_rbd_create_opts, diff --git a/block/sheepdog.c b/block/sheepdog.c index 07c467d010..2dcc5959f4 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2603,7 +2603,7 @@ static BlockDriver bdrv_sheepdog = { .bdrv_needs_filename = true, .bdrv_file_open = sd_open, .bdrv_close = sd_close, - .bdrv_create2 = sd_create, + .bdrv_create = sd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, @@ -2636,7 +2636,7 @@ static BlockDriver bdrv_sheepdog_tcp = { .bdrv_needs_filename = true, .bdrv_file_open = sd_open, .bdrv_close = sd_close, - .bdrv_create2 = sd_create, + .bdrv_create = sd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, @@ -2669,7 +2669,7 @@ static BlockDriver bdrv_sheepdog_unix = { .bdrv_needs_filename = true, .bdrv_file_open = sd_open, .bdrv_close = sd_close, - .bdrv_create2 = sd_create, + .bdrv_create = sd_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_getlength = sd_getlength, .bdrv_get_allocated_file_size = sd_get_allocated_file_size, diff --git a/block/ssh.c b/block/ssh.c index 9696c2bc1f..cd2fd751fe 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -1075,7 +1075,7 @@ static BlockDriver bdrv_ssh = { .instance_size = sizeof(BDRVSSHState), .bdrv_parse_filename = ssh_parse_filename, .bdrv_file_open = ssh_file_open, - .bdrv_create2 = ssh_create, + .bdrv_create = ssh_create, .bdrv_close = ssh_close, .bdrv_has_zero_init = ssh_has_zero_init, .bdrv_co_readv = ssh_co_readv, diff --git a/block/vdi.c b/block/vdi.c index 31d9b3ce44..01fe22ebe8 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -830,7 +830,7 @@ static BlockDriver bdrv_vdi = { .bdrv_open = vdi_open, .bdrv_close = vdi_close, .bdrv_reopen_prepare = vdi_reopen_prepare, - .bdrv_create2 = vdi_create, + .bdrv_create = vdi_create, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = vdi_co_get_block_status, .bdrv_make_empty = vdi_make_empty, diff --git a/block/vhdx.c b/block/vhdx.c index e36f897953..fedcf9f9ca 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1793,7 +1793,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp) block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX : block_size; - ret = bdrv_create_file(filename, NULL, opts, &local_err); + ret = bdrv_create_file(filename, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); goto exit; @@ -1922,7 +1922,7 @@ static BlockDriver bdrv_vhdx = { .bdrv_reopen_prepare = vhdx_reopen_prepare, .bdrv_co_readv = vhdx_co_readv, .bdrv_co_writev = vhdx_co_writev, - .bdrv_create2 = vhdx_create, + .bdrv_create = vhdx_create, .bdrv_get_info = vhdx_get_info, .bdrv_check = vhdx_check, diff --git a/block/vmdk.c b/block/vmdk.c index d19f15b7da..83dd6fe4fb 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1539,7 +1539,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, NULL, &local_err); + ret = bdrv_create_file(filename, NULL, &local_err); if (ret < 0) { error_propagate(errp, local_err); goto exit; @@ -1873,7 +1873,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) if (!split && !flat) { desc_offset = 0x200; } else { - ret = bdrv_create_file(filename, NULL, opts, &local_err); + ret = bdrv_create_file(filename, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); goto exit; @@ -2169,7 +2169,7 @@ static BlockDriver bdrv_vmdk = { .bdrv_write_compressed = vmdk_write_compressed, .bdrv_co_write_zeroes = vmdk_co_write_zeroes, .bdrv_close = vmdk_close, - .bdrv_create2 = vmdk_create, + .bdrv_create = vmdk_create, .bdrv_co_flush_to_disk = vmdk_co_flush, .bdrv_co_get_block_status = vmdk_co_get_block_status, .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size, diff --git a/block/vpc.c b/block/vpc.c index 8ebf424037..798d8540db 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -896,7 +896,7 @@ static BlockDriver bdrv_vpc = { .bdrv_open = vpc_open, .bdrv_close = vpc_close, .bdrv_reopen_prepare = vpc_reopen_prepare, - .bdrv_create2 = vpc_create, + .bdrv_create = vpc_create, .bdrv_read = vpc_co_read, .bdrv_write = vpc_co_write, diff --git a/block/vvfat.c b/block/vvfat.c index b1ab195334..70176b1619 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2911,7 +2911,6 @@ static BlockDriver vvfat_write_target = { static int enable_write_target(BDRVVVFATState *s, Error **errp) { BlockDriver *bdrv_qcow = NULL; - QemuOptsList *create_opts = NULL; QemuOpts *opts = NULL; int ret; int size = sector2cluster(s, s->sector_count); @@ -2927,21 +2926,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp) } bdrv_qcow = bdrv_find_format("qcow"); - assert(!(bdrv_qcow->create_opts && bdrv_qcow->create_options)); - if (bdrv_qcow->create_options) { - create_opts = params_to_opts(bdrv_qcow->create_options); - } else { - create_opts = bdrv_qcow->create_opts; - } - opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); + opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort); qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512); qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:"); - ret = bdrv_create(bdrv_qcow, s->qcow_filename, NULL, opts, errp); + ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp); qemu_opts_del(opts); - if (bdrv_qcow->create_options) { - qemu_opts_free(create_opts); - } if (ret < 0) { goto err; } diff --git a/include/block/block.h b/include/block/block.h index 4312b8176e..f15b99b00b 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -204,9 +204,8 @@ 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, QemuOpts *opts, Error **errp); -int bdrv_create_file(const char* filename, QEMUOptionParameter *options, - QemuOpts *opts, Error **errp); + QemuOpts *opts, Error **errp); +int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp); BlockDriverState *bdrv_new(const char *device_name, Error **errp); void bdrv_make_anon(BlockDriverState *bs); void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old); @@ -312,8 +311,7 @@ typedef enum { int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix); -int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options, - QemuOpts *opts); +int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts); /* external snapshots */ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, diff --git a/include/block/block_int.h b/include/block/block_int.h index 8a77d79f41..7aa2213f77 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -116,10 +116,7 @@ struct BlockDriver { const uint8_t *buf, int nb_sectors); void (*bdrv_close)(BlockDriverState *bs); void (*bdrv_rebind)(BlockDriverState *bs); - int (*bdrv_create)(const char *filename, QEMUOptionParameter *options, - Error **errp); - /* FIXME: will remove the duplicate and rename back to bdrv_create later */ - int (*bdrv_create2)(const char *filename, QemuOpts *opts, Error **errp); + int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp); int (*bdrv_set_key)(BlockDriverState *bs, const char *key); int (*bdrv_make_empty)(BlockDriverState *bs); /* aio */ @@ -218,12 +215,6 @@ struct BlockDriver { BlockDriverCompletionFunc *cb, void *opaque); /* List of options for creating images, terminated by name == NULL */ - QEMUOptionParameter *create_options; - /* FIXME: will replace create_options. - * These two fields are mutually exclusive. At most one is non-NULL. - * create_options should only be set with bdrv_create, and create_opts - * should only be set with bdrv_create2. - */ QemuOptsList *create_opts; /* @@ -233,12 +224,7 @@ struct BlockDriver { int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result, BdrvCheckMode fix); - int (*bdrv_amend_options)(BlockDriverState *bs, - QEMUOptionParameter *options); - /* FIXME: will remove the duplicate and rename back to - * bdrv_amend_options later - */ - int (*bdrv_amend_options2)(BlockDriverState *bs, QemuOpts *opts); + int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts); void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event); diff --git a/include/qemu/option.h b/include/qemu/option.h index 34552678c3..921eccdb38 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -31,25 +31,6 @@ #include "qapi/error.h" #include "qapi/qmp/qdict.h" -enum QEMUOptionParType { - OPT_FLAG, - OPT_NUMBER, - OPT_SIZE, - OPT_STRING, -}; - -typedef struct QEMUOptionParameter { - const char *name; - enum QEMUOptionParType type; - union { - uint64_t n; - char* s; - } value; - const char *help; - bool assigned; -} QEMUOptionParameter; - - const char *get_opt_name(char *buf, int buf_size, const char *p, char delim); const char *get_opt_value(char *buf, int buf_size, const char *p); int get_next_param_value(char *buf, int buf_size, @@ -58,32 +39,11 @@ int get_param_value(char *buf, int buf_size, const char *tag, const char *str); -/* - * The following functions take a parameter list as input. This is a pointer to - * the first element of a QEMUOptionParameter array which is terminated by an - * entry with entry->name == NULL. - */ - -QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, - const char *name); -int set_option_parameter(QEMUOptionParameter *list, const char *name, - const char *value); -int set_option_parameter_int(QEMUOptionParameter *list, const char *name, - uint64_t value); -QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest, - QEMUOptionParameter *list); -QEMUOptionParameter *parse_option_parameters(const char *param, - QEMUOptionParameter *list, QEMUOptionParameter *dest); void parse_option_size(const char *name, const char *value, uint64_t *ret, Error **errp); -void free_option_parameters(QEMUOptionParameter *list); -void print_option_parameters(QEMUOptionParameter *list); -void print_option_help(QEMUOptionParameter *list); bool has_help_option(const char *param); bool is_valid_option_list(const char *param); -/* ------------------------------------------------------------------ */ - typedef struct QemuOpt QemuOpt; typedef struct QemuOpts QemuOpts; typedef struct QemuOptsList QemuOptsList; @@ -175,12 +135,6 @@ int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque, int abort_on_failure); void qemu_opts_print_help(QemuOptsList *list); void qemu_opts_free(QemuOptsList *list); -QEMUOptionParameter *opts_to_params(QemuOpts *opts); -QemuOptsList *params_to_opts(QEMUOptionParameter *list); -/* FIXME: will remove QEMUOptionParameter after all drivers switch to QemuOpts. - */ -QemuOptsList *qemu_opts_append(QemuOptsList *dst, - QemuOptsList *list, - QEMUOptionParameter *param); +QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list); #endif diff --git a/qemu-img.c b/qemu-img.c index 8acdcca8bf..c98896b281 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -280,8 +280,7 @@ static int print_block_option_help(const char *filename, const char *fmt) return 1; } - create_opts = qemu_opts_append(create_opts, drv->create_opts, - drv->create_options); + create_opts = qemu_opts_append(create_opts, drv->create_opts); if (filename) { proto_drv = bdrv_find_protocol(filename, true); if (!proto_drv) { @@ -289,8 +288,7 @@ static int print_block_option_help(const char *filename, const char *fmt) qemu_opts_free(create_opts); return 1; } - create_opts = qemu_opts_append(create_opts, proto_drv->create_opts, - proto_drv->create_options); + create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); } qemu_opts_print_help(create_opts); @@ -1381,10 +1379,8 @@ static int img_convert(int argc, char **argv) goto out; } - create_opts = qemu_opts_append(create_opts, drv->create_opts, - drv->create_options); - create_opts = qemu_opts_append(create_opts, proto_drv->create_opts, - proto_drv->create_options); + 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)) { @@ -1437,7 +1433,7 @@ static int img_convert(int argc, char **argv) if (!skip_create) { /* Create the new image */ - ret = bdrv_create(drv, out_filename, NULL, opts, &local_err); + ret = bdrv_create(drv, out_filename, opts, &local_err); if (ret < 0) { error_report("%s: error while converting %s: %s", out_filename, out_fmt, error_get_pretty(local_err)); @@ -2766,8 +2762,7 @@ static int img_amend(int argc, char **argv) goto out; } - create_opts = qemu_opts_append(create_opts, bs->drv->create_opts, - bs->drv->create_options); + create_opts = qemu_opts_append(create_opts, bs->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'", fmt); @@ -2775,7 +2770,7 @@ static int img_amend(int argc, char **argv) goto out; } - ret = bdrv_amend_options(bs, NULL, opts); + ret = bdrv_amend_options(bs, opts); if (ret < 0) { error_report("Error while amending options: %s", strerror(-ret)); goto out; diff --git a/util/qemu-option.c b/util/qemu-option.c index 0d9d3ec889..8ac8111ea8 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -123,22 +123,6 @@ int get_param_value(char *buf, int buf_size, return get_next_param_value(buf, buf_size, tag, &str); } -/* - * Searches an option list for an option with the given name - */ -QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list, - const char *name) -{ - while (list && list->name) { - if (!strcmp(list->name, name)) { - return list; - } - list++; - } - - return NULL; -} - static void parse_option_bool(const char *name, const char *value, bool *ret, Error **errp) { @@ -226,244 +210,6 @@ void parse_option_size(const char *name, const char *value, } } -/* - * Sets the value of a parameter in a given option list. The parsing of the - * value depends on the type of option: - * - * OPT_FLAG (uses value.n): - * If no value is given, the flag is set to 1. - * Otherwise the value must be "on" (set to 1) or "off" (set to 0) - * - * OPT_STRING (uses value.s): - * value is strdup()ed and assigned as option value - * - * OPT_SIZE (uses value.n): - * The value is converted to an integer. Suffixes for kilobytes etc. are - * allowed (powers of 1024). - * - * Returns 0 on succes, -1 in error cases - */ -int set_option_parameter(QEMUOptionParameter *list, const char *name, - const char *value) -{ - bool flag; - Error *local_err = NULL; - - // Find a matching parameter - list = get_option_parameter(list, name); - if (list == NULL) { - fprintf(stderr, "Unknown option '%s'\n", name); - return -1; - } - - // Process parameter - switch (list->type) { - case OPT_FLAG: - parse_option_bool(name, value, &flag, &local_err); - if (!local_err) { - list->value.n = flag; - } - break; - - case OPT_STRING: - if (value != NULL) { - list->value.s = g_strdup(value); - } else { - fprintf(stderr, "Option '%s' needs a parameter\n", name); - return -1; - } - break; - - case OPT_SIZE: - parse_option_size(name, value, &list->value.n, &local_err); - break; - - default: - fprintf(stderr, "Bug: Option '%s' has an unknown type\n", name); - return -1; - } - - if (local_err) { - qerror_report_err(local_err); - error_free(local_err); - return -1; - } - - list->assigned = true; - - return 0; -} - -/* - * Sets the given parameter to an integer instead of a string. - * This function cannot be used to set string options. - * - * Returns 0 on success, -1 in error cases - */ -int set_option_parameter_int(QEMUOptionParameter *list, const char *name, - uint64_t value) -{ - // Find a matching parameter - list = get_option_parameter(list, name); - if (list == NULL) { - fprintf(stderr, "Unknown option '%s'\n", name); - return -1; - } - - // Process parameter - switch (list->type) { - case OPT_FLAG: - case OPT_NUMBER: - case OPT_SIZE: - list->value.n = value; - break; - - default: - return -1; - } - - list->assigned = true; - - return 0; -} - -/* - * Frees a option list. If it contains strings, the strings are freed as well. - */ -void free_option_parameters(QEMUOptionParameter *list) -{ - QEMUOptionParameter *cur = list; - - while (cur && cur->name) { - if (cur->type == OPT_STRING) { - g_free(cur->value.s); - } - cur++; - } - - g_free(list); -} - -/* - * Count valid options in list - */ -static size_t count_option_parameters(QEMUOptionParameter *list) -{ - size_t num_options = 0; - - while (list && list->name) { - num_options++; - list++; - } - - return num_options; -} - -/* - * Append an option list (list) to an option list (dest). - * - * If dest is NULL, a new copy of list is created. - * - * Returns a pointer to the first element of dest (or the newly allocated copy) - */ -QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest, - QEMUOptionParameter *list) -{ - size_t num_options, num_dest_options; - - num_options = count_option_parameters(dest); - num_dest_options = num_options; - - num_options += count_option_parameters(list); - - dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter)); - dest[num_dest_options].name = NULL; - - while (list && list->name) { - if (get_option_parameter(dest, list->name) == NULL) { - dest[num_dest_options++] = *list; - dest[num_dest_options].name = NULL; - } - list++; - } - - return dest; -} - -/* - * Parses a parameter string (param) into an option list (dest). - * - * list is the template option list. If dest is NULL, a new copy of list is - * created. If list is NULL, this function fails. - * - * A parameter string consists of one or more parameters, separated by commas. - * Each parameter consists of its name and possibly of a value. In the latter - * case, the value is delimited by an = character. To specify a value which - * contains commas, double each comma so it won't be recognized as the end of - * the parameter. - * - * For more details of the parsing see above. - * - * Returns a pointer to the first element of dest (or the newly allocated copy) - * or NULL in error cases - */ -QEMUOptionParameter *parse_option_parameters(const char *param, - QEMUOptionParameter *list, QEMUOptionParameter *dest) -{ - QEMUOptionParameter *allocated = NULL; - char name[256]; - char value[256]; - char *param_delim, *value_delim; - char next_delim; - int i; - - if (list == NULL) { - return NULL; - } - - if (dest == NULL) { - dest = allocated = append_option_parameters(NULL, list); - } - - for (i = 0; dest[i].name; i++) { - dest[i].assigned = false; - } - - while (*param) { - - // Find parameter name and value in the string - param_delim = strchr(param, ','); - value_delim = strchr(param, '='); - - if (value_delim && (value_delim < param_delim || !param_delim)) { - next_delim = '='; - } else { - next_delim = ','; - value_delim = NULL; - } - - param = get_opt_name(name, sizeof(name), param, next_delim); - if (value_delim) { - param = get_opt_value(value, sizeof(value), param + 1); - } - if (*param != '\0') { - param++; - } - - // Set the parameter - if (set_option_parameter(dest, name, value_delim ? value : NULL)) { - goto fail; - } - } - - return dest; - -fail: - // Only free the list if it was newly allocated - free_option_parameters(allocated); - return NULL; -} - bool has_help_option(const char *param) { size_t buflen = strlen(param) + 1; @@ -513,46 +259,6 @@ out: return result; } -/* - * Prints all options of a list that have a value to stdout - */ -void print_option_parameters(QEMUOptionParameter *list) -{ - while (list && list->name) { - switch (list->type) { - case OPT_STRING: - if (list->value.s != NULL) { - printf("%s='%s' ", list->name, list->value.s); - } - break; - case OPT_FLAG: - printf("%s=%s ", list->name, list->value.n ? "on" : "off"); - break; - case OPT_SIZE: - case OPT_NUMBER: - printf("%s=%" PRId64 " ", list->name, list->value.n); - break; - default: - printf("%s=(unknown type) ", list->name); - break; - } - list++; - } -} - -/* - * Prints an overview of all available options - */ -void print_option_help(QEMUOptionParameter *list) -{ - printf("Supported options:\n"); - while (list && list->name) { - printf("%-16s %s\n", list->name, - list->help ? list->help : "No description available"); - list++; - } -} - void qemu_opts_print_help(QemuOptsList *list) { QemuOptDesc *desc; @@ -1369,121 +1075,6 @@ static size_t count_opts_list(QemuOptsList *list) return num_opts; } -/* Convert QEMUOptionParameter to QemuOpts - * FIXME: this function will be removed after all drivers - * switch to QemuOpts - */ -QemuOptsList *params_to_opts(QEMUOptionParameter *list) -{ - QemuOptsList *opts = NULL; - size_t num_opts, i = 0; - - if (!list) { - return NULL; - } - - num_opts = count_option_parameters(list); - opts = g_malloc0(sizeof(QemuOptsList) + - (num_opts + 1) * sizeof(QemuOptDesc)); - QTAILQ_INIT(&opts->head); - /* (const char *) members will point to malloced space and need to free */ - opts->allocated = true; - - while (list && list->name) { - opts->desc[i].name = g_strdup(list->name); - opts->desc[i].help = g_strdup(list->help); - switch (list->type) { - case OPT_FLAG: - opts->desc[i].type = QEMU_OPT_BOOL; - opts->desc[i].def_value_str = - g_strdup(list->value.n ? "on" : "off"); - break; - - case OPT_NUMBER: - opts->desc[i].type = QEMU_OPT_NUMBER; - if (list->value.n) { - opts->desc[i].def_value_str = - g_strdup_printf("%" PRIu64, list->value.n); - } - break; - - case OPT_SIZE: - opts->desc[i].type = QEMU_OPT_SIZE; - if (list->value.n) { - opts->desc[i].def_value_str = - g_strdup_printf("%" PRIu64, list->value.n); - } - break; - - case OPT_STRING: - opts->desc[i].type = QEMU_OPT_STRING; - opts->desc[i].def_value_str = g_strdup(list->value.s); - break; - } - - i++; - list++; - } - - return opts; -} - -/* convert QemuOpts to QEMUOptionParameter - * Note: result QEMUOptionParameter has shorter lifetime than - * input QemuOpts. - * FIXME: this function will be removed after all drivers - * switch to QemuOpts - */ -QEMUOptionParameter *opts_to_params(QemuOpts *opts) -{ - QEMUOptionParameter *dest = NULL; - QemuOptDesc *desc; - size_t num_opts, i = 0; - const char *tmp; - - if (!opts || !opts->list || !opts->list->desc) { - return NULL; - } - assert(!opts_accepts_any(opts)); - - num_opts = count_opts_list(opts->list); - dest = g_malloc0((num_opts + 1) * sizeof(QEMUOptionParameter)); - - desc = opts->list->desc; - while (desc && desc->name) { - dest[i].name = desc->name; - dest[i].help = desc->help; - dest[i].assigned = qemu_opt_find(opts, desc->name) ? true : false; - switch (desc->type) { - case QEMU_OPT_STRING: - dest[i].type = OPT_STRING; - tmp = qemu_opt_get(opts, desc->name); - dest[i].value.s = g_strdup(tmp); - break; - - case QEMU_OPT_BOOL: - dest[i].type = OPT_FLAG; - dest[i].value.n = qemu_opt_get_bool(opts, desc->name, 0) ? 1 : 0; - break; - - case QEMU_OPT_NUMBER: - dest[i].type = OPT_NUMBER; - dest[i].value.n = qemu_opt_get_number(opts, desc->name, 0); - break; - - case QEMU_OPT_SIZE: - dest[i].type = OPT_SIZE; - dest[i].value.n = qemu_opt_get_size(opts, desc->name, 0); - break; - } - - i++; - desc++; - } - - return dest; -} - void qemu_opts_free(QemuOptsList *list) { /* List members point to new malloced space and need to be freed. @@ -1504,27 +1095,20 @@ void qemu_opts_free(QemuOptsList *list) g_free(list); } -/* Realloc dst option list and append options either from an option list (list) - * or a QEMUOptionParameter (param) to it. dst could be NULL or a malloced list. - * FIXME: will remove QEMUOptionParameter after all drivers switch to QemuOpts. +/* Realloc dst option list and append options from an option list (list) + * to it. dst could be NULL or a malloced list. */ QemuOptsList *qemu_opts_append(QemuOptsList *dst, - QemuOptsList *list, - QEMUOptionParameter *param) + QemuOptsList *list) { size_t num_opts, num_dst_opts; QemuOptDesc *desc; bool need_init = false; - assert(!(list && param)); - if (!param && !list) { + if (!list) { return dst; } - if (param) { - list = params_to_opts(param); - } - /* If dst is NULL, after realloc, some area of dst should be initialized * before adding options to it. */ @@ -1565,8 +1149,5 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst, } } - if (param) { - qemu_opts_free(list); - } return dst; } From 98d896d978eef0fd6ff8d93a1ccea34e00b97f8c Mon Sep 17 00:00:00 2001 From: Chunyan Liu Date: Thu, 5 Jun 2014 17:21:12 +0800 Subject: [PATCH 39/39] QemuOpts: cleanup tmp 'allocated' member from QemuOptsList Now only qemu_opts_append uses 'allocated' to indicate free memory. For this function only, we can also let result list's (const char *) members point to input list's members, only if the input list has longer lifetime than result list. In current code, that is true. So, we can remove the 'allocated' member from QemuOptsList definition to keep code clean. Signed-off-by: Chunyan Liu Signed-off-by: Stefan Hajnoczi --- include/qemu/option.h | 6 ------ util/qemu-option.c | 27 +++------------------------ 2 files changed, 3 insertions(+), 30 deletions(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index 921eccdb38..59bea759a2 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -63,12 +63,6 @@ typedef struct QemuOptDesc { } QemuOptDesc; struct QemuOptsList { - /* FIXME: Temp used for QEMUOptionParamter->QemuOpts conversion to - * indicate the need to free memory. Will remove after all drivers - * switch to QemuOpts. - */ - bool allocated; - const char *name; const char *implied_opt_name; bool merge_lists; /* Merge multiple uses of option into a single list? */ diff --git a/util/qemu-option.c b/util/qemu-option.c index 8ac8111ea8..836055a4d2 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -1077,26 +1077,13 @@ static size_t count_opts_list(QemuOptsList *list) void qemu_opts_free(QemuOptsList *list) { - /* List members point to new malloced space and need to be freed. - * FIXME: - * Introduced for QEMUOptionParamter->QemuOpts conversion. - * Will remove after all drivers switch to QemuOpts. - */ - if (list && list->allocated) { - QemuOptDesc *desc = list->desc; - while (desc && desc->name) { - g_free((char *)desc->name); - g_free((char *)desc->help); - g_free((char *)desc->def_value_str); - desc++; - } - } - g_free(list); } /* Realloc dst option list and append options from an option list (list) * to it. dst could be NULL or a malloced list. + * The lifetime of dst must be shorter than the input list because the + * QemuOptDesc->name, ->help, and ->def_value_str strings are shared. */ QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list) @@ -1125,24 +1112,16 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst, dst->name = NULL; dst->implied_opt_name = NULL; QTAILQ_INIT(&dst->head); - dst->allocated = true; dst->merge_lists = false; } dst->desc[num_dst_opts].name = NULL; - /* (const char *) members of result dst are malloced, need free. */ - assert(dst->allocated); /* append list->desc to dst->desc */ if (list) { desc = list->desc; while (desc && desc->name) { if (find_desc_by_name(dst->desc, desc->name) == NULL) { - dst->desc[num_dst_opts].name = g_strdup(desc->name); - dst->desc[num_dst_opts].type = desc->type; - dst->desc[num_dst_opts].help = g_strdup(desc->help); - dst->desc[num_dst_opts].def_value_str = - g_strdup(desc->def_value_str); - num_dst_opts++; + dst->desc[num_dst_opts++] = *desc; dst->desc[num_dst_opts].name = NULL; } desc++;