qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2] vl: Add support to set properties when using JSON syntax for


From: MkfsSion
Subject: [PATCH v2] vl: Add support to set properties when using JSON syntax for -device via -set option
Date: Fri, 24 Dec 2021 15:25:11 +0800

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 fixes the above issue by trying to convert value provided by -set
option to the type that the setting property actually takes.

Signed-off-by: YuanYang Meng <mkfssion@mkfssion.com>
---
 v2:
     1.Set device option when group is 'device' only
     2.Store value in type that properties actually take


 softmmu/vl.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index 620a1f1367..c213e9e022 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"
@@ -2274,6 +2276,61 @@ static void qemu_read_default_config_file(Error **errp)
     }
 }
 
+static bool qemu_set_device_option_property(const char *id, const char *key,
+                                            const char *value, Error **errp) {
+    DeviceOption *opt;
+    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)) {
+            QObject *obj = NULL;
+            if ((strcmp(key, "id") == 0) ||
+                (strcmp(key, "bus") == 0) ||
+                (strcmp(key, "driver") == 0)) {
+                obj = QOBJECT(qstring_from_str(value));
+            } else {
+                const char *driver = qdict_get_try_str(opt->opts, "driver");
+                if (driver) {
+                    ObjectClass *klass = object_class_by_name(driver);
+                    ObjectProperty *prop = object_class_property_find(klass, 
key);
+                    if (prop) {
+                        if (strcmp(prop->type, "str") == 0) {
+                            obj = QOBJECT(qstring_from_str(value));
+                        } else if (strcmp(prop->type, "bool") == 0) {
+                            bool boolean;
+                            if (qapi_bool_parse(key, value, &boolean, errp)) {
+                                obj = QOBJECT(qbool_from_bool(boolean));
+                            }
+                        } else if (strncmp(prop->type, "uint", 4) == 0) {
+                            uint64_t num;
+                            if (parse_option_size(key, value, &num, errp)) {
+                                obj = QOBJECT(qnum_from_uint(num));
+                            }
+                        } else {
+                            error_setg(errp,
+                                       "Setting property %s on device %s with "
+                                       "type %s is unsupported via -set 
option",
+                                       key, id, prop->type);
+                        }
+                    } else {
+                        error_setg(errp, "Unable to find property %s on device 
%s",
+                                   key, id);
+                    }
+                } else {
+                    error_setg(errp, "Unable to get driver for device %s", id);
+                }
+            }
+            if (obj) {
+                qdict_del(opt->opts, key);
+                qdict_put_obj(opt->opts, key, obj);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+    return false;
+}
+
 static void qemu_set_option(const char *str, Error **errp)
 {
     char group[64], id[64], arg[64];
@@ -2294,6 +2351,11 @@ static void qemu_set_option(const char *str, Error 
**errp)
         if (list) {
             opts = qemu_opts_find(list, id);
             if (!opts) {
+                if (strcmp(group, "device") == 0) {
+                    if (qemu_set_device_option_property(id, arg,
+                                                        str + offset + 1, 
errp))
+                        return;
+                }
                 error_setg(errp, "there is no %s \"%s\" defined", group, id);
                 return;
             }
-- 
2.34.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]