When using JSON syntax for -device, -set option can not find device specified in JSON by id field. The following commandline is an example:
$ qemu-system-x86_64 -device '{"id":"foo"}' -set device.foo.bar=1 qemu-system-x86_64: -set device.foo.bar=1: there is no device "foo" defined The patch adds -set options to JSON device opts dict for adding options to device by latter object_set_properties_from_keyval call. Signed-off-by: YuanYang Meng <mkfss...@mkfssion.com> --- include/qemu/option.h | 4 ++++ softmmu/vl.c | 28 ++++++++++++++++++++++++++++ util/qemu-option.c | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index 306bf07575..31fa9fdc25 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -45,6 +45,10 @@ const char *get_opt_value(const char *p, char **value); bool parse_option_size(const char *name, const char *value, uint64_t *ret, Error **errp); + +bool parse_option_number(const char *name, const char *value, + uint64_t *ret, Error **errp); + bool has_help_option(const char *param); enum QemuOptType { diff --git a/softmmu/vl.c b/softmmu/vl.c index 620a1f1367..feb3c49a65 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -30,7 +30,9 @@ #include "hw/qdev-properties.h" #include "qapi/compat-policy.h" #include "qapi/error.h" +#include "qapi/qmp/qbool.h" #include "qapi/qmp/qdict.h" +#include "qapi/qmp/qnum.h" #include "qapi/qmp/qstring.h" #include "qapi/qmp/qjson.h" #include "qemu-version.h" @@ -2279,6 +2281,7 @@ static void qemu_set_option(const char *str, Error **errp) char group[64], id[64], arg[64]; QemuOptsList *list; QemuOpts *opts; + DeviceOption *opt; int rc, offset; rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset); @@ -2294,6 +2297,31 @@ static void qemu_set_option(const char *str, Error **errp) if (list) { opts = qemu_opts_find(list, id); if (!opts) { + QTAILQ_FOREACH(opt, &device_opts, next) { + const char *device_id = qdict_get_try_str(opt->opts, "id"); + if (device_id && (strcmp(device_id, id) == 0)) { + if (qdict_get(opt->opts, arg)) { + qdict_del(opt->opts, arg); + } + const char *value = str + offset + 1; + QObject *obj = NULL; + bool boolean; + uint64_t num; + if (qapi_bool_parse(arg, value, &boolean, NULL)) { + obj = QOBJECT(qbool_from_bool(boolean)); + } else if (parse_option_number(arg, value, &num, NULL)) { + obj = QOBJECT(qnum_from_uint(num)); + } else if (parse_option_size(arg, value, &num, NULL)) { + obj = QOBJECT(qnum_from_uint(num)); + } else { + obj = QOBJECT(qstring_from_str(value)); + } + if (obj) { + qdict_put_obj(opt->opts, arg, obj); + return; + } + } + } error_setg(errp, "there is no %s \"%s\" defined", group, id); return; } diff --git a/util/qemu-option.c b/util/qemu-option.c index eedd08929b..b2427cba9f 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -88,7 +88,7 @@ const char *get_opt_value(const char *p, char **value) return offset; } -static bool parse_option_number(const char *name, const char *value, +bool parse_option_number(const char *name, const char *value, uint64_t *ret, Error **errp) { uint64_t number; -- 2.34.1