* [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser
@ 2012-10-25 12:57 Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 01/10] qemu-option: opt_set(): split it up into more functions Dong Xu Wang
` (9 more replies)
0 siblings, 10 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
Patch 1-3 are from Luiz, added Markus's comments, discussion could be found here:
http://lists.nongnu.org/archive/html/qemu-devel/2012-07/msg02716.html
Patch 3 was changed according Paolo's comments.
Patch 4-5: because qemu_opts_create can not fail while id is null, so create
function qemu_opts_create_nofail and use it.
Patch 6: create function qemu_opt_set_number, like qemu_opt_set_bool.
Patch 7: add def_value and use it in qemu_opts_print.
Patch 8: Create functions to pair with QEMUOptionParameter parser.
Patch 9: Use QemuOpts parser in Block.
Patch 10: Remove QEMUOptionParameter parser related code.
v3->v4):
1) Rebased to the newest source tree.
2) Remove redundant "#include "block-cache.h"
3) Other small changes.
v2->v3:
1) rewrite qemu_opt_set_bool and qemu_opt_set_number according Paolo's coments.
2) split patches to make review easier.
v1->v2:
1) add Luiz's patches.
2) create qemu_opt_set_number() and qemu_opts_create_nofail() functions.
3) add QemuOptsList map to drivers.
4) use original opts parser, not creating new ones.
5) fix other bugs.
Luiz Capitulino (2):
qemu-option: opt_set(): split it up into more functions
qemu-option: qemu_opts_validate(): fix duplicated code
Dong Xu Wang (8):
qemu-option: qemu_opt_set_bool(): fix code duplication
introduce qemu_opts_create_nofail function
use qemu_opts_create_nofail
create new function: qemu_opt_set_number
add def_value and use it in qemu_opts_print.
Create four opts list related functions
Use QemuOpts support in block layer
remove QEMUOptionParameter related functions and struct
block.c | 91 +++++-----
block.h | 5 +-
block/cow.c | 51 +++---
block/qcow.c | 64 ++++---
block/qcow2.c | 176 +++++++++---------
block/qed.c | 90 +++++-----
block/raw-posix.c | 68 ++++----
block/raw.c | 31 ++-
block/sheepdog.c | 80 ++++----
block/vdi.c | 73 ++++----
block/vmdk.c | 79 ++++----
block/vpc.c | 56 ++++---
block/vvfat.c | 11 +-
block_int.h | 6 +-
blockdev.c | 2 +-
qemu-config.c | 4 +-
qemu-img.c | 63 +++----
qemu-option.c | 528 +++++++++++++++++++----------------------------------
qemu-option.h | 40 +----
qemu-sockets.c | 10 +-
vl.c | 12 +-
21 files changed, 692 insertions(+), 848 deletions(-)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 01/10] qemu-option: opt_set(): split it up into more functions
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 02/10] qemu-option: qemu_opts_validate(): fix duplicated code Dong Xu Wang
` (8 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang, Luiz Capitulino
The new functions are opts_accepts_any() and find_desc_by_name(), which
are also going to be used by qemu_opts_validate() (see next commit).
This also makes opt_set() slightly more readable.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 40 ++++++++++++++++++++++++----------------
1 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index 27891e7..375daaa 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -602,26 +602,36 @@ static void qemu_opt_del(QemuOpt *opt)
g_free(opt);
}
-static void opt_set(QemuOpts *opts, const char *name, const char *value,
- bool prepend, Error **errp)
+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)
{
- QemuOpt *opt;
- const QemuOptDesc *desc = opts->list->desc;
- Error *local_err = NULL;
int i;
for (i = 0; desc[i].name != NULL; i++) {
if (strcmp(desc[i].name, name) == 0) {
- break;
+ return &desc[i];
}
}
- if (desc[i].name == NULL) {
- if (i == 0) {
- /* empty list -> allow any */;
- } else {
- error_set(errp, QERR_INVALID_PARAMETER, name);
- return;
- }
+
+ return NULL;
+}
+
+static void opt_set(QemuOpts *opts, const char *name, const char *value,
+ bool prepend, Error **errp)
+{
+ QemuOpt *opt;
+ const QemuOptDesc *desc;
+ Error *local_err = NULL;
+
+ desc = find_desc_by_name(opts->list->desc, name);
+ if (!desc && !opts_accepts_any(opts)) {
+ error_set(errp, QERR_INVALID_PARAMETER, name);
+ return;
}
opt = g_malloc0(sizeof(*opt));
@@ -632,9 +642,7 @@ static void opt_set(QemuOpts *opts, const char *name, const char *value,
} else {
QTAILQ_INSERT_TAIL(&opts->head, opt, next);
}
- if (desc[i].name != NULL) {
- opt->desc = desc+i;
- }
+ opt->desc = desc;
if (value) {
opt->str = g_strdup(value);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 02/10] qemu-option: qemu_opts_validate(): fix duplicated code
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 01/10] qemu-option: opt_set(): split it up into more functions Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 03/10] qemu-option: qemu_opt_set_bool(): fix code duplication Dong Xu Wang
` (7 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang, Luiz Capitulino
Use opts_accepts_any() and find_desc_by_name().
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 14 +++-----------
1 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index 375daaa..74321bb 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -1076,23 +1076,15 @@ void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
QemuOpt *opt;
Error *local_err = NULL;
- assert(opts->list->desc[0].name == NULL);
+ assert(opts_accepts_any(opts));
QTAILQ_FOREACH(opt, &opts->head, next) {
- int i;
-
- for (i = 0; desc[i].name != NULL; i++) {
- if (strcmp(desc[i].name, opt->name) == 0) {
- break;
- }
- }
- if (desc[i].name == NULL) {
+ opt->desc = find_desc_by_name(desc, opt->name);
+ if (!opt->desc) {
error_set(errp, QERR_INVALID_PARAMETER, opt->name);
return;
}
- opt->desc = &desc[i];
-
qemu_opt_parse(opt, &local_err);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 03/10] qemu-option: qemu_opt_set_bool(): fix code duplication
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 01/10] qemu-option: opt_set(): split it up into more functions Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 02/10] qemu-option: qemu_opts_validate(): fix duplicated code Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 04/10] introduce qemu_opts_create_nofail function Dong Xu Wang
` (6 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
It will set opt->str in qemu_opt_set_bool, without opt->str, there
will be some potential bugs.
These are uses of opt->str, and what happens when it isn't set:
* qemu_opt_get(): returns NULL, which means "not set". Bug can bite
when value isn't the default value.
* qemu_opt_parse(): passes NULL to parse_option_bool(), which treats it
like "on". Wrong if the value is actually false. Bug can bite when
qemu_opts_validate() runs after qemu_opt_set_bool().
* qemu_opt_del(): passes NULL to g_free(), which is just fine.
* qemu_opt_foreach(): passes NULL to the callback, which is unlikely to
be prepared for it.
* qemu_opts_print(): prints NULL, which crashes on some systems.
* qemu_opts_to_qdict(): passes NULL to qstring_from_str(), which
crashes.
It also makes qemu_opt_set_bool more readable by using find_desc_by_name
and opts_accepts_any.
It is based on Luiz's patch and uses Markus's comments. Discussions can
be found at:
http://lists.nongnu.org/archive/html/qemu-devel/2012-07/msg02716.html
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 27 +++++++++------------------
1 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index 74321bb..e0131ce 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -677,30 +677,21 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
{
QemuOpt *opt;
const QemuOptDesc *desc = opts->list->desc;
- int i;
- for (i = 0; desc[i].name != NULL; i++) {
- if (strcmp(desc[i].name, name) == 0) {
- break;
- }
- }
- if (desc[i].name == NULL) {
- if (i == 0) {
- /* empty list -> allow any */;
- } else {
- qerror_report(QERR_INVALID_PARAMETER, name);
- return -1;
- }
+ opt = g_malloc0(sizeof(*opt));
+ opt->desc = find_desc_by_name(desc, name);
+ if (!opt->desc && !opts_accepts_any(opts)) {
+ qerror_report(QERR_INVALID_PARAMETER, name);
+ g_free(opt);
+ return -1;
}
- opt = g_malloc0(sizeof(*opt));
opt->name = g_strdup(name);
opt->opts = opts;
- QTAILQ_INSERT_TAIL(&opts->head, opt, next);
- if (desc[i].name != NULL) {
- opt->desc = desc+i;
- }
opt->value.boolean = !!val;
+ opt->str = g_strdup(val ? "on" : "off");
+ QTAILQ_INSERT_TAIL(&opts->head, opt, next);
+
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 04/10] introduce qemu_opts_create_nofail function
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
` (2 preceding siblings ...)
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 03/10] qemu-option: qemu_opt_set_bool(): fix code duplication Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-25 13:06 ` Peter Maydell
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 05/10] use qemu_opts_create_nofail Dong Xu Wang
` (5 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
While id is NULL, qemu_opts_create can not fail, so ignore
errors is fine.
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 5 +++++
qemu-option.h | 1 +
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index e0131ce..d7d5ea9 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -780,6 +780,11 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
return opts;
}
+QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
+{
+ return qemu_opts_create(list, NULL, 0, NULL);
+}
+
void qemu_opts_reset(QemuOptsList *list)
{
QemuOpts *opts, *next_opts;
diff --git a/qemu-option.h b/qemu-option.h
index ca72986..b0f8d1e 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -133,6 +133,7 @@ int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);
+QemuOpts *qemu_opts_create_nofail(QemuOptsList *list);
void qemu_opts_reset(QemuOptsList *list);
void qemu_opts_loc_restore(QemuOpts *opts);
int qemu_opts_set(QemuOptsList *list, const char *id,
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 05/10] use qemu_opts_create_nofail
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
` (3 preceding siblings ...)
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 04/10] introduce qemu_opts_create_nofail function Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 06/10] create new function: qemu_opt_set_number Dong Xu Wang
` (4 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
We will use qemu_opts_create_nofail function, it can make code
more readable.
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
blockdev.c | 2 +-
qemu-config.c | 4 ++--
qemu-img.c | 2 +-
qemu-sockets.c | 10 +++++-----
vl.c | 12 +++++-------
5 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 99828ad..1742f40 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -562,7 +562,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
break;
case IF_VIRTIO:
/* add virtio block device */
- opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(qemu_find_opts("device"));
if (arch_type == QEMU_ARCH_S390X) {
qemu_opt_set(opts, "driver", "virtio-blk-s390");
} else {
diff --git a/qemu-config.c b/qemu-config.c
index cd1ec21..959a350 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -765,7 +765,7 @@ int qemu_global_option(const char *str)
return -1;
}
- opts = qemu_opts_create(&qemu_global_opts, NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(&qemu_global_opts);
qemu_opt_set(opts, "driver", driver);
qemu_opt_set(opts, "property", property);
qemu_opt_set(opts, "value", str+offset+1);
@@ -852,7 +852,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
error_free(local_err);
goto out;
}
- opts = qemu_opts_create(list, NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(list);
continue;
}
if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) {
diff --git a/qemu-img.c b/qemu-img.c
index f17f187..f1c224e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1778,7 +1778,7 @@ static int img_resize(int argc, char **argv)
}
/* Parse size */
- param = qemu_opts_create(&resize_options, NULL, 0, NULL);
+ param = qemu_opts_create_nofail(&resize_options);
if (qemu_opt_set(param, BLOCK_OPT_SIZE, size)) {
/* Error message already printed when size parsing fails */
ret = -1;
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 2b1ed2f..edee875 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -572,7 +572,7 @@ int inet_listen(const char *str, char *ostr, int olen,
char *optstr;
int sock = -1;
- opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(&dummy_opts);
if (inet_parse(opts, str) == 0) {
sock = inet_listen_opts(opts, port_offset, errp);
if (sock != -1 && ostr) {
@@ -609,7 +609,7 @@ int inet_connect(const char *str, Error **errp)
QemuOpts *opts;
int sock = -1;
- opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(&dummy_opts);
if (inet_parse(opts, str) == 0) {
sock = inet_connect_opts(opts, errp, NULL, NULL);
} else {
@@ -641,7 +641,7 @@ int inet_nonblocking_connect(const char *str,
g_assert(callback != NULL);
- opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(&dummy_opts);
if (inet_parse(opts, str) == 0) {
sock = inet_connect_opts(opts, errp, callback, opaque);
} else {
@@ -737,7 +737,7 @@ int unix_listen(const char *str, char *ostr, int olen)
char *path, *optstr;
int sock, len;
- opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(&dummy_opts);
optstr = strchr(str, ',');
if (optstr) {
@@ -765,7 +765,7 @@ int unix_connect(const char *path)
QemuOpts *opts;
int sock;
- opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(&dummy_opts);
qemu_opt_set(opts, "path", path);
sock = unix_connect_opts(opts);
qemu_opts_del(opts);
diff --git a/vl.c b/vl.c
index ee3c43a..c748d57 100644
--- a/vl.c
+++ b/vl.c
@@ -1883,7 +1883,7 @@ static int balloon_parse(const char *arg)
return -1;
} else {
/* create empty opts */
- opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0, NULL);
+ opts = qemu_opts_create_nofail(qemu_find_opts("device"));
}
qemu_opt_set(opts, "driver", "virtio-balloon");
return 0;
@@ -2131,14 +2131,14 @@ static int virtcon_parse(const char *devname)
exit(1);
}
- bus_opts = qemu_opts_create(device, NULL, 0, NULL);
+ bus_opts = qemu_opts_create_nofail(device);
if (arch_type == QEMU_ARCH_S390X) {
qemu_opt_set(bus_opts, "driver", "virtio-serial-s390");
} else {
qemu_opt_set(bus_opts, "driver", "virtio-serial-pci");
}
- dev_opts = qemu_opts_create(device, NULL, 0, NULL);
+ dev_opts = qemu_opts_create_nofail(device);
qemu_opt_set(dev_opts, "driver", "virtconsole");
snprintf(label, sizeof(label), "virtcon%d", index);
@@ -2944,8 +2944,7 @@ int main(int argc, char **argv, char **envp)
qemu_opt_set_bool(fsdev, "readonly",
qemu_opt_get_bool(opts, "readonly", 0));
- device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
- NULL);
+ device = qemu_opts_create_nofail(qemu_find_opts("device"));
qemu_opt_set(device, "driver", "virtio-9p-pci");
qemu_opt_set(device, "fsdev",
qemu_opt_get(opts, "mount_tag"));
@@ -2965,8 +2964,7 @@ int main(int argc, char **argv, char **envp)
}
qemu_opt_set(fsdev, "fsdriver", "synth");
- device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
- NULL);
+ device = qemu_opts_create_nofail(qemu_find_opts("device"));
qemu_opt_set(device, "driver", "virtio-9p-pci");
qemu_opt_set(device, "fsdev", "v_synth");
qemu_opt_set(device, "mount_tag", "v_synth");
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 06/10] create new function: qemu_opt_set_number
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
` (4 preceding siblings ...)
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 05/10] use qemu_opts_create_nofail Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-26 9:02 ` Stefan Hajnoczi
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 07/10] add def_value and use it in qemu_opts_print Dong Xu Wang
` (3 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 24 ++++++++++++++++++++++++
qemu-option.h | 1 +
2 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index d7d5ea9..eeb2c9c 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -695,6 +695,30 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
return 0;
}
+int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
+{
+ char buffer[1024];
+ QemuOpt *opt;
+ const QemuOptDesc *desc = opts->list->desc;
+
+ snprintf(buffer, sizeof(buffer), "%" PRId64, val);
+ opt = g_malloc0(sizeof(*opt));
+ opt->desc = find_desc_by_name(desc, name);
+ if (!opt->desc && !opts_accepts_any(opts)) {
+ qerror_report(QERR_INVALID_PARAMETER, name);
+ g_free(opt);
+ return -1;
+ }
+
+ opt->name = g_strdup(name);
+ opt->opts = opts;
+ opt->value.uint = val;
+ opt->str = g_strdup(buffer);
+ QTAILQ_INSERT_TAIL(&opts->head, opt, next);
+
+ return 0;
+}
+
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
int abort_on_failure)
{
diff --git a/qemu-option.h b/qemu-option.h
index b0f8d1e..002dd07 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -126,6 +126,7 @@ 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,
Error **errp);
int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val);
+int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val);
typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque);
int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
int abort_on_failure);
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 07/10] add def_value and use it in qemu_opts_print.
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
` (5 preceding siblings ...)
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 06/10] create new function: qemu_opt_set_number Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-26 9:32 ` Stefan Hajnoczi
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 08/10] Create four opts list related functions Dong Xu Wang
` (2 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
qemu_opts_print has no user now, so I re-write it and use it in
qemu-img.c.
qemu_opts_print will be used while using "qemu-img create", it will
produce the same output as previous code.
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 41 ++++++++++++++++++++++++++++++++---------
qemu-option.h | 1 +
2 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index eeb2c9c..54dbdd0 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -860,15 +860,38 @@ void qemu_opts_del(QemuOpts *opts)
int qemu_opts_print(QemuOpts *opts, void *dummy)
{
- QemuOpt *opt;
-
- fprintf(stderr, "%s: %s:", opts->list->name,
- opts->id ? opts->id : "<noid>");
- QTAILQ_FOREACH(opt, &opts->head, next) {
- fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
- }
- fprintf(stderr, "\n");
- return 0;
+ QemuOpt *opt = NULL;
+ QemuOptDesc *desc = opts->list->desc;
+
+ while (desc && desc->name) {
+ opt = qemu_opt_find(opts, desc->name);
+ switch (desc->type) {
+ case QEMU_OPT_STRING:
+ if (opt != NULL) {
+ printf("%s='%s' ", opt->name, opt->str);
+ }
+ break;
+ case QEMU_OPT_BOOL:
+ printf("%s=%s ", desc->name, (opt && opt->str) ? "on" : "off");
+ break;
+ case QEMU_OPT_NUMBER:
+ case QEMU_OPT_SIZE:
+ if (strcmp(desc->name, "cluster_size")) {
+ printf("%s=%" PRId64 " ", desc->name,
+ (opt && opt->value.uint) ? opt->value.uint : 0);
+ } else {
+ printf("%s=%" PRId64 " ", desc->name,
+ (opt && opt->value.uint) ?
+ opt->value.uint : desc->def_value);
+ }
+ break;
+ default:
+ printf("%s=(unknown type) ", desc->name);
+ break;
+ }
+ desc++;
+ }
+ return 0;
}
static int opts_do_parse(QemuOpts *opts, const char *params,
diff --git a/qemu-option.h b/qemu-option.h
index 002dd07..9ea59cf 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -96,6 +96,7 @@ typedef struct QemuOptDesc {
const char *name;
enum QemuOptType type;
const char *help;
+ uint64_t def_value;
} QemuOptDesc;
struct QemuOptsList {
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 08/10] Create four opts list related functions
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
` (6 preceding siblings ...)
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 07/10] add def_value and use it in qemu_opts_print Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 09/10] Use QemuOpts support in block layer Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 10/10] remove QEMUOptionParameter related functions and struct Dong Xu Wang
9 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
This patch will create 4 functions, count_opts_list, append_opts_list,
free_opts_list and print_opts_list, they will used in following commits.
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
qemu-option.h | 5 ++-
2 files changed, 91 insertions(+), 1 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index 54dbdd0..ab270f0 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -1153,3 +1153,90 @@ 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)
+{
+ size_t i = 0;
+
+ while (list && list->desc[i].name) {
+ i++;
+ }
+
+ return i;
+}
+
+/* Create a new QemuOptsList and make its desc to the merge of first and second.
+ * It will allocate space for one new QemuOptsList plus enouth space for
+ * QemuOptDesc in first and second QemuOptsList. First argument's QemuOptDesc
+ * members take precedence over second's.
+ */
+QemuOptsList *append_opts_list(QemuOptsList *first,
+ QemuOptsList *second)
+{
+ size_t num_first_options, num_second_options;
+ QemuOptsList *dest = NULL;
+ int i = 0;
+ int index = 0;
+
+ num_first_options = count_opts_list(first);
+ num_second_options = count_opts_list(second);
+ if (num_first_options + num_second_options == 0) {
+ return NULL;
+ }
+
+ dest = g_malloc0(sizeof(QemuOptsList)
+ + (num_first_options + num_second_options) * sizeof(QemuOptDesc));
+
+ dest->name = "append_opts_list";
+ dest->implied_opt_name = NULL;
+ dest->merge_lists = false;
+ QTAILQ_INIT(&dest->head);
+ while (first && (first->desc[i].name)) {
+ if (!find_desc_by_name(dest->desc, first->desc[i].name)) {
+ dest->desc[index].name = g_strdup(first->desc[i].name);
+ dest->desc[index].help = g_strdup(first->desc[i].help);
+ dest->desc[index].type = first->desc[i].type;
+ dest->desc[index].def_value = first->desc[i].def_value;
+ ++index;
+ }
+ i++;
+ }
+ i = 0;
+ while (second && (second->desc[i].name)) {
+ if (!find_desc_by_name(dest->desc, second->desc[i].name)) {
+ dest->desc[index].name = g_strdup(first->desc[i].name);
+ dest->desc[index].help = g_strdup(first->desc[i].help);
+ dest->desc[index].type = second->desc[i].type;
+ dest->desc[index].def_value = second->desc[i].def_value;
+ ++index;
+ }
+ i++;
+ }
+ dest->desc[index].name = NULL;
+ return dest;
+}
+
+void free_opts_list(QemuOptsList *list)
+{
+ int i = 0;
+
+ while (list && list->desc[i].name) {
+ g_free((char *)list->desc[i].name);
+ g_free((char *)list->desc[i].help);
+ i++;
+ }
+
+ g_free(list);
+}
+
+void print_opts_list(QemuOptsList *list)
+{
+ int i = 0;
+ printf("Supported options:\n");
+ while (list && list->desc[i].name) {
+ printf("%-16s %s\n", list->desc[i].name,
+ list->desc[i].help ?
+ list->desc[i].help : "No description available");
+ i++;
+ }
+}
diff --git a/qemu-option.h b/qemu-option.h
index 9ea59cf..d1825ee 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -155,5 +155,8 @@ typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
int qemu_opts_print(QemuOpts *opts, void *dummy);
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
int abort_on_failure);
-
+QemuOptsList *append_opts_list(QemuOptsList *dest,
+ QemuOptsList *list);
+void free_opts_list(QemuOptsList *list);
+void print_opts_list(QemuOptsList *list);
#endif
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 09/10] Use QemuOpts support in block layer
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
` (7 preceding siblings ...)
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 08/10] Create four opts list related functions Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
2012-10-26 9:51 ` Stefan Hajnoczi
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 10/10] remove QEMUOptionParameter related functions and struct Dong Xu Wang
9 siblings, 1 reply; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
This patch will use QemuOpts related functions in block layer, add
a member bdrv_create_options to BlockDriver struct, it will return
a QemuOptsList pointer, which includes the image format's create
options.
And create options's primary consumer is block creating related functions,
so modify them together.
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
block.c | 91 +++++++++++++--------------
block.h | 5 +-
block/cow.c | 51 ++++++++-------
block/qcow.c | 64 ++++++++++---------
block/qcow2.c | 176 +++++++++++++++++++++++++++-------------------------
block/qed.c | 90 ++++++++++++++-------------
block/raw-posix.c | 68 ++++++++++-----------
block/raw.c | 31 ++++++---
block/sheepdog.c | 80 ++++++++++++------------
block/vdi.c | 73 +++++++++++-----------
block/vmdk.c | 79 ++++++++++++-----------
block/vpc.c | 56 ++++++++++-------
block/vvfat.c | 11 ++--
block_int.h | 6 +-
qemu-img.c | 61 +++++++++----------
qemu-option.c | 9 ++-
16 files changed, 489 insertions(+), 462 deletions(-)
diff --git a/block.c b/block.c
index e95f613..f639655 100644
--- a/block.c
+++ b/block.c
@@ -353,7 +353,7 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
typedef struct CreateCo {
BlockDriver *drv;
char *filename;
- QEMUOptionParameter *options;
+ QemuOpts *opts;
int ret;
} CreateCo;
@@ -362,11 +362,11 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
CreateCo *cco = opaque;
assert(cco->drv);
- cco->ret = cco->drv->bdrv_create(cco->filename, cco->options);
+ cco->ret = cco->drv->bdrv_create(cco->filename, cco->opts);
}
int bdrv_create(BlockDriver *drv, const char* filename,
- QEMUOptionParameter *options)
+ QemuOpts *opts)
{
int ret;
@@ -374,7 +374,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
CreateCo cco = {
.drv = drv,
.filename = g_strdup(filename),
- .options = options,
+ .opts = opts,
.ret = NOT_DONE,
};
@@ -399,7 +399,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
return ret;
}
-int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
+int bdrv_create_file(const char *filename, QemuOpts *opts)
{
BlockDriver *drv;
@@ -408,7 +408,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
return -ENOENT;
}
- return bdrv_create(drv, filename, options);
+ return bdrv_create(drv, filename, opts);
}
/*
@@ -748,7 +748,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
int64_t total_size;
int is_protocol = 0;
BlockDriver *bdrv_qcow2;
- QEMUOptionParameter *options;
+ QemuOpts *opts;
char backing_filename[PATH_MAX];
/* if snapshot, we create a temporary backing file and open it
@@ -781,17 +781,16 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
return -errno;
bdrv_qcow2 = bdrv_find_format("qcow2");
- options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
+ opts = qemu_opts_create_nofail(bdrv_qcow2->bdrv_create_options());
- set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);
- set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, backing_filename);
if (drv) {
- set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
- drv->format_name);
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, drv->format_name);
}
- ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
- free_option_parameters(options);
+ ret = bdrv_create(bdrv_qcow2, tmp_filename, opts);
+ qemu_opts_del(opts);
if (ret < 0) {
return ret;
}
@@ -4296,8 +4295,10 @@ int bdrv_img_create(const char *filename, const char *fmt,
const char *base_filename, const char *base_fmt,
char *options, uint64_t img_size, int flags)
{
- QEMUOptionParameter *param = NULL, *create_options = NULL;
- QEMUOptionParameter *backing_fmt, *backing_file, *size;
+ QemuOpts *opts = NULL;
+ QemuOptsList *create_options = NULL;
+ const char *backing_fmt, *backing_file;
+ int64_t size;
BlockDriverState *bs = NULL;
BlockDriver *drv, *proto_drv;
BlockDriver *backing_drv = NULL;
@@ -4317,21 +4318,16 @@ int bdrv_img_create(const char *filename, const char *fmt,
ret = -EINVAL;
goto out;
}
-
- create_options = append_option_parameters(create_options,
- drv->create_options);
- create_options = append_option_parameters(create_options,
- proto_drv->create_options);
-
+ create_options = append_opts_list(drv->bdrv_create_options(),
+ proto_drv->bdrv_create_options());
/* Create parameter list with default values */
- param = parse_option_parameters("", create_options, param);
+ opts = qemu_opts_create(create_options, NULL, 0, NULL);
- set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
/* Parse -o options */
if (options) {
- param = parse_option_parameters(options, create_options, param);
- if (param == NULL) {
+ if (qemu_opts_do_parse(opts, options, NULL) != 0) {
error_report("Invalid options for file format '%s'.", fmt);
ret = -EINVAL;
goto out;
@@ -4339,7 +4335,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
}
if (base_filename) {
- if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
+ if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE,
base_filename)) {
error_report("Backing file not supported for file format '%s'",
fmt);
@@ -4349,7 +4345,7 @@ int 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_report("Backing file format not supported for file "
"format '%s'", fmt);
ret = -EINVAL;
@@ -4357,9 +4353,9 @@ int bdrv_img_create(const char *filename, const char *fmt,
}
}
- 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_report("Error: Trying to create an image with the "
"same filename as the backing file");
ret = -EINVAL;
@@ -4367,12 +4363,11 @@ int bdrv_img_create(const char *filename, const char *fmt,
}
}
- 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_report("Unknown backing file format '%s'",
- backing_fmt->value.s);
+ error_report("Unknown backing file format '%s'", backing_fmt);
ret = -EINVAL;
goto out;
}
@@ -4380,11 +4375,10 @@ int bdrv_img_create(const char *filename, const char *fmt,
// 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_number(opts, BLOCK_OPT_SIZE, -1);
+ if (size == -1) {
+ if (backing_file) {
uint64_t size;
- char buf[32];
int back_flags;
/* backing files always opened read-only */
@@ -4393,16 +4387,15 @@ int bdrv_img_create(const char *filename, const char *fmt,
bs = bdrv_new("");
- ret = bdrv_open(bs, backing_file->value.s, back_flags, backing_drv);
+ ret = bdrv_open(bs, backing_file, back_flags, backing_drv);
if (ret < 0) {
- error_report("Could not open '%s'", backing_file->value.s);
+ error_report("Could not open '%s'", backing_file);
goto out;
}
bdrv_get_geometry(bs, &size);
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);
} else {
error_report("Image creation needs a size parameter");
ret = -EINVAL;
@@ -4411,10 +4404,10 @@ int bdrv_img_create(const char *filename, const char *fmt,
}
printf("Formatting '%s', fmt=%s ", filename, fmt);
- print_option_parameters(param);
+ qemu_opts_print(opts, NULL);
puts("");
- ret = bdrv_create(drv, filename, param);
+ ret = bdrv_create(drv, filename, opts);
if (ret < 0) {
if (ret == -ENOTSUP) {
@@ -4430,8 +4423,10 @@ int bdrv_img_create(const char *filename, const char *fmt,
}
out:
- free_option_parameters(create_options);
- free_option_parameters(param);
+ free_opts_list(create_options);
+ if (opts) {
+ qemu_opts_del(opts);
+ }
if (bs) {
bdrv_delete(bs);
diff --git a/block.h b/block.h
index e2d89d7..7842d85 100644
--- a/block.h
+++ b/block.h
@@ -124,8 +124,8 @@ BlockDriver *bdrv_find_protocol(const char *filename);
BlockDriver *bdrv_find_format(const char *format_name);
BlockDriver *bdrv_find_whitelisted_format(const char *format_name);
int bdrv_create(BlockDriver *drv, const char* filename,
- QEMUOptionParameter *options);
-int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
+ QemuOpts *options);
+int bdrv_create_file(const char *filename, QemuOpts *options);
BlockDriverState *bdrv_new(const char *device_name);
void bdrv_make_anon(BlockDriverState *bs);
void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
@@ -425,5 +425,4 @@ typedef enum {
#define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt)
void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event);
-
#endif
diff --git a/block/cow.c b/block/cow.c
index a5a00eb..eb1bce6 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -255,7 +255,7 @@ static void cow_close(BlockDriverState *bs)
{
}
-static int cow_create(const char *filename, QEMUOptionParameter *options)
+static int cow_create(const char *filename, QemuOpts *opts)
{
struct cow_header_v2 cow_header;
struct stat st;
@@ -264,17 +264,11 @@ static int cow_create(const char *filename, QEMUOptionParameter *options)
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++;
- }
+ /* Read out opts */
+ image_sectors = qemu_opt_get_number(opts, BLOCK_OPT_SIZE, 0) / 512;
+ image_filename = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
- ret = bdrv_create_file(filename, options);
+ ret = bdrv_create_file(filename, opts);
if (ret < 0) {
return ret;
}
@@ -318,20 +312,29 @@ exit:
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_NUMBER,
+ .help = "Virtual disk size"
+ },
+ {
+ .name = BLOCK_OPT_BACKING_FILE,
+ .type = QEMU_OPT_STRING,
+ .help = "File name of a base image"
+ },
+ { /* end of list */ }
+ }
};
+static QemuOptsList *cow_create_options(void)
+{
+ return &cow_create_opts;
+}
+
static BlockDriver bdrv_cow = {
.format_name = "cow",
.instance_size = sizeof(BDRVCowState),
@@ -345,7 +348,7 @@ static BlockDriver bdrv_cow = {
.bdrv_write = cow_co_write,
.bdrv_co_is_allocated = cow_co_is_allocated,
- .create_options = cow_create_options,
+ .bdrv_create_options = cow_create_options,
};
static void bdrv_cow_init(void)
diff --git a/block/qcow.c b/block/qcow.c
index b239c82..fa0583c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -651,7 +651,7 @@ static void qcow_close(BlockDriverState *bs)
error_free(s->migration_blocker);
}
-static int qcow_create(const char *filename, QEMUOptionParameter *options)
+static int qcow_create(const char *filename, QemuOpts *opts)
{
int header_size, backing_filename_len, l1_size, shift, i;
QCowHeader header;
@@ -662,19 +662,14 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options)
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++;
+ /* Read out opts */
+ total_size = qemu_opt_get_number(opts, BLOCK_OPT_SIZE, 0) / 512;
+ backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+ if (qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, 0)) {
+ flags |= BLOCK_FLAG_ENCRYPT;
}
- ret = bdrv_create_file(filename, options);
+ ret = bdrv_create_file(filename, opts);
if (ret < 0) {
return ret;
}
@@ -851,25 +846,32 @@ 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_NUMBER,
+ .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"
+ },
+ { /* end of list */ }
+ }
};
+static QemuOptsList *qcow_create_options(void)
+{
+ return &qcow_create_opts;
+}
static BlockDriver bdrv_qcow = {
.format_name = "qcow",
@@ -889,7 +891,7 @@ static BlockDriver bdrv_qcow = {
.bdrv_write_compressed = qcow_write_compressed,
.bdrv_get_info = qcow_get_info,
- .create_options = qcow_create_options,
+ .bdrv_create_options = qcow_create_options,
};
static void bdrv_qcow_init(void)
diff --git a/block/qcow2.c b/block/qcow2.c
index c1ff31f..54bda70 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1180,7 +1180,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)
{
/* Calculate cluster_bits */
int cluster_bits;
@@ -1211,7 +1211,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
uint8_t* refcount_table;
int ret;
- ret = bdrv_create_file(filename, options);
+ ret = bdrv_create_file(filename, NULL);
if (ret < 0) {
return ret;
}
@@ -1314,7 +1314,7 @@ out:
return ret;
}
-static int qcow2_create(const char *filename, QEMUOptionParameter *options)
+static int qcow2_create(const char *filename, QemuOpts *opts)
{
const char *backing_file = NULL;
const char *backing_fmt = NULL;
@@ -1323,45 +1323,41 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
size_t cluster_size = DEFAULT_CLUSTER_SIZE;
int prealloc = 0;
int version = 2;
+ const char *buf;
/* 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 {
- fprintf(stderr, "Invalid preallocation mode: '%s'\n",
- options->value.s);
- return -EINVAL;
- }
- } else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
- if (!options->value.s || !strcmp(options->value.s, "0.10")) {
- version = 2;
- } else if (!strcmp(options->value.s, "1.1")) {
- version = 3;
- } else {
- fprintf(stderr, "Invalid compatibility level: '%s'\n",
- 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_number(opts, BLOCK_OPT_SIZE, 0) / 512;
+ backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+ backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
+ if (qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, 0)) {
+ flags |= BLOCK_FLAG_ENCRYPT;
+ }
+ cluster_size =
+ qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, DEFAULT_CLUSTER_SIZE);
+ buf = qemu_opt_get(opts, BLOCK_OPT_PREALLOC);
+ if (!buf || !strcmp(buf, "off")) {
+ prealloc = 0;
+ } else if (!strcmp(buf, "metadata")) {
+ prealloc = 1;
+ } else {
+ fprintf(stderr, "Invalid preallocation mode: '%s'\n",
+ buf);
+ return -EINVAL;
+ }
+
+ buf = qemu_opt_get(opts, BLOCK_OPT_COMPAT_LEVEL);
+ if (!buf || !strcmp(buf, "0.10")) {
+ version = 2;
+ } else if (!strcmp(buf, "1.1")) {
+ version = 3;
+ } else {
+ fprintf(stderr, "Invalid compatibility level: '%s'\n",
+ buf);
+ return -EINVAL;
+ }
+
+ if (qemu_opt_get_bool(opts, BLOCK_OPT_LAZY_REFCOUNTS, 0)) {
+ flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
}
if (backing_file && prealloc) {
@@ -1377,7 +1373,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
}
return qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
- cluster_size, prealloc, options, version);
+ cluster_size, prealloc, opts, version);
}
static int qcow2_make_empty(BlockDriverState *bs)
@@ -1638,51 +1634,60 @@ static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
return ret;
}
-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_NUMBER,
+ .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"
+ },
+ {
+ .name = BLOCK_OPT_CLUSTER_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "qcow2 cluster size",
+ .def_value = 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",
+ },
+ { /* end of list */ }
+ }
};
+static QemuOptsList *qcow2_create_options(void)
+{
+ return &qcow2_create_opts;
+}
+
static BlockDriver bdrv_qcow2 = {
.format_name = "qcow2",
.instance_size = sizeof(BDRVQcowState),
@@ -1718,8 +1723,9 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_invalidate_cache = qcow2_invalidate_cache,
- .create_options = qcow2_create_options,
.bdrv_check = qcow2_check,
+
+ .bdrv_create_options = qcow2_create_options,
};
static void bdrv_qcow2_init(void)
diff --git a/block/qed.c b/block/qed.c
index 6c182ca..0a9dbe8 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -603,7 +603,7 @@ out:
return ret;
}
-static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options)
+static int bdrv_qed_create(const char *filename, QemuOpts *opts)
{
uint64_t image_size = 0;
uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
@@ -611,24 +611,14 @@ static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options)
const char *backing_file = NULL;
const char *backing_fmt = NULL;
- 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_number(opts, BLOCK_OPT_SIZE, 0);
+ backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+ backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
+ cluster_size = qemu_opt_get_size(opts,
+ BLOCK_OPT_CLUSTER_SIZE,
+ QED_DEFAULT_CLUSTER_SIZE);
+ table_size =
+ qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, QED_DEFAULT_TABLE_SIZE);
if (!qed_is_cluster_size_valid(cluster_size)) {
fprintf(stderr, "QED cluster size must be within range [%u, %u] and power of 2\n",
@@ -1537,36 +1527,48 @@ 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_NUMBER,
+ .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 = QED_DEFAULT_CLUSTER_SIZE,
+ },
+ {
+ .name = BLOCK_OPT_TABLE_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "L1/L2 table size (in clusters)"
+ },
+ { /* end of list */ }
+ }
};
+static QemuOptsList *qed_create_options(void)
+{
+ return &qed_create_opts;
+}
static BlockDriver bdrv_qed = {
.format_name = "qed",
.instance_size = sizeof(BDRVQEDState),
- .create_options = qed_create_options,
+ .bdrv_create_options = qed_create_options,
.bdrv_probe = bdrv_qed_probe,
.bdrv_rebind = bdrv_qed_rebind,
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 28d439f..e9a9c07 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -118,6 +118,19 @@
#define MAX_BLOCKSIZE 4096
+static QemuOptsList file_proto_create_opts = {
+ .name = "file-proto-create-opts",
+ .head = QTAILQ_HEAD_INITIALIZER(file_proto_create_opts.head),
+ .desc = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Virtual disk size"
+ },
+ { /* end of list */ }
+ }
+};
+
typedef struct BDRVRawState {
int fd;
int type;
@@ -674,19 +687,14 @@ 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)
+static int raw_create(const char *filename, QemuOpts *opts)
{
int fd;
int result = 0;
int64_t total_size = 0;
- /* 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_number(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
@@ -836,14 +844,10 @@ static coroutine_fn int raw_co_discard(BlockDriverState *bs,
return 0;
}
-static QEMUOptionParameter raw_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
- },
- { NULL }
-};
+static QemuOptsList *raw_create_options(void)
+{
+ return &file_proto_create_opts;
+}
static BlockDriver bdrv_file = {
.format_name = "file",
@@ -867,8 +871,7 @@ static BlockDriver bdrv_file = {
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
-
- .create_options = raw_create_options,
+ .bdrv_create_options = raw_create_options,
};
/***********************************************/
@@ -1081,20 +1084,15 @@ static int fd_open(BlockDriverState *bs)
#endif /* !linux && !FreeBSD */
-static int hdev_create(const char *filename, QEMUOptionParameter *options)
+static int hdev_create(const char *filename, QemuOpts *opts)
{
int fd;
int ret = 0;
struct stat stat_buf;
int64_t total_size = 0;
- /* 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_number(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
fd = qemu_open(filename, O_WRONLY | O_BINARY);
if (fd < 0)
@@ -1118,23 +1116,23 @@ static int hdev_has_zero_init(BlockDriverState *bs)
static BlockDriver bdrv_host_device = {
.format_name = "host_device",
- .protocol_name = "host_device",
+ .protocol_name = "host_device",
.instance_size = sizeof(BDRVRawState),
.bdrv_probe_device = hdev_probe_device,
.bdrv_file_open = hdev_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
- .create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
- .bdrv_aio_readv = raw_aio_readv,
- .bdrv_aio_writev = raw_aio_writev,
- .bdrv_aio_flush = raw_aio_flush,
+ .bdrv_aio_readv = raw_aio_readv,
+ .bdrv_aio_writev = raw_aio_writev,
+ .bdrv_aio_flush = raw_aio_flush,
.bdrv_truncate = raw_truncate,
- .bdrv_getlength = raw_getlength,
+ .bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
+ .bdrv_create_options = raw_create_options,
/* generic scsi device */
#ifdef __linux__
@@ -1245,7 +1243,6 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_file_open = floppy_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
- .create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_aio_readv = raw_aio_readv,
@@ -1261,6 +1258,7 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_is_inserted = floppy_is_inserted,
.bdrv_media_changed = floppy_media_changed,
.bdrv_eject = floppy_eject,
+ .bdrv_create_options = raw_create_options,
};
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
@@ -1344,7 +1342,6 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_file_open = cdrom_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
- .create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_aio_readv = raw_aio_readv,
@@ -1364,6 +1361,8 @@ static BlockDriver bdrv_host_cdrom = {
/* generic scsi device */
.bdrv_ioctl = hdev_ioctl,
.bdrv_aio_ioctl = hdev_aio_ioctl,
+
+ .bdrv_create_options = raw_create_options,
};
#endif /* __linux__ */
@@ -1463,7 +1462,6 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_file_open = cdrom_open,
.bdrv_close = raw_close,
.bdrv_create = hdev_create,
- .create_options = raw_create_options,
.bdrv_has_zero_init = hdev_has_zero_init,
.bdrv_aio_readv = raw_aio_readv,
diff --git a/block/raw.c b/block/raw.c
index 253e949..68b1cc9 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -95,25 +95,34 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
}
-static int raw_create(const char *filename, QEMUOptionParameter *options)
+static int raw_create(const char *filename, QemuOpts *options)
{
return bdrv_create_file(filename, options);
}
-static QEMUOptionParameter raw_create_options[] = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = OPT_SIZE,
- .help = "Virtual disk size"
- },
- { NULL }
-};
-
static int raw_has_zero_init(BlockDriverState *bs)
{
return bdrv_has_zero_init(bs->file);
}
+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_NUMBER,
+ .help = "Virtual disk size"
+ },
+ { /* end of list */ }
+ }
+};
+
+static QemuOptsList *raw_create_options(void)
+{
+ return &raw_create_opts;
+}
+
static BlockDriver bdrv_raw = {
.format_name = "raw",
@@ -143,8 +152,8 @@ static BlockDriver bdrv_raw = {
.bdrv_aio_ioctl = raw_aio_ioctl,
.bdrv_create = raw_create,
- .create_options = raw_create_options,
.bdrv_has_zero_init = raw_has_zero_init,
+ .bdrv_create_options = raw_create_options,
};
static void bdrv_raw_init(void)
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 9306174..8fd0ef4 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1261,12 +1261,12 @@ out:
return ret;
}
-static int sd_create(const char *filename, QEMUOptionParameter *options)
+static int sd_create(const char *filename, QemuOpts *opts)
{
int ret = 0;
uint32_t vid = 0, base_vid = 0;
int64_t vdi_size = 0;
- char *backing_file = NULL;
+ const char *backing_file = NULL, *buf = NULL;
BDRVSheepdogState *s;
char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid;
@@ -1285,26 +1285,18 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
goto out;
}
- while (options && options->name) {
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
- 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_report("Invalid preallocation mode: '%s'",
- options->value.s);
- ret = -EINVAL;
- goto out;
- }
- }
- options++;
+ vdi_size = qemu_opt_get_number(opts, BLOCK_OPT_SIZE, 0);
+ backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+ buf = qemu_opt_get(opts, BLOCK_OPT_PREALLOC);
+ if (!buf || !strcmp(buf, "off")) {
+ prealloc = false;
+ } else if (!strcmp(buf, "full")) {
+ prealloc = true;
+ } else {
+ error_report("Invalid preallocation mode: '%s'", buf);
+ ret = -EINVAL;
+ goto out;
}
-
if (vdi_size > SD_MAX_VDI_SIZE) {
error_report("too big image size");
ret = -EINVAL;
@@ -2040,26 +2032,34 @@ static int sd_load_vmstate(BlockDriverState *bs, uint8_t *data,
return do_load_save_vmstate(s, data, pos, size, 1);
}
-
-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)"
- },
- { 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_NUMBER,
+ .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)"
+ },
+ { /* end of list */ }
+ }
};
+static QemuOptsList *sd_create_options(void)
+{
+ return &sd_create_opts;
+}
+
BlockDriver bdrv_sheepdog = {
.format_name = "sheepdog",
.protocol_name = "sheepdog",
@@ -2082,7 +2082,7 @@ BlockDriver bdrv_sheepdog = {
.bdrv_save_vmstate = sd_save_vmstate,
.bdrv_load_vmstate = sd_load_vmstate,
- .create_options = sd_create_options,
+ .bdrv_create_options = sd_create_options,
};
static void bdrv_sheepdog_init(void)
diff --git a/block/vdi.c b/block/vdi.c
index f35b12e..758024c 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -623,7 +623,7 @@ static int vdi_co_write(BlockDriverState *bs,
return ret;
}
-static int vdi_create(const char *filename, QEMUOptionParameter *options)
+static int vdi_create(const char *filename, QemuOpts *opts)
{
int fd;
int result = 0;
@@ -638,25 +638,17 @@ 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_number(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;
- }
+ block_size = qemu_opt_get_size(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(opts, BLOCK_OPT_ENCRYPT, 0)) {
+ image_type = VDI_TYPE_STATIC;
}
+#endif
fd = qemu_open(filename,
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
@@ -736,31 +728,40 @@ 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_NUMBER,
+ .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_val = 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"
+ },
#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 QemuOptsList *vdi_create_options(void)
+{
+ return &vdi_create_opts;
+}
+
static BlockDriver bdrv_vdi = {
.format_name = "vdi",
.instance_size = sizeof(BDRVVdiState),
@@ -779,7 +780,7 @@ static BlockDriver bdrv_vdi = {
.bdrv_get_info = vdi_get_info,
- .create_options = vdi_create_options,
+ .bdrv_create_options = vdi_create_options,
.bdrv_check = vdi_check,
};
diff --git a/block/vmdk.c b/block/vmdk.c
index 1a80e5a..c5b866f 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1431,7 +1431,7 @@ static int relative_path(char *dest, int dest_size,
return 0;
}
-static int vmdk_create(const char *filename, QEMUOptionParameter *options)
+static int vmdk_create(const char *filename, QemuOpts *opts)
{
int fd, idx = 0;
char desc[BUF_SIZE];
@@ -1470,19 +1470,13 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
return -EINVAL;
}
- /* 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_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;
- }
- options++;
+ /* Read out opts */
+ total_size = qemu_opt_get_number(opts, BLOCK_OPT_SIZE, 0);
+ backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
+ if (qemu_opt_get_bool(opts, BLOCK_OPT_COMPAT6, 0)) {
+ flags |= BLOCK_FLAG_COMPAT6;
}
+ fmt = qemu_opt_get(opts, BLOCK_OPT_SUBFMT);
if (!fmt) {
/* Default format to monolithicSparse */
fmt = "monolithicSparse";
@@ -1648,32 +1642,41 @@ static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
return ret;
}
-static QEMUOptionParameter vmdk_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_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} "
- },
- { 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_NUMBER,
+ .help = "Virtual disk size"
+ },
+ {
+ .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"
+ },
+ {
+ .name = BLOCK_OPT_SUBFMT,
+ .type = QEMU_OPT_STRING,
+ .help =
+ "VMDK flat extent format, can be one of "
+ "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
+ },
+ { /* end of list */ }
+ }
};
+static QemuOptsList *vmdk_create_options(void)
+{
+ return &vmdk_create_opts;
+}
+
static BlockDriver bdrv_vmdk = {
.format_name = "vmdk",
.instance_size = sizeof(BDRVVmdkState),
@@ -1688,7 +1691,7 @@ static BlockDriver bdrv_vmdk = {
.bdrv_co_is_allocated = vmdk_co_is_allocated,
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
- .create_options = vmdk_create_options,
+ .bdrv_create_options = vmdk_create_options,
};
static void bdrv_vmdk_init(void)
diff --git a/block/vpc.c b/block/vpc.c
index b6bf52f..f1fd5dc 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -653,11 +653,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)
+static int vpc_create(const char *filename, QemuOpts *opts)
{
uint8_t buf[1024];
struct vhd_footer *footer = (struct vhd_footer *) buf;
- QEMUOptionParameter *disk_type_param;
+ const char *disk_type_param;
int fd, i;
uint16_t cyls = 0;
uint8_t heads = 0;
@@ -667,14 +667,13 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options)
int disk_type;
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")) {
+ /* Read out opts */
+ total_size = qemu_opt_get_number(opts, BLOCK_OPT_SIZE, 0);
+ disk_type_param = qemu_opt_get(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;
@@ -766,22 +765,31 @@ 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_NUMBER,
+ .help = "Virtual disk size"
+ },
+ {
+ .name = BLOCK_OPT_SUBFMT,
+ .type = OPT_STRING,
+ .help =
+ "Type of virtual hard disk format. Supported formats are "
+ "{dynamic (default) | fixed} "
+ },
+ { /* end of list */ }
+ }
};
+static QemuOptsList *vpc_create_options(void)
+{
+ return &vpc_create_opts;
+}
+
static BlockDriver bdrv_vpc = {
.format_name = "vpc",
.instance_size = sizeof(BDRVVPCState),
@@ -795,7 +803,7 @@ static BlockDriver bdrv_vpc = {
.bdrv_read = vpc_co_read,
.bdrv_write = vpc_co_write,
- .create_options = vpc_create_options,
+ .bdrv_create_options = vpc_create_options,
};
static void bdrv_vpc_init(void)
diff --git a/block/vvfat.c b/block/vvfat.c
index 59d3c5b..94c1821 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2806,7 +2806,7 @@ static BlockDriver vvfat_write_target = {
static int enable_write_target(BDRVVVFATState *s)
{
BlockDriver *bdrv_qcow;
- QEMUOptionParameter *options;
+ QemuOpts *opts;
int ret;
int size = sector2cluster(s, s->sector_count);
s->used_clusters = calloc(size, 1);
@@ -2822,12 +2822,13 @@ static int enable_write_target(BDRVVVFATState *s)
}
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:");
+ opts = qemu_opts_create_nofail(bdrv_qcow->bdrv_create_options());
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
- if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
+ if (bdrv_create(bdrv_qcow, s->qcow_filename, opts) < 0) {
return -1;
+ }
s->qcow = bdrv_new("");
if (s->qcow == NULL) {
diff --git a/block_int.h b/block_int.h
index f4bae04..a104e70 100644
--- a/block_int.h
+++ b/block_int.h
@@ -88,7 +88,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);
+ int (*bdrv_create)(const char *filename, QemuOpts *options);
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
int (*bdrv_make_empty)(BlockDriverState *bs);
/* aio */
@@ -177,9 +177,7 @@ struct BlockDriver {
unsigned long int req, void *buf,
BlockDriverCompletionFunc *cb, void *opaque);
- /* List of options for creating images, terminated by name == NULL */
- QEMUOptionParameter *create_options;
-
+ QemuOptsList *(*bdrv_create_options)(void);
/*
* Returns 0 for completed check, -errno for internal errors.
diff --git a/qemu-img.c b/qemu-img.c
index f1c224e..05d05e8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -200,7 +200,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_options = NULL;
/* Find driver and parse its options */
drv = bdrv_find_format(fmt);
@@ -215,12 +215,10 @@ static int print_block_option_help(const char *filename, const char *fmt)
return 1;
}
- create_options = append_option_parameters(create_options,
- drv->create_options);
- create_options = append_option_parameters(create_options,
- proto_drv->create_options);
- print_option_help(create_options);
- free_option_parameters(create_options);
+ create_options = append_opts_list(drv->bdrv_create_options(),
+ proto_drv->bdrv_create_options());
+ print_opts_list(create_options);
+ free_opts_list(create_options);
return 0;
}
@@ -271,19 +269,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 *list,
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(list, BLOCK_OPT_BACKING_FILE, base_filename)) {
error_report("Backing file not supported for file format '%s'",
fmt);
return -1;
}
}
if (base_fmt) {
- if (set_option_parameter(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
+ if (qemu_opt_set(list, BLOCK_OPT_BACKING_FMT, base_fmt)) {
error_report("Backing file format not supported for file "
"format '%s'", fmt);
return -1;
@@ -670,8 +668,9 @@ static int img_convert(int argc, char **argv)
uint8_t * buf = NULL;
const uint8_t *buf1;
BlockDriverInfo bdi;
- QEMUOptionParameter *param = NULL, *create_options = NULL;
- QEMUOptionParameter *out_baseimg_param;
+ QemuOpts *param = NULL;
+ QemuOptsList *create_options = NULL;
+ const char *out_baseimg_param;
char *options = NULL;
const char *snapshot_name = NULL;
float local_progress;
@@ -806,40 +805,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_options = append_opts_list(drv->bdrv_create_options(),
+ proto_drv->bdrv_create_options());
if (options) {
- param = parse_option_parameters(options, create_options, param);
- if (param == NULL) {
+ if (qemu_opts_do_parse(param, options, NULL) != 0) {
error_report("Invalid options for file format '%s'.", out_fmt);
ret = -1;
goto out;
}
} else {
- param = parse_option_parameters("", create_options, param);
+ param = qemu_opts_create(create_options, NULL, 0, NULL);
}
-
- set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
+ qemu_opt_set_number(param, BLOCK_OPT_SIZE, total_sectors * 512);
ret = add_old_style_options(out_fmt, param, 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(param, 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);
+ const char *encryption =
+ qemu_opt_get(param, BLOCK_OPT_ENCRYPT);
+ const char *preallocation =
+ qemu_opt_get(param, BLOCK_OPT_PREALLOC);
if (!drv->bdrv_write_compressed) {
error_report("Compression not supported for this file format");
@@ -847,15 +842,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");
@@ -1069,8 +1064,10 @@ static int img_convert(int argc, char **argv)
}
out:
qemu_progress_end();
- free_option_parameters(create_options);
- free_option_parameters(param);
+ free_opts_list(create_options);
+ if (param) {
+ qemu_opts_del(param);
+ }
qemu_vfree(buf);
if (out_bs) {
bdrv_delete(out_bs);
diff --git a/qemu-option.c b/qemu-option.c
index ab270f0..c391f7d 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -553,10 +553,15 @@ 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)
{
- QemuOpt *opt = qemu_opt_find(opts, name);
+ QemuOpt *opt;
+ if (!opts) {
+ return defval;
+ }
+ opt = qemu_opt_find(opts, name);
- if (opt == NULL)
+ if (opt == NULL) {
return defval;
+ }
assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
return opt->value.uint;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH V4 10/10] remove QEMUOptionParameter related functions and struct
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
` (8 preceding siblings ...)
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 09/10] Use QemuOpts support in block layer Dong Xu Wang
@ 2012-10-25 12:57 ` Dong Xu Wang
9 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-25 12:57 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, Dong Xu Wang
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
qemu-option.c | 285 ---------------------------------------------------------
qemu-option.h | 32 -------
2 files changed, 0 insertions(+), 317 deletions(-)
diff --git a/qemu-option.c b/qemu-option.c
index c391f7d..cc34a68 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -153,22 +153,6 @@ int check_params(char *buf, int buf_size,
return 0;
}
-/*
- * 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)
{
@@ -240,275 +224,6 @@ static 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 (!error_is_set(&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 (error_is_set(&local_err)) {
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
- }
-
- 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;
- }
-
- 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;
-
- if (list == NULL) {
- return NULL;
- }
-
- if (dest == NULL) {
- dest = allocated = append_option_parameters(NULL, list);
- }
-
- 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;
-}
-
-/*
- * 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++;
- }
-}
-
/* ------------------------------------------------------------------ */
static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
diff --git a/qemu-option.h b/qemu-option.h
index d1825ee..4ce762b 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -38,17 +38,6 @@ enum QEMUOptionParType {
OPT_STRING,
};
-typedef struct QEMUOptionParameter {
- const char *name;
- enum QEMUOptionParType type;
- union {
- uint64_t n;
- char* s;
- } value;
- const char *help;
-} 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,27 +47,6 @@ int get_param_value(char *buf, int buf_size,
int check_params(char *buf, int buf_size,
const char * const *params, 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 free_option_parameters(QEMUOptionParameter *list);
-void print_option_parameters(QEMUOptionParameter *list);
-void print_option_help(QEMUOptionParameter *list);
-
/* ------------------------------------------------------------------ */
typedef struct QemuOpt QemuOpt;
--
1.7.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH V4 04/10] introduce qemu_opts_create_nofail function
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 04/10] introduce qemu_opts_create_nofail function Dong Xu Wang
@ 2012-10-25 13:06 ` Peter Maydell
2012-10-26 2:46 ` Dong Xu Wang
0 siblings, 1 reply; 17+ messages in thread
From: Peter Maydell @ 2012-10-25 13:06 UTC (permalink / raw)
To: Dong Xu Wang; +Cc: kwolf, qemu-devel
On 25 October 2012 13:57, Dong Xu Wang <wdongxu@linux.vnet.ibm.com> wrote:
> While id is NULL, qemu_opts_create can not fail, so ignore
> errors is fine.
>
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> ---
> qemu-option.c | 5 +++++
> qemu-option.h | 1 +
> 2 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/qemu-option.c b/qemu-option.c
> index e0131ce..d7d5ea9 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -780,6 +780,11 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
> return opts;
> }
>
> +QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
> +{
> + return qemu_opts_create(list, NULL, 0, NULL);
> +}
_nofail versions of routines generally abort() if the function
they are wrapping returns an error (compare qemu_ram_addr_from_host_nofail
or qdev_init_nofail). This code just ignores the error. Although
as you say at the moment there is nothing that sets an error
in the id==NULL case this is somewhat vulnerable to future code
changes in the function it calls.
I think this would be better as:
{
QemuOpts *opts;
Error *errp = NULL;
opts = qemu_opts_create(list, NULL, 0, &errp);
assert_no_error(errp);
return opts;
}
-- PMM
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH V4 04/10] introduce qemu_opts_create_nofail function
2012-10-25 13:06 ` Peter Maydell
@ 2012-10-26 2:46 ` Dong Xu Wang
0 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-26 2:46 UTC (permalink / raw)
To: Peter Maydell; +Cc: kwolf, qemu-devel
On Thu, Oct 25, 2012 at 9:06 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 25 October 2012 13:57, Dong Xu Wang <wdongxu@linux.vnet.ibm.com> wrote:
>> While id is NULL, qemu_opts_create can not fail, so ignore
>> errors is fine.
>>
>> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
>> ---
>> qemu-option.c | 5 +++++
>> qemu-option.h | 1 +
>> 2 files changed, 6 insertions(+), 0 deletions(-)
>>
>> diff --git a/qemu-option.c b/qemu-option.c
>> index e0131ce..d7d5ea9 100644
>> --- a/qemu-option.c
>> +++ b/qemu-option.c
>> @@ -780,6 +780,11 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
>> return opts;
>> }
>>
>> +QemuOpts *qemu_opts_create_nofail(QemuOptsList *list)
>> +{
>> + return qemu_opts_create(list, NULL, 0, NULL);
>> +}
>
> _nofail versions of routines generally abort() if the function
> they are wrapping returns an error (compare qemu_ram_addr_from_host_nofail
> or qdev_init_nofail). This code just ignores the error. Although
> as you say at the moment there is nothing that sets an error
> in the id==NULL case this is somewhat vulnerable to future code
> changes in the function it calls.
>
> I think this would be better as:
>
> {
> QemuOpts *opts;
> Error *errp = NULL;
> opts = qemu_opts_create(list, NULL, 0, &errp);
> assert_no_error(errp);
> return opts;
> }
Okay, will do that in next version, thank you Peter.
>
> -- PMM
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH V4 06/10] create new function: qemu_opt_set_number
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 06/10] create new function: qemu_opt_set_number Dong Xu Wang
@ 2012-10-26 9:02 ` Stefan Hajnoczi
2012-10-29 8:03 ` Dong Xu Wang
0 siblings, 1 reply; 17+ messages in thread
From: Stefan Hajnoczi @ 2012-10-26 9:02 UTC (permalink / raw)
To: Dong Xu Wang; +Cc: kwolf, qemu-devel
On Thu, Oct 25, 2012 at 08:57:24PM +0800, Dong Xu Wang wrote:
> diff --git a/qemu-option.c b/qemu-option.c
> index d7d5ea9..eeb2c9c 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -695,6 +695,30 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
> return 0;
> }
>
> +int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
> +{
> + char buffer[1024];
> + QemuOpt *opt;
> + const QemuOptDesc *desc = opts->list->desc;
> +
> + snprintf(buffer, sizeof(buffer), "%" PRId64, val);
g_strdup_printf() is a nice replacement for fixed-size buffer +
snprintf() + g_strdup():
http://developer.gnome.org/glib/2.28/glib-String-Utility-Functions.html#g-strdup-printf
Stefan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH V4 07/10] add def_value and use it in qemu_opts_print.
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 07/10] add def_value and use it in qemu_opts_print Dong Xu Wang
@ 2012-10-26 9:32 ` Stefan Hajnoczi
0 siblings, 0 replies; 17+ messages in thread
From: Stefan Hajnoczi @ 2012-10-26 9:32 UTC (permalink / raw)
To: Dong Xu Wang; +Cc: kwolf, qemu-devel
On Thu, Oct 25, 2012 at 08:57:25PM +0800, Dong Xu Wang wrote:
> qemu_opts_print has no user now, so I re-write it and use it in
> qemu-img.c.
>
> qemu_opts_print will be used while using "qemu-img create", it will
> produce the same output as previous code.
>
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> ---
> qemu-option.c | 41 ++++++++++++++++++++++++++++++++---------
> qemu-option.h | 1 +
> 2 files changed, 33 insertions(+), 9 deletions(-)
The behavior of this function has changed. I think you are trying to
achieve the following:
1. Print every possible option, whether a value has been set or not.
2. Option descriptors may provide a default value.
3. Print to stdout instead of stderr.
Previously the behavior was to print every option that has been set.
Options that have not been set would be skipped.
Please include the intention behind the change either in the commit
description or in a doc comment before the function. It took me a while
to figure out "why" this change is useful.
> diff --git a/qemu-option.c b/qemu-option.c
> index eeb2c9c..54dbdd0 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -860,15 +860,38 @@ void qemu_opts_del(QemuOpts *opts)
>
> int qemu_opts_print(QemuOpts *opts, void *dummy)
> {
> - QemuOpt *opt;
> -
> - fprintf(stderr, "%s: %s:", opts->list->name,
> - opts->id ? opts->id : "<noid>");
> - QTAILQ_FOREACH(opt, &opts->head, next) {
> - fprintf(stderr, " %s=\"%s\"", opt->name, opt->str);
> - }
> - fprintf(stderr, "\n");
> - return 0;
> + QemuOpt *opt = NULL;
> + QemuOptDesc *desc = opts->list->desc;
> +
> + while (desc && desc->name) {
> + opt = qemu_opt_find(opts, desc->name);
> + switch (desc->type) {
> + case QEMU_OPT_STRING:
> + if (opt != NULL) {
> + printf("%s='%s' ", opt->name, opt->str);
> + }
> + break;
> + case QEMU_OPT_BOOL:
> + printf("%s=%s ", desc->name, (opt && opt->str) ? "on" : "off");
> + break;
> + case QEMU_OPT_NUMBER:
> + case QEMU_OPT_SIZE:
> + if (strcmp(desc->name, "cluster_size")) {
> + printf("%s=%" PRId64 " ", desc->name,
> + (opt && opt->value.uint) ? opt->value.uint : 0);
> + } else {
> + printf("%s=%" PRId64 " ", desc->name,
> + (opt && opt->value.uint) ?
> + opt->value.uint : desc->def_value);
> + }
> + break;
> + default:
> + printf("%s=(unknown type) ", desc->name);
> + break;
> + }
This is very specific to qemu-img output formatting. An idea to make
the formatting rules more general:
1. Strings are printed with '%s', other values are printed unquoted %s.
2. If the option has not been set, then def_print_str is used.
3. If the option has not been set and def_print_str is NULL then the
option is skipped.
The code becomes:
for (desc = opts->list->desc; desc && desc->name; desc++) {
const char *value = desc->def_print_str;
QemuOpt *opt;
opt = qemu_opt_find(opts, desc->name);
if (opt) {
value = opt->str;
}
if (!value) {
continue;
}
if (desc->type == QEMU_OPT_STRING) {
printf("%s='%s' ", desc->name, value);
} else {
printf("%s=%s ", desc->name, value);
}
}
If you want an option to print a default value, def_print_str must be
set. Otherwise the option is skipped when no value has been set.
> + desc++;
> + }
> + return 0;
> }
>
> static int opts_do_parse(QemuOpts *opts, const char *params,
> diff --git a/qemu-option.h b/qemu-option.h
> index 002dd07..9ea59cf 100644
> --- a/qemu-option.h
> +++ b/qemu-option.h
> @@ -96,6 +96,7 @@ typedef struct QemuOptDesc {
> const char *name;
> enum QemuOptType type;
> const char *help;
> + uint64_t def_value;
The name "def_value" suggests that this is used as a default value for
the option. In fact it's only used as the default value for printing.
I suggest calling it def_print_str.
Also, if you do the change I suggested above, then this becomes const
char * instead of being uint64_t - this way it can be used for any
option type (str, bool, number, size).
Stefan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH V4 09/10] Use QemuOpts support in block layer
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 09/10] Use QemuOpts support in block layer Dong Xu Wang
@ 2012-10-26 9:51 ` Stefan Hajnoczi
0 siblings, 0 replies; 17+ messages in thread
From: Stefan Hajnoczi @ 2012-10-26 9:51 UTC (permalink / raw)
To: Dong Xu Wang; +Cc: kwolf, qemu-devel
On Thu, Oct 25, 2012 at 08:57:27PM +0800, Dong Xu Wang wrote:
> @@ -177,9 +177,7 @@ struct BlockDriver {
> unsigned long int req, void *buf,
> BlockDriverCompletionFunc *cb, void *opaque);
>
> - /* List of options for creating images, terminated by name == NULL */
> - QEMUOptionParameter *create_options;
> -
> + QemuOptsList *(*bdrv_create_options)(void);
Why is .bdrv_create_options() a function? It would be less code for
BlockDrivers to have a pointer: QemuOptsList *.
> /* 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);
> + const char *encryption =
> + qemu_opt_get(param, BLOCK_OPT_ENCRYPT);
> + const char *preallocation =
> + qemu_opt_get(param, BLOCK_OPT_PREALLOC);
>
> if (!drv->bdrv_write_compressed) {
> error_report("Compression not supported for this file format");
> @@ -847,15 +842,15 @@ static int img_convert(int argc, char **argv)
> goto out;
> }
>
> - if (encryption && encryption->value.n) {
> + if (encryption) {
encryption=off will print an error here. We need to use
qemu_opt_get_bool().
> diff --git a/qemu-option.c b/qemu-option.c
> index ab270f0..c391f7d 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -553,10 +553,15 @@ 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)
> {
> - QemuOpt *opt = qemu_opt_find(opts, name);
> + QemuOpt *opt;
> + if (!opts) {
> + return defval;
> + }
> + opt = qemu_opt_find(opts, name);
>
> - if (opt == NULL)
> + if (opt == NULL) {
> return defval;
> + }
> assert(opt->desc && opt->desc->type == QEMU_OPT_NUMBER);
> return opt->value.uint;
> }
This should be a separate patch, but there is a problem with the change
anyway: all qemu_opt_*() functions assume QemuOpts *opts is non-NULL.
This change makes qemu_opt_get_number() inconsistent. This will lead to
bugs when people assume qemu_opt_get_bool() also handles opts == NULL,
for example.
Can the qemu-img/block callers make sure opts is never NULL or will that
add a lot of extra checks?
Stefan
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH V4 06/10] create new function: qemu_opt_set_number
2012-10-26 9:02 ` Stefan Hajnoczi
@ 2012-10-29 8:03 ` Dong Xu Wang
0 siblings, 0 replies; 17+ messages in thread
From: Dong Xu Wang @ 2012-10-29 8:03 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: kwolf, qemu-devel
On Fri, Oct 26, 2012 at 5:02 PM, Stefan Hajnoczi <stefanha@gmail.com> wrote:
> On Thu, Oct 25, 2012 at 08:57:24PM +0800, Dong Xu Wang wrote:
>> diff --git a/qemu-option.c b/qemu-option.c
>> index d7d5ea9..eeb2c9c 100644
>> --- a/qemu-option.c
>> +++ b/qemu-option.c
>> @@ -695,6 +695,30 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
>> return 0;
>> }
>>
>> +int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val)
>> +{
>> + char buffer[1024];
>> + QemuOpt *opt;
>> + const QemuOptDesc *desc = opts->list->desc;
>> +
>> + snprintf(buffer, sizeof(buffer), "%" PRId64, val);
>
> g_strdup_printf() is a nice replacement for fixed-size buffer +
> snprintf() + g_strdup():
>
> http://developer.gnome.org/glib/2.28/glib-String-Utility-Functions.html#g-strdup-printf
>
Okay.
> Stefan
>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-10-29 8:04 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-25 12:57 [Qemu-devel] [PATCH V4 00/10] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 01/10] qemu-option: opt_set(): split it up into more functions Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 02/10] qemu-option: qemu_opts_validate(): fix duplicated code Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 03/10] qemu-option: qemu_opt_set_bool(): fix code duplication Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 04/10] introduce qemu_opts_create_nofail function Dong Xu Wang
2012-10-25 13:06 ` Peter Maydell
2012-10-26 2:46 ` Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 05/10] use qemu_opts_create_nofail Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 06/10] create new function: qemu_opt_set_number Dong Xu Wang
2012-10-26 9:02 ` Stefan Hajnoczi
2012-10-29 8:03 ` Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 07/10] add def_value and use it in qemu_opts_print Dong Xu Wang
2012-10-26 9:32 ` Stefan Hajnoczi
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 08/10] Create four opts list related functions Dong Xu Wang
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 09/10] Use QemuOpts support in block layer Dong Xu Wang
2012-10-26 9:51 ` Stefan Hajnoczi
2012-10-25 12:57 ` [Qemu-devel] [PATCH V4 10/10] remove QEMUOptionParameter related functions and struct Dong Xu Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).