* [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig
@ 2020-11-11 14:25 Paolo Bonzini
2020-11-11 14:25 ` [PATCH 01/12] tests: convert check-qom-proplist to keyval Paolo Bonzini
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
This is yet another RFC on the command-line parsing overhaul. Here,
I'm switching HMP, -object and -readconfig away from QemuOpts. There are
pending QemuOpts and keyval patches that make the syntaxes the same
apart from:
- "implicit value" options (where the lack of value is turned
into "on" or "off"), which will be deprecated
- the processing of invalid, empty or overlong keys which can be considered
bugfixes.
Along the way, the object_add HMP command grows help support.
The plan on top of this is to also keyval-ify -M and -accel. The reason
for this, in my evil plan, is to allow for compound properties. These
compound properties would be used for replacements of options like -smp
(-M smp.xxx), -icount (-accel tcg,icount.xxx) and -chardev (as in -object
chardev-socket,addr.host).
Paolo
Paolo Bonzini (12):
tests: convert check-qom-proplist to keyval
keyval: introduce keyval_parse_into
hmp: replace "O" parser with keyval
qom: use qemu_printf to print help for user-creatable objects
hmp: special case help options for object_add
qemu-io: use keyval for -object parsing
qemu-nbd: use keyval for -object parsing
qemu-img: use keyval for -object parsing
qemu-config: add error propagation to qemu_config_parse
qemu-config: parse configuration files to a QDict
qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict
qemu: use keyval for -object parsing
block/blkdebug.c | 3 +-
hmp-commands.hx | 6 +-
include/qemu/config-file.h | 8 +-
include/qemu/option.h | 2 +
include/qom/object_interfaces.h | 45 +-----
monitor/hmp-cmds.c | 22 +--
monitor/hmp.c | 20 ++-
qemu-img.c | 258 +++++++-------------------------
qemu-io.c | 42 ++----
qemu-nbd.c | 42 ++----
qom/object_interfaces.c | 57 +------
softmmu/vl.c | 113 ++++++++------
tests/check-qom-proplist.c | 58 ++++---
util/keyval.c | 39 ++++-
util/qemu-config.c | 99 +++++++-----
util/qemu-option.c | 3 +-
16 files changed, 324 insertions(+), 493 deletions(-)
--
2.26.2
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 01/12] tests: convert check-qom-proplist to keyval
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 02/12] keyval: introduce keyval_parse_into Paolo Bonzini
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
The command-line creation test is using QemuOpts. Switch it to keyval,
since all the -object command line options will follow
qemu-storage-daemon and do the same.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
tests/check-qom-proplist.c | 58 +++++++++++++++++++++++++-------------
1 file changed, 38 insertions(+), 20 deletions(-)
diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c
index 1b76581980..8dba26fb3c 100644
--- a/tests/check-qom-proplist.c
+++ b/tests/check-qom-proplist.c
@@ -21,6 +21,8 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qobject.h"
#include "qom/object.h"
#include "qemu/module.h"
#include "qemu/option.h"
@@ -400,42 +402,58 @@ static void test_dummy_createlist(void)
static void test_dummy_createcmdl(void)
{
- QemuOpts *opts;
+ QDict *qdict;
DummyObject *dobj;
Error *err = NULL;
+ bool help;
const char *params = TYPE_DUMMY \
",id=dev0," \
"bv=yes,sv=Hiss hiss hiss,av=platypus";
- qemu_add_opts(&qemu_object_opts);
- opts = qemu_opts_parse(&qemu_object_opts, params, true, &err);
+ qdict = keyval_parse(params, "qom-type", &help, &err);
g_assert(err == NULL);
- g_assert(opts);
+ g_assert(qdict);
+ g_assert(!help);
- dobj = DUMMY_OBJECT(user_creatable_add_opts(opts, &err));
+ g_assert(user_creatable_add_dict(qdict, true, &err));
g_assert(err == NULL);
+ qobject_unref(qdict);
+
+ dobj = DUMMY_OBJECT(object_resolve_path_component(object_get_objects_root(),
+ "dev0"));
g_assert(dobj);
g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss");
g_assert(dobj->bv == true);
g_assert(dobj->av == DUMMY_PLATYPUS);
+ qdict = keyval_parse(params, "qom-type", &help, &err);
+ g_assert(!user_creatable_add_dict(qdict, true, &err));
+ g_assert(err);
+ g_assert(object_resolve_path_component(object_get_objects_root(), "dev0")
+ == OBJECT(dobj));
+ qobject_unref(qdict);
+ error_free(err);
+ err = NULL;
+
+ qdict = keyval_parse(params, "qom-type", &help, &err);
user_creatable_del("dev0", &error_abort);
+ g_assert(object_resolve_path_component(object_get_objects_root(), "dev0")
+ == NULL);
- object_unref(OBJECT(dobj));
-
- /*
- * cmdline-parsing via qemu_opts_parse() results in a QemuOpts entry
- * corresponding to the Object's ID to be added to the QemuOptsList
- * for objects. To avoid having this entry conflict with future
- * Objects using the same ID (which can happen in cases where
- * qemu_opts_parse() is used to parse the object params, such as
- * with hmp_object_add() at the time of this comment), we need to
- * check for this in user_creatable_del() and remove the QemuOpts if
- * it is present.
- *
- * The below check ensures this works as expected.
- */
- g_assert_null(qemu_opts_find(&qemu_object_opts, "dev0"));
+ g_assert(user_creatable_add_dict(qdict, true, &err));
+ g_assert(err == NULL);
+ qobject_unref(qdict);
+
+ dobj = DUMMY_OBJECT(object_resolve_path_component(object_get_objects_root(),
+ "dev0"));
+ g_assert(dobj);
+ g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss");
+ g_assert(dobj->bv == true);
+ g_assert(dobj->av == DUMMY_PLATYPUS);
+ g_assert(object_resolve_path_component(object_get_objects_root(), "dev0")
+ == OBJECT(dobj));
+
+ object_unparent(OBJECT(dobj));
}
static void test_dummy_badenum(void)
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 02/12] keyval: introduce keyval_parse_into
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
2020-11-11 14:25 ` [PATCH 01/12] tests: convert check-qom-proplist to keyval Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 03/12] hmp: replace "O" parser with keyval Paolo Bonzini
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Allow parsing multiple keyval sequences into the same dictionary (as will
become useful for -M) or simply allow using a dictionary that came from
somewhere else (e.g. in an HMP parsing handler).
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/option.h | 2 ++
util/keyval.c | 39 ++++++++++++++++++++++++++++++++-------
2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/include/qemu/option.h b/include/qemu/option.h
index f73e0dc7d9..092e291c37 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -147,6 +147,8 @@ void qemu_opts_print_help(QemuOptsList *list, bool print_caption);
void qemu_opts_free(QemuOptsList *list);
QemuOptsList *qemu_opts_append(QemuOptsList *dst, QemuOptsList *list);
+QDict *keyval_parse_into(QDict *qdict, const char *params, const char *implied_key,
+ bool *p_help, Error **errp);
QDict *keyval_parse(const char *params, const char *implied_key,
bool *help, Error **errp);
diff --git a/util/keyval.c b/util/keyval.c
index 76daab0885..dd93da1ce5 100644
--- a/util/keyval.c
+++ b/util/keyval.c
@@ -436,13 +436,12 @@ static QObject *keyval_listify(QDict *cur, GSList *key_of_cur, Error **errp)
* If @p_help is not NULL, store whether help is requested there.
* If @p_help is NULL and help is requested, fail.
*
- * On success, return a dictionary of the parsed keys and values.
+ * On success, return @dict, now filled with the parsed keys and values.
* On failure, store an error through @errp and return NULL.
*/
-QDict *keyval_parse(const char *params, const char *implied_key,
- bool *p_help, Error **errp)
+QDict *keyval_parse_into(QDict *qdict, const char *params, const char *implied_key,
+ bool *p_help, Error **errp)
{
- QDict *qdict = qdict_new();
QObject *listified;
g_autofree char *dup;
char *s;
@@ -452,7 +451,6 @@ QDict *keyval_parse(const char *params, const char *implied_key,
while (*s) {
s = keyval_parse_one(qdict, s, implied_key, &help, errp);
if (!s) {
- qobject_unref(qdict);
return NULL;
}
implied_key = NULL;
@@ -462,15 +460,42 @@ QDict *keyval_parse(const char *params, const char *implied_key,
*p_help = help;
} else if (help) {
error_setg(errp, "Help is not available for this option");
- qobject_unref(qdict);
return NULL;
}
listified = keyval_listify(qdict, NULL, errp);
if (!listified) {
- qobject_unref(qdict);
return NULL;
}
assert(listified == QOBJECT(qdict));
return qdict;
}
+
+/*
+ * Parse @params in QEMU's traditional KEY=VALUE,... syntax.
+ *
+ * If @implied_key, the first KEY= can be omitted. @implied_key is
+ * implied then, and VALUE can't be empty or contain ',' or '='.
+ *
+ * A parameter "help" or "?" without a value isn't added to the
+ * resulting dictionary, but instead is interpreted as help request.
+ * All other options are parsed and returned normally so that context
+ * specific help can be printed.
+ *
+ * If @p_help is not NULL, store whether help is requested there.
+ * If @p_help is NULL and help is requested, fail.
+ *
+ * On success, return a dictionary of the parsed keys and values.
+ * On failure, store an error through @errp and return NULL.
+ */
+QDict *keyval_parse(const char *params, const char *implied_key,
+ bool *p_help, Error **errp)
+{
+ QDict *qdict = qdict_new();
+ QDict *ret = keyval_parse_into(qdict, params, implied_key, p_help, errp);
+
+ if (!ret) {
+ qobject_unref(qdict);
+ }
+ return ret;
+}
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 03/12] hmp: replace "O" parser with keyval
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
2020-11-11 14:25 ` [PATCH 01/12] tests: convert check-qom-proplist to keyval Paolo Bonzini
2020-11-11 14:25 ` [PATCH 02/12] keyval: introduce keyval_parse_into Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 04/12] qom: use qemu_printf to print help for user-creatable objects Paolo Bonzini
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
HMP is using QemuOpts to parse free-form commands device_add,
netdev_add and object_add. However, none of these need QemuOpts
for validation (these three QemuOptsLists are all of the catch-all
kind), and keyval is already able to parse into QDict. So use
keyval directly, avoiding the detour from
string to QemuOpts to QDict.
The args_type now stores the implied key. This arguably makes more
sense than storing the QemuOptsList name; at least, it _is_ a key
that might end up in the arguments QDict.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hmp-commands.hx | 6 +++---
monitor/hmp.c | 20 +++++++++-----------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index ff2d7aa8f3..35ecd0d9ca 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -668,7 +668,7 @@ ERST
{
.name = "device_add",
- .args_type = "device:O",
+ .args_type = "driver:O",
.params = "driver[,prop=value][,...]",
.help = "add device, like -device on the command line",
.cmd = hmp_device_add,
@@ -1314,7 +1314,7 @@ ERST
{
.name = "netdev_add",
- .args_type = "netdev:O",
+ .args_type = "type:O",
.params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
.help = "add host network device",
.cmd = hmp_netdev_add,
@@ -1342,7 +1342,7 @@ ERST
{
.name = "object_add",
- .args_type = "object:O",
+ .args_type = "qom-type:O",
.params = "[qom-type=]type,id=str[,prop=value][,...]",
.help = "create QOM object",
.cmd = hmp_object_add,
diff --git a/monitor/hmp.c b/monitor/hmp.c
index 0027f1465d..e535baafd0 100644
--- a/monitor/hmp.c
+++ b/monitor/hmp.c
@@ -744,13 +744,9 @@ static QDict *monitor_parse_arguments(Monitor *mon,
break;
case 'O':
{
- QemuOptsList *opts_list;
- QemuOpts *opts;
+ Error *errp;
+ bool help;
- opts_list = qemu_find_opts(key);
- if (!opts_list || opts_list->desc->name) {
- goto bad_type;
- }
while (qemu_isspace(*p)) {
p++;
}
@@ -760,12 +756,14 @@ static QDict *monitor_parse_arguments(Monitor *mon,
if (get_str(buf, sizeof(buf), &p) < 0) {
goto fail;
}
- opts = qemu_opts_parse_noisily(opts_list, buf, true);
- if (!opts) {
- goto fail;
+ keyval_parse_into(qdict, buf, key, &help, &errp);
+ if (help) {
+ if (qdict_haskey(qdict, key)) {
+ qdict_put_bool(qdict, "help", true);
+ } else {
+ qdict_put_str(qdict, key, "help");
+ }
}
- qemu_opts_to_qdict(opts, qdict);
- qemu_opts_del(opts);
}
break;
case '/':
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 04/12] qom: use qemu_printf to print help for user-creatable objects
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (2 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 03/12] hmp: replace "O" parser with keyval Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 05/12] hmp: special case help options for object_add Paolo Bonzini
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
This is needed when we add help support for object_add.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qom/object_interfaces.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index ed896fe764..34edc3d1d8 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -13,6 +13,7 @@
#include "qemu/option.h"
#include "qapi/opts-visitor.h"
#include "qemu/config-file.h"
+#include "qemu/qemu-print.h"
bool user_creatable_complete(UserCreatable *uc, Error **errp)
{
@@ -214,15 +215,15 @@ char *object_property_help(const char *name, const char *type,
return g_string_free(str, false);
}
-static void user_creatable_print_types(void)
+void user_creatable_print_types(void)
{
GSList *l, *list;
- printf("List of user creatable objects:\n");
+ qemu_printf("List of user creatable objects:\n");
list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
for (l = list; l != NULL; l = l->next) {
ObjectClass *oc = OBJECT_CLASS(l->data);
- printf(" %s\n", object_class_get_name(oc));
+ qemu_printf(" %s\n", object_class_get_name(oc));
}
g_slist_free(list);
}
@@ -253,12 +254,12 @@ static bool user_creatable_print_type_properites(const char *type)
}
g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
if (array->len > 0) {
- printf("%s options:\n", type);
+ qemu_printf("%s options:\n", type);
} else {
- printf("There are no options for %s.\n", type);
+ qemu_printf("There are no options for %s.\n", type);
}
for (i = 0; i < array->len; i++) {
- printf("%s\n", (char *)array->pdata[i]);
+ qemu_printf("%s\n", (char *)array->pdata[i]);
}
g_ptr_array_set_free_func(array, g_free);
g_ptr_array_free(array, true);
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 05/12] hmp: special case help options for object_add
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (3 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 04/12] qom: use qemu_printf to print help for user-creatable objects Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 06/12] qemu-io: use keyval for -object parsing Paolo Bonzini
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Fix "object_add help" and "object_add TYPE,help".
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qom/object_interfaces.h | 9 ++++++++-
monitor/hmp-cmds.c | 22 ++++++++--------------
qom/object_interfaces.c | 2 +-
3 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 07d5cc8832..abb23eaea3 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -149,6 +149,13 @@ typedef bool (*user_creatable_add_opts_predicate)(const char *type);
int user_creatable_add_opts_foreach(void *opaque,
QemuOpts *opts, Error **errp);
+/**
+ * user_creatable_print_types:
+ *
+ * Prints a list of user-creatable objects to stdout or the monitor.
+ */
+void user_creatable_print_types(void);
+
/**
* user_creatable_print_help:
* @type: the QOM type to be added
@@ -174,7 +181,7 @@ bool user_creatable_print_help(const char *type, QemuOpts *opts);
* no help was requested. It should only be called if we know that help is
* requested and it will always print some help.
*/
-void user_creatable_print_help_from_qdict(QDict *args);
+void user_creatable_print_help_from_qdict(const QDict *args);
/**
* user_creatable_del:
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 65d8ff4849..153ece8176 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1664,23 +1664,17 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
void hmp_object_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
- QemuOpts *opts;
- Object *obj = NULL;
- opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
- if (err) {
- goto end;
+ if (is_help_option(qdict_get_str(qdict, "qom-type"))) {
+ user_creatable_print_types();
+ return;
}
-
- obj = user_creatable_add_opts(opts, &err);
- qemu_opts_del(opts);
-
-end:
- hmp_handle_error(mon, err);
-
- if (obj) {
- object_unref(obj);
+ if (qdict_haskey(qdict, "help")) {
+ user_creatable_print_help_from_qdict(qdict);
+ return;
}
+ user_creatable_add_dict((QDict *)qdict, true, &err);
+ hmp_handle_error(mon, err);
}
void hmp_getfd(Monitor *mon, const QDict *qdict)
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 34edc3d1d8..f7dcdf18e2 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -280,7 +280,7 @@ bool user_creatable_print_help(const char *type, QemuOpts *opts)
return false;
}
-void user_creatable_print_help_from_qdict(QDict *args)
+void user_creatable_print_help_from_qdict(const QDict *args)
{
const char *type = qdict_get_try_str(args, "qom-type");
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 06/12] qemu-io: use keyval for -object parsing
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (4 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 05/12] hmp: special case help options for object_add Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 07/12] qemu-nbd: " Paolo Bonzini
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Enable creation of object with non-scalar properties.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-io.c | 42 +++++++++++++-----------------------------
1 file changed, 13 insertions(+), 29 deletions(-)
diff --git a/qemu-io.c b/qemu-io.c
index ac88d8bd40..306086f767 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -477,23 +477,6 @@ enum {
OPTION_IMAGE_OPTS = 257,
};
-static QemuOptsList qemu_object_opts = {
- .name = "object",
- .implied_opt_name = "qom-type",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
- .desc = {
- { }
- },
-};
-
-static bool qemu_io_object_print_help(const char *type, QemuOpts *opts)
-{
- if (user_creatable_print_help(type, opts)) {
- exit(0);
- }
- return true;
-}
-
static QemuOptsList file_opts = {
.name = "file",
.implied_opt_name = "file",
@@ -550,7 +533,6 @@ int main(int argc, char **argv)
qcrypto_init(&error_fatal);
module_call_init(MODULE_INIT_QOM);
- qemu_add_opts(&qemu_object_opts);
qemu_add_opts(&qemu_trace_opts);
bdrv_init();
@@ -612,14 +594,20 @@ int main(int argc, char **argv)
case 'U':
force_share = true;
break;
- case OPTION_OBJECT: {
- QemuOpts *qopts;
- qopts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!qopts) {
- exit(1);
+ case OPTION_OBJECT:
+ {
+ QDict *args;
+ bool help;
+
+ args = keyval_parse(optarg, "qom-type", &help, &error_fatal);
+ if (help) {
+ user_creatable_print_help_from_qdict(args);
+ exit(EXIT_SUCCESS);
+ }
+ user_creatable_add_dict(args, true, &error_fatal);
+ qobject_unref(args);
+ break;
}
- } break;
case OPTION_IMAGE_OPTS:
imageOpts = true;
break;
@@ -644,10 +632,6 @@ int main(int argc, char **argv)
exit(1);
}
- qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_io_object_print_help, &error_fatal);
-
if (!trace_init_backends()) {
exit(1);
}
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 07/12] qemu-nbd: use keyval for -object parsing
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (5 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 06/12] qemu-io: use keyval for -object parsing Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 08/12] qemu-img: " Paolo Bonzini
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Enable creation of object with non-scalar properties.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-nbd.c | 42 +++++++++++++-----------------------------
1 file changed, 13 insertions(+), 29 deletions(-)
diff --git a/qemu-nbd.c b/qemu-nbd.c
index a7075c5419..b4bd21a21e 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -407,23 +407,6 @@ static QemuOptsList file_opts = {
},
};
-static QemuOptsList qemu_object_opts = {
- .name = "object",
- .implied_opt_name = "qom-type",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
- .desc = {
- { }
- },
-};
-
-static bool qemu_nbd_object_print_help(const char *type, QemuOpts *opts)
-{
- if (user_creatable_print_help(type, opts)) {
- exit(0);
- }
- return true;
-}
-
static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, bool list,
Error **errp)
@@ -599,7 +582,6 @@ int main(int argc, char **argv)
qcrypto_init(&error_fatal);
module_call_init(MODULE_INIT_QOM);
- qemu_add_opts(&qemu_object_opts);
qemu_add_opts(&qemu_trace_opts);
qemu_init_exec_dir(argv[0]);
@@ -752,14 +734,20 @@ int main(int argc, char **argv)
case '?':
error_report("Try `%s --help' for more information.", argv[0]);
exit(EXIT_FAILURE);
- case QEMU_NBD_OPT_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- exit(EXIT_FAILURE);
+ case QEMU_NBD_OPT_OBJECT:
+ {
+ QDict *args;
+ bool help;
+
+ args = keyval_parse(optarg, "qom-type", &help, &error_fatal);
+ if (help) {
+ user_creatable_print_help_from_qdict(args);
+ exit(EXIT_SUCCESS);
+ }
+ user_creatable_add_dict(args, true, &error_fatal);
+ qobject_unref(args);
+ break;
}
- } break;
case QEMU_NBD_OPT_TLSCREDS:
tlscredsid = optarg;
break;
@@ -807,10 +795,6 @@ int main(int argc, char **argv)
export_name = "";
}
- qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_nbd_object_print_help, &error_fatal);
-
if (!trace_init_backends()) {
exit(1);
}
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 08/12] qemu-img: use keyval for -object parsing
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (6 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 07/12] qemu-nbd: " Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 09/12] qemu-config: add error propagation to qemu_config_parse Paolo Bonzini
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Enable creation of object with non-scalar properties.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qemu-img.c | 258 +++++++++++------------------------------------------
1 file changed, 52 insertions(+), 206 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index 8bdea40b58..a91bbba4c6 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -227,21 +227,27 @@ static void QEMU_NORETURN help(void)
exit(EXIT_SUCCESS);
}
-static QemuOptsList qemu_object_opts = {
- .name = "object",
- .implied_opt_name = "qom-type",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
- .desc = {
- { }
- },
-};
-
-static bool qemu_img_object_print_help(const char *type, QemuOpts *opts)
+static void qemu_img_object_parse(const char *optarg, int exit_code)
{
- if (user_creatable_print_help(type, opts)) {
- exit(0);
+ QDict *args;
+ bool help;
+ Error *local_error = NULL;
+
+ args = keyval_parse(optarg, "qom-type", &help, &local_error);
+ if (local_error) {
+ error_report_err(local_error);
+ exit(exit_code);
}
- return true;
+ if (help) {
+ user_creatable_print_help_from_qdict(args);
+ exit(EXIT_SUCCESS);
+ }
+ user_creatable_add_dict(args, true, &local_error);
+ if (local_error) {
+ error_report_err(local_error);
+ exit(exit_code);
+ }
+ qobject_unref(args);
}
/*
@@ -567,14 +573,9 @@ static int img_create(int argc, char **argv)
case 'u':
flags |= BDRV_O_NO_BACKING;
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- goto fail;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
}
}
@@ -590,12 +591,6 @@ static int img_create(int argc, char **argv)
}
optind++;
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- goto fail;
- }
-
/* Get image size, if specified */
if (optind < argc) {
int64_t sval;
@@ -805,14 +800,9 @@ static int img_check(int argc, char **argv)
case 'U':
force_share = true;
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -832,12 +822,6 @@ static int img_check(int argc, char **argv)
return 1;
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- return 1;
- }
-
ret = bdrv_parse_cache_mode(cache, &flags, &writethrough);
if (ret < 0) {
error_report("Invalid source cache option: %s", cache);
@@ -1035,14 +1019,9 @@ static int img_commit(int argc, char **argv)
return 1;
}
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -1059,12 +1038,6 @@ static int img_commit(int argc, char **argv)
}
filename = argv[optind++];
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- return 1;
- }
-
flags = BDRV_O_RDWR | BDRV_O_UNMAP;
ret = bdrv_parse_cache_mode(cache, &flags, &writethrough);
if (ret < 0) {
@@ -1424,15 +1397,9 @@ static int img_compare(int argc, char **argv)
case 'U':
force_share = true;
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- ret = 2;
- goto out4;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 2);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -1451,13 +1418,6 @@ static int img_compare(int argc, char **argv)
filename1 = argv[optind++];
filename2 = argv[optind++];
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- ret = 2;
- goto out4;
- }
-
/* Initialize before goto out */
qemu_progress_init(progress, 2.0);
@@ -1642,7 +1602,6 @@ out2:
blk_unref(blk1);
out3:
qemu_progress_end();
-out4:
return ret;
}
@@ -2344,15 +2303,9 @@ static int img_convert(int argc, char **argv)
goto fail_getopt;
}
break;
- case OPTION_OBJECT: {
- QemuOpts *object_opts;
- object_opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!object_opts) {
- goto fail_getopt;
- }
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
break;
- }
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -2380,12 +2333,6 @@ static int img_convert(int argc, char **argv)
out_fmt = "raw";
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- goto fail_getopt;
- }
-
if (s.compressed && s.copy_range) {
error_report("Cannot enable copy offloading when -c is used");
goto fail_getopt;
@@ -2977,14 +2924,9 @@ static int img_info(int argc, char **argv)
case OPTION_BACKING_CHAIN:
chain = true;
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -3004,12 +2946,6 @@ static int img_info(int argc, char **argv)
return 1;
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- return 1;
- }
-
list = collect_image_info_list(image_opts, filename, fmt, chain,
force_share);
if (!list) {
@@ -3219,14 +3155,9 @@ static int img_map(int argc, char **argv)
return 1;
}
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -3246,12 +3177,6 @@ static int img_map(int argc, char **argv)
return 1;
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- return 1;
- }
-
blk = img_open(image_opts, filename, fmt, 0, false, false, force_share);
if (!blk) {
return 1;
@@ -3390,14 +3315,9 @@ static int img_snapshot(int argc, char **argv)
case 'U':
force_share = true;
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -3409,12 +3329,6 @@ static int img_snapshot(int argc, char **argv)
}
filename = argv[optind++];
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- return 1;
- }
-
/* Open the image */
blk = img_open(image_opts, filename, NULL, bdrv_oflags, false, quiet,
force_share);
@@ -3548,14 +3462,9 @@ static int img_rebase(int argc, char **argv)
case 'q':
quiet = true;
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -3577,12 +3486,6 @@ static int img_rebase(int argc, char **argv)
}
filename = argv[optind++];
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- return 1;
- }
-
qemu_progress_init(progress, 2.0);
qemu_progress_print(0, 100);
@@ -3973,14 +3876,9 @@ static int img_resize(int argc, char **argv)
case 'q':
quiet = true;
break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
+ case OPTION_OBJECT:
+ qemu_img_object_parse(optarg, 1);
+ break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -4002,12 +3900,6 @@ static int img_resize(int argc, char **argv)
}
filename = argv[optind++];
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- return 1;
- }
-
/* Choose grow, shrink, or absolute resize mode */
switch (size[0]) {
case '+':
@@ -4187,12 +4079,7 @@ static int img_amend(int argc, char **argv)
quiet = true;
break;
case OPTION_OBJECT:
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- ret = -1;
- goto out_no_progress;
- }
+ qemu_img_object_parse(optarg, 1);
break;
case OPTION_IMAGE_OPTS:
image_opts = true;
@@ -4207,13 +4094,6 @@ static int img_amend(int argc, char **argv)
error_exit("Must specify options (-o)");
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- ret = -1;
- goto out_no_progress;
- }
-
if (quiet) {
progress = false;
}
@@ -4672,7 +4552,6 @@ static int img_bitmap(int argc, char **argv)
{
Error *err = NULL;
int c, ret = 1;
- QemuOpts *opts = NULL;
const char *fmt = NULL, *src_fmt = NULL, *src_filename = NULL;
const char *filename, *bitmap;
BlockBackend *blk = NULL, *src = NULL;
@@ -4766,10 +4645,7 @@ static int img_bitmap(int argc, char **argv)
merge = true;
break;
case OPTION_OBJECT:
- opts = qemu_opts_parse_noisily(&qemu_object_opts, optarg, true);
- if (!opts) {
- goto out;
- }
+ qemu_img_object_parse(optarg, 1);
break;
case OPTION_IMAGE_OPTS:
image_opts = true;
@@ -4777,12 +4653,6 @@ static int img_bitmap(int argc, char **argv)
}
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- goto out;
- }
-
if (QSIMPLEQ_EMPTY(&actions)) {
error_report("Need at least one of --add, --remove, --clear, "
"--enable, --disable, or --merge");
@@ -4878,7 +4748,6 @@ static int img_bitmap(int argc, char **argv)
out:
blk_unref(src);
blk_unref(blk);
- qemu_opts_del(opts);
return ret;
}
@@ -5040,10 +4909,7 @@ static int img_dd(int argc, char **argv)
force_share = true;
break;
case OPTION_OBJECT:
- if (!qemu_opts_parse_noisily(&qemu_object_opts, optarg, true)) {
- ret = -1;
- goto out;
- }
+ qemu_img_object_parse(optarg, 1);
break;
case OPTION_IMAGE_OPTS:
image_opts = true;
@@ -5090,13 +4956,6 @@ static int img_dd(int argc, char **argv)
goto out;
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- ret = -1;
- goto out;
- }
-
blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
force_share);
@@ -5272,7 +5131,6 @@ static int img_measure(int argc, char **argv)
char *snapshot_name = NULL;
bool force_share = false;
QemuOpts *opts = NULL;
- QemuOpts *object_opts = NULL;
QemuOpts *sn_opts = NULL;
QemuOptsList *create_opts = NULL;
bool image_opts = false;
@@ -5317,11 +5175,7 @@ static int img_measure(int argc, char **argv)
force_share = true;
break;
case OPTION_OBJECT:
- object_opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!object_opts) {
- goto out;
- }
+ qemu_img_object_parse(optarg, 1);
break;
case OPTION_IMAGE_OPTS:
image_opts = true;
@@ -5351,12 +5205,6 @@ static int img_measure(int argc, char **argv)
}
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- qemu_img_object_print_help, &error_fatal)) {
- goto out;
- }
-
if (argc - optind > 1) {
error_report("At most one filename argument is allowed.");
goto out;
@@ -5444,7 +5292,6 @@ static int img_measure(int argc, char **argv)
out:
qapi_free_BlockMeasureInfo(info);
- qemu_opts_del(object_opts);
qemu_opts_del(opts);
qemu_opts_del(sn_opts);
qemu_opts_free(create_opts);
@@ -5496,7 +5343,6 @@ int main(int argc, char **argv)
error_exit("Not enough arguments");
}
- qemu_add_opts(&qemu_object_opts);
qemu_add_opts(&qemu_source_opts);
qemu_add_opts(&qemu_trace_opts);
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 09/12] qemu-config: add error propagation to qemu_config_parse
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (7 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 08/12] qemu-img: " Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 10/12] qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict Paolo Bonzini
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
This enables some simplification of vl.c via error_fatal.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
block/blkdebug.c | 3 +--
include/qemu/config-file.h | 4 ++--
softmmu/vl.c | 24 +++++++-----------------
util/qemu-config.c | 20 ++++++++++----------
4 files changed, 20 insertions(+), 31 deletions(-)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 5fe6172da9..7eaa8a28bf 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -279,9 +279,8 @@ static int read_config(BDRVBlkdebugState *s, const char *filename,
return -errno;
}
- ret = qemu_config_parse(f, config_groups, filename);
+ ret = qemu_config_parse(f, config_groups, filename, errp);
if (ret < 0) {
- error_setg(errp, "Could not parse blkdebug config file");
goto fail;
}
}
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index 29226107bd..4e235f63ce 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -11,9 +11,9 @@ void qemu_add_drive_opts(QemuOptsList *list);
int qemu_global_option(const char *str);
void qemu_config_write(FILE *fp);
-int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname);
+int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp);
-int qemu_read_config_file(const char *filename);
+int qemu_read_config_file(const char *filename, Error **errp);
/* Parse QDict options as a replacement for a config file (allowing multiple
enumerated (0..(n-1)) configuration "sections") */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index ac6fec732e..e46f286ad2 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2041,17 +2041,16 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
return 0;
}
-static int qemu_read_default_config_file(void)
+static void qemu_read_default_config_file(Error **errp)
{
int ret;
+ Error *local_err = NULL;
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
- ret = qemu_read_config_file(file);
+ ret = qemu_read_config_file(file, &local_err);
if (ret < 0 && ret != -ENOENT) {
- return ret;
+ error_propagate(errp, local_err);
}
-
- return 0;
}
static void user_register_global_props(void)
@@ -2598,9 +2597,7 @@ void qemu_init(int argc, char **argv, char **envp)
}
if (userconfig) {
- if (qemu_read_default_config_file() < 0) {
- exit(1);
- }
+ qemu_read_default_config_file(&error_fatal);
}
/* second pass of option parsing */
@@ -3292,15 +3289,8 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_plugin_opt_parse(optarg, &plugin_list);
break;
case QEMU_OPTION_readconfig:
- {
- int ret = qemu_read_config_file(optarg);
- if (ret < 0) {
- error_report("read config %s: %s", optarg,
- strerror(-ret));
- exit(1);
- }
- break;
- }
+ qemu_read_config_file(optarg, &error_fatal);
+ break;
case QEMU_OPTION_spice:
olist = qemu_find_opts_err("spice", NULL);
if (!olist) {
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 725e3d7e4b..7804333b5a 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -356,7 +356,7 @@ void qemu_config_write(FILE *fp)
}
/* Returns number of config groups on success, -errno on error */
-int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
+int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp)
{
char line[1024], group[64], id[64], arg[64], value[1024];
Location loc;
@@ -381,7 +381,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
/* group with id */
list = find_list(lists, group, &local_err);
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
goto out;
}
opts = qemu_opts_create(list, id, 1, NULL);
@@ -392,7 +392,7 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
/* group without id */
list = find_list(lists, group, &local_err);
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
goto out;
}
opts = qemu_opts_create(list, NULL, 0, &error_abort);
@@ -404,20 +404,19 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname)
sscanf(line, " %63s = \"\"", arg) == 1) {
/* arg = value */
if (opts == NULL) {
- error_report("no group defined");
+ error_setg(errp, "no group defined");
goto out;
}
- if (!qemu_opt_set(opts, arg, value, &local_err)) {
- error_report_err(local_err);
+ if (!qemu_opt_set(opts, arg, value, errp)) {
goto out;
}
continue;
}
- error_report("parse error");
+ error_setg(errp, "parse error");
goto out;
}
if (ferror(fp)) {
- error_report("error reading file");
+ error_setg(errp, "error reading file");
goto out;
}
res = count;
@@ -426,16 +425,17 @@ out:
return res;
}
-int qemu_read_config_file(const char *filename)
+int qemu_read_config_file(const char *filename, Error **errp)
{
FILE *f = fopen(filename, "r");
int ret;
if (f == NULL) {
+ error_setg_errno(errp, errno, "Cannot read config file %s", filename);
return -errno;
}
- ret = qemu_config_parse(f, vm_config_groups, filename);
+ ret = qemu_config_parse(f, vm_config_groups, filename, errp);
fclose(f);
return ret;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 10/12] qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (8 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 09/12] qemu-config: add error propagation to qemu_config_parse Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 11/12] qemu-config: parse configuration files to a QDict Paolo Bonzini
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
util/qemu-option.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 40564a12eb..afba08d92e 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1052,7 +1052,8 @@ bool qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp)
while (entry != NULL) {
next = qdict_next(qdict, entry);
- if (find_desc_by_name(opts->list->desc, entry->key)) {
+ if (opts_accepts_any(opts->list) ||
+ find_desc_by_name(opts->list->desc, entry->key)) {
if (!qemu_opts_from_qdict_entry(opts, entry, errp)) {
return false;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 11/12] qemu-config: parse configuration files to a QDict
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (9 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 10/12] qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-11 14:25 ` [PATCH 12/12] qemu: use keyval for -object parsing Paolo Bonzini
2020-11-13 14:35 ` [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Kevin Wolf
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Change the parser to put the values into a QDict and pass them
to a callback. qemu_config_parse's QemuOpts creation is
itself turned into a callback function.
Note that the QemuOpts are now created at the _end_ of the group,
rather than at the beginning. Therefore, loc_set_file is delayed
until after the callback has been invoked.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/config-file.h | 6 ++-
softmmu/vl.c | 4 +-
util/qemu-config.c | 91 +++++++++++++++++++++++++-------------
3 files changed, 68 insertions(+), 33 deletions(-)
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index 4e235f63ce..6f9b511f48 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -1,6 +1,7 @@
#ifndef QEMU_CONFIG_FILE_H
#define QEMU_CONFIG_FILE_H
+typedef void QEMUConfigCB(const char *group, QDict *qdict, void *opaque, Error **errp);
QemuOptsList *qemu_find_opts(const char *group);
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
@@ -13,7 +14,10 @@ int qemu_global_option(const char *str);
void qemu_config_write(FILE *fp);
int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp);
-int qemu_read_config_file(const char *filename, Error **errp);
+/* A default callback for qemu_read_config_file(). */
+void qemu_config_do_parse(const char *group, QDict *qdict, void *opaque, Error **errp);
+
+int qemu_read_config_file(const char *filename, QEMUConfigCB *f, Error **errp);
/* Parse QDict options as a replacement for a config file (allowing multiple
enumerated (0..(n-1)) configuration "sections") */
diff --git a/softmmu/vl.c b/softmmu/vl.c
index e46f286ad2..9b3b687a85 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2047,7 +2047,7 @@ static void qemu_read_default_config_file(Error **errp)
Error *local_err = NULL;
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
- ret = qemu_read_config_file(file, &local_err);
+ ret = qemu_read_config_file(file, qemu_config_do_parse, &local_err);
if (ret < 0 && ret != -ENOENT) {
error_propagate(errp, local_err);
}
@@ -3289,7 +3289,7 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_plugin_opt_parse(optarg, &plugin_list);
break;
case QEMU_OPTION_readconfig:
- qemu_read_config_file(optarg, &error_fatal);
+ qemu_read_config_file(optarg, qemu_config_do_parse, &error_fatal);
break;
case QEMU_OPTION_spice:
olist = qemu_find_opts_err("spice", NULL);
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 7804333b5a..a1db99dcba 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -356,19 +356,19 @@ void qemu_config_write(FILE *fp)
}
/* Returns number of config groups on success, -errno on error */
-int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp)
+static int qemu_config_foreach(FILE *fp, QEMUConfigCB *cb, void *opaque,
+ const char *fname, Error **errp)
{
- char line[1024], group[64], id[64], arg[64], value[1024];
+ char line[1024], prev_group[64], group[64], arg[64], value[1024];
Location loc;
- QemuOptsList *list = NULL;
Error *local_err = NULL;
- QemuOpts *opts = NULL;
+ QDict *qdict = NULL;
int res = -EINVAL, lno = 0;
int count = 0;
loc_push_none(&loc);
while (fgets(line, sizeof(line), fp) != NULL) {
- loc_set_file(fname, ++lno);
+ ++lno;
if (line[0] == '\n') {
/* skip empty lines */
continue;
@@ -377,39 +377,39 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error *
/* comment */
continue;
}
- if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
- /* group with id */
- list = find_list(lists, group, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out;
+ if (line[0] == '[') {
+ QDict *prev = qdict;
+ if (sscanf(line, "[%63s \"%63[^\"]\"]", group, value) == 2) {
+ qdict = qdict_new();
+ qdict_put_str(qdict, "id", value);
+ count++;
+ } else if (sscanf(line, "[%63[^]]]", group) == 1) {
+ qdict = qdict_new();
+ count++;
}
- opts = qemu_opts_create(list, id, 1, NULL);
- count++;
- continue;
- }
- if (sscanf(line, "[%63[^]]]", group) == 1) {
- /* group without id */
- list = find_list(lists, group, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out;
+ if (qdict != prev) {
+ if (prev) {
+ cb(prev_group, prev, opaque, &local_err);
+ qobject_unref(prev);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto out;
+ }
+ }
+ strcpy(prev_group, group);
+ continue;
}
- opts = qemu_opts_create(list, NULL, 0, &error_abort);
- count++;
- continue;
}
+ loc_set_file(fname, lno);
value[0] = '\0';
if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2 ||
sscanf(line, " %63s = \"\"", arg) == 1) {
/* arg = value */
- if (opts == NULL) {
+ if (qdict == NULL) {
error_setg(errp, "no group defined");
goto out;
}
- if (!qemu_opt_set(opts, arg, value, errp)) {
- goto out;
- }
+ qdict_put_str(qdict, arg, value);
continue;
}
error_setg(errp, "parse error");
@@ -422,10 +422,41 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error *
res = count;
out:
loc_pop(&loc);
+ if (qdict) {
+ cb(group, qdict, opaque, errp);
+ qobject_unref(qdict);
+ }
return res;
}
-int qemu_read_config_file(const char *filename, Error **errp)
+void qemu_config_do_parse(const char *group, QDict *qdict, void *opaque, Error **errp)
+{
+ QemuOptsList **lists = opaque;
+ const char *id = qdict_get_try_str(qdict, "id");
+ QemuOptsList *list;
+ QemuOpts *opts;
+
+ list = find_list(lists, group, errp);
+ if (!list) {
+ return;
+ }
+
+ opts = qemu_opts_create(list, id, 1, errp);
+ if (!opts) {
+ return;
+ }
+ if (id) {
+ qdict_del(qdict, "id");
+ }
+ qemu_opts_absorb_qdict(opts, qdict, errp);
+}
+
+int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error **errp)
+{
+ return qemu_config_foreach(fp, qemu_config_do_parse, lists, fname, errp);
+}
+
+int qemu_read_config_file(const char *filename, QEMUConfigCB *cb, Error **errp)
{
FILE *f = fopen(filename, "r");
int ret;
@@ -435,7 +466,7 @@ int qemu_read_config_file(const char *filename, Error **errp)
return -errno;
}
- ret = qemu_config_parse(f, vm_config_groups, filename, errp);
+ ret = qemu_config_foreach(f, cb, vm_config_groups, filename, errp);
fclose(f);
return ret;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 12/12] qemu: use keyval for -object parsing
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (10 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 11/12] qemu-config: parse configuration files to a QDict Paolo Bonzini
@ 2020-11-11 14:25 ` Paolo Bonzini
2020-11-13 14:35 ` [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Kevin Wolf
12 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2020-11-11 14:25 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qom/object_interfaces.h | 44 ----------------
qom/object_interfaces.c | 42 ---------------
softmmu/vl.c | 93 ++++++++++++++++++++++-----------
3 files changed, 63 insertions(+), 116 deletions(-)
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index abb23eaea3..77a4d5cf98 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -119,36 +119,6 @@ bool user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
*/
Object *user_creatable_add_opts(QemuOpts *opts, Error **errp);
-
-/**
- * user_creatable_add_opts_predicate:
- * @type: the QOM type to be added
- *
- * A callback function to determine whether an object
- * of type @type should be created. Instances of this
- * callback should be passed to user_creatable_add_opts_foreach
- */
-typedef bool (*user_creatable_add_opts_predicate)(const char *type);
-
-/**
- * user_creatable_add_opts_foreach:
- * @opaque: a user_creatable_add_opts_predicate callback or NULL
- * @opts: options to create
- * @errp: unused
- *
- * An iterator callback to be used in conjunction with
- * the qemu_opts_foreach() method for creating a list of
- * objects from a set of QemuOpts
- *
- * The @opaque parameter can be passed a user_creatable_add_opts_predicate
- * callback to filter which types of object are created during iteration.
- * When it fails, report the error.
- *
- * Returns: 0 on success, -1 when an error was reported.
- */
-int user_creatable_add_opts_foreach(void *opaque,
- QemuOpts *opts, Error **errp);
-
/**
* user_creatable_print_types:
*
@@ -156,20 +126,6 @@ int user_creatable_add_opts_foreach(void *opaque,
*/
void user_creatable_print_types(void);
-/**
- * user_creatable_print_help:
- * @type: the QOM type to be added
- * @opts: options to create
- *
- * Prints help if requested in @type or @opts. Note that if @type is neither
- * "help"/"?" nor a valid user creatable type, no help will be printed
- * regardless of @opts.
- *
- * Returns: true if a help option was found and help was printed, false
- * otherwise.
- */
-bool user_creatable_print_help(const char *type, QemuOpts *opts);
-
/**
* user_creatable_print_help_from_qdict:
* @args: options to create
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index f7dcdf18e2..08d1f5c0d5 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -171,27 +171,6 @@ Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
return obj;
}
-
-int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
-{
- bool (*type_opt_predicate)(const char *, QemuOpts *) = opaque;
- Object *obj = NULL;
- const char *type;
-
- type = qemu_opt_get(opts, "qom-type");
- if (type && type_opt_predicate &&
- !type_opt_predicate(type, opts)) {
- return 0;
- }
-
- obj = user_creatable_add_opts(opts, errp);
- if (!obj) {
- return -1;
- }
- object_unref(obj);
- return 0;
-}
-
char *object_property_help(const char *name, const char *type,
QObject *defval, const char *description)
{
@@ -266,20 +245,6 @@ static bool user_creatable_print_type_properites(const char *type)
return true;
}
-bool user_creatable_print_help(const char *type, QemuOpts *opts)
-{
- if (is_help_option(type)) {
- user_creatable_print_types();
- return true;
- }
-
- if (qemu_opt_has_help_opt(opts)) {
- return user_creatable_print_type_properites(type);
- }
-
- return false;
-}
-
void user_creatable_print_help_from_qdict(const QDict *args)
{
const char *type = qdict_get_try_str(args, "qom-type");
@@ -306,13 +271,6 @@ bool user_creatable_del(const char *id, Error **errp)
return false;
}
- /*
- * if object was defined on the command-line, remove its corresponding
- * option group entry
- */
- qemu_opts_del(qemu_opts_find(qemu_find_opts_err("object", &error_abort),
- id));
-
object_unparent(obj);
return true;
}
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 9b3b687a85..bb4dc87a29 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -116,6 +116,7 @@
#include "qapi/qapi-commands-migration.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-ui.h"
+#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/iothread.h"
#include "qemu/guest-random.h"
@@ -136,6 +137,7 @@ static const char *boot_order;
static const char *boot_once;
static const char *incoming;
static const char *loadvm;
+static GSList *object_opts_list = NULL;
static ram_addr_t maxram_size;
static uint64_t ram_slots;
static int display_remote;
@@ -308,15 +310,6 @@ static QemuOptsList qemu_add_fd_opts = {
},
};
-static QemuOptsList qemu_object_opts = {
- .name = "object",
- .implied_opt_name = "qom-type",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
- .desc = {
- { }
- },
-};
-
static QemuOptsList qemu_tpmdev_opts = {
.name = "tpmdev",
.implied_opt_name = "type",
@@ -1678,12 +1671,8 @@ static int machine_set_property(void *opaque,
* cannot be created here, as it depends on the chardev
* already existing.
*/
-static bool object_create_early(const char *type, QemuOpts *opts)
+static bool object_create_early(const char *type)
{
- if (user_creatable_print_help(type, opts)) {
- exit(0);
- }
-
/*
* Objects should not be made "delayed" without a reason. If you
* add one, state the reason in a comment!
@@ -1769,6 +1758,22 @@ static void qemu_apply_machine_options(void)
current_machine->boot_order = boot_order;
}
+static void user_creatable_add_dict_foreach(void *data, void *opaque)
+{
+ bool (*type_opt_predicate)(const char *) = opaque;
+ QDict *dict = data;
+ const char *type = qdict_get_try_str(dict, "qom-type");
+
+ if (!type) {
+ error_report("Parameter 'qom-type' is missing");
+ }
+ if (type_opt_predicate && !type_opt_predicate(type)) {
+ return;
+ }
+
+ user_creatable_add_dict(dict, true, &error_fatal);
+}
+
static void qemu_create_early_backends(void)
{
MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
@@ -1795,9 +1800,9 @@ static void qemu_create_early_backends(void)
exit(1);
}
- qemu_opts_foreach(qemu_find_opts("object"),
- user_creatable_add_opts_foreach,
- object_create_early, &error_fatal);
+ g_slist_foreach(object_opts_list,
+ user_creatable_add_dict_foreach,
+ object_create_early);
/* spice needs the timers to be initialized by this point */
/* spice must initialize before audio as it changes the default auiodev */
@@ -1826,9 +1831,9 @@ static void qemu_create_early_backends(void)
* The remainder of object creation happens after the
* creation of chardev, fsdev, net clients and device data types.
*/
-static bool object_create_late(const char *type, QemuOpts *opts)
+static bool object_create_late(const char *type)
{
- return !object_create_early(type, opts);
+ return !object_create_early(type);
}
static void qemu_create_late_backends(void)
@@ -1839,9 +1844,9 @@ static void qemu_create_late_backends(void)
net_init_clients(&error_fatal);
- qemu_opts_foreach(qemu_find_opts("object"),
- user_creatable_add_opts_foreach,
- object_create_late, &error_fatal);
+ g_slist_foreach(object_opts_list,
+ user_creatable_add_dict_foreach,
+ object_create_late);
if (tpm_init() < 0) {
exit(1);
@@ -2041,13 +2046,32 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
return 0;
}
+/*
+ * Parse non-QemuOpts config file groups, pass the rest to
+ * qemu_config_do_parse.
+ */
+static void qemu_parse_config_group(const char *group, QDict *qdict,
+ void *opaque, Error **errp)
+{
+ if (g_str_equal(group, "object")) {
+ QObject *crumpled = qdict_crumple(qdict, errp);
+ if (!crumpled) {
+ return;
+ }
+ object_opts_list = g_slist_prepend(object_opts_list, crumpled);
+ return;
+ }
+
+ qemu_config_do_parse(group, qdict, opaque, errp);
+}
+
static void qemu_read_default_config_file(Error **errp)
{
int ret;
Error *local_err = NULL;
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
- ret = qemu_read_config_file(file, qemu_config_do_parse, &local_err);
+ ret = qemu_read_config_file(file, qemu_parse_config_group, &local_err);
if (ret < 0 && ret != -ENOENT) {
error_propagate(errp, local_err);
}
@@ -2561,7 +2585,6 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_smp_opts);
qemu_add_opts(&qemu_boot_opts);
qemu_add_opts(&qemu_add_fd_opts);
- qemu_add_opts(&qemu_object_opts);
qemu_add_opts(&qemu_tpmdev_opts);
qemu_add_opts(&qemu_realtime_opts);
qemu_add_opts(&qemu_overcommit_opts);
@@ -3289,7 +3312,7 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_plugin_opt_parse(optarg, &plugin_list);
break;
case QEMU_OPTION_readconfig:
- qemu_read_config_file(optarg, qemu_config_do_parse, &error_fatal);
+ qemu_read_config_file(optarg, qemu_parse_config_group, &error_fatal);
break;
case QEMU_OPTION_spice:
olist = qemu_find_opts_err("spice", NULL);
@@ -3361,12 +3384,18 @@ void qemu_init(int argc, char **argv, char **envp)
#endif
break;
case QEMU_OPTION_object:
- opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
- optarg, true);
- if (!opts) {
- exit(1);
+ {
+ QDict *args;
+ bool help;
+
+ args = keyval_parse(optarg, "qom-type", &help, &error_fatal);
+ if (help) {
+ user_creatable_print_help_from_qdict(args);
+ exit(EXIT_SUCCESS);
+ }
+ object_opts_list = g_slist_prepend(object_opts_list, args);
+ break;
}
- break;
case QEMU_OPTION_realtime:
warn_report("'-realtime mlock=...' is deprecated, please use "
"'-overcommit mem-lock=...' instead");
@@ -3424,6 +3453,10 @@ void qemu_init(int argc, char **argv, char **envp)
}
}
}
+
+ /* Cleanup after option parsing loop. */
+ object_opts_list = g_slist_reverse(object_opts_list);
+
/*
* Clear error location left behind by the loop.
* Best done right after the loop. Do not insert code here!
--
2.26.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
` (11 preceding siblings ...)
2020-11-11 14:25 ` [PATCH 12/12] qemu: use keyval for -object parsing Paolo Bonzini
@ 2020-11-13 14:35 ` Kevin Wolf
12 siblings, 0 replies; 14+ messages in thread
From: Kevin Wolf @ 2020-11-13 14:35 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
Am 11.11.2020 um 15:25 hat Paolo Bonzini geschrieben:
> This is yet another RFC on the command-line parsing overhaul. Here,
> I'm switching HMP, -object and -readconfig away from QemuOpts. There are
> pending QemuOpts and keyval patches that make the syntaxes the same
> apart from:
>
> - "implicit value" options (where the lack of value is turned
> into "on" or "off"), which will be deprecated
>
> - the processing of invalid, empty or overlong keys which can be considered
> bugfixes.
>
> Along the way, the object_add HMP command grows help support.
>
> The plan on top of this is to also keyval-ify -M and -accel. The reason
> for this, in my evil plan, is to allow for compound properties. These
> compound properties would be used for replacements of options like -smp
> (-M smp.xxx), -icount (-accel tcg,icount.xxx) and -chardev (as in -object
> chardev-socket,addr.host).
I haven't reviewed everything in detail, but this approach looks
workable to me.
Of course, at the moment -object is a bit different from other options
in that it doesn't have a QAPI object for the options, but you just
directly pass QDicts to user_creatable_add_dict(). But plugging in a
visitor for other options groups doesn't suddenly require a different
design, so this is fine.
Kevin
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2020-11-13 14:36 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-11 14:25 [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Paolo Bonzini
2020-11-11 14:25 ` [PATCH 01/12] tests: convert check-qom-proplist to keyval Paolo Bonzini
2020-11-11 14:25 ` [PATCH 02/12] keyval: introduce keyval_parse_into Paolo Bonzini
2020-11-11 14:25 ` [PATCH 03/12] hmp: replace "O" parser with keyval Paolo Bonzini
2020-11-11 14:25 ` [PATCH 04/12] qom: use qemu_printf to print help for user-creatable objects Paolo Bonzini
2020-11-11 14:25 ` [PATCH 05/12] hmp: special case help options for object_add Paolo Bonzini
2020-11-11 14:25 ` [PATCH 06/12] qemu-io: use keyval for -object parsing Paolo Bonzini
2020-11-11 14:25 ` [PATCH 07/12] qemu-nbd: " Paolo Bonzini
2020-11-11 14:25 ` [PATCH 08/12] qemu-img: " Paolo Bonzini
2020-11-11 14:25 ` [PATCH 09/12] qemu-config: add error propagation to qemu_config_parse Paolo Bonzini
2020-11-11 14:25 ` [PATCH 10/12] qemu-option: support accept-any QemuOptsList in qemu_opts_absorb_qdict Paolo Bonzini
2020-11-11 14:25 ` [PATCH 11/12] qemu-config: parse configuration files to a QDict Paolo Bonzini
2020-11-11 14:25 ` [PATCH 12/12] qemu: use keyval for -object parsing Paolo Bonzini
2020-11-13 14:35 ` [RFC PATCH 00/12] Remove QemuOpts usage for HMP, -object and -readconfig Kevin Wolf
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.