Blame 0004-vl-plumb-keyval-based-options-into-readconfig.patch

Paolo Bonzini d9c8b5
From 8eef1078eff6fc5cc045684486d228153463dac2 Mon Sep 17 00:00:00 2001
Paolo Bonzini d9c8b5
From: Paolo Bonzini <pbonzini@redhat.com>
Paolo Bonzini d9c8b5
Date: Tue, 18 May 2021 11:40:58 -0400
Paolo Bonzini d9c8b5
Subject: [PATCH 4/5] vl: plumb keyval-based options into -readconfig
Paolo Bonzini d9c8b5
Paolo Bonzini d9c8b5
Let -readconfig support parsing command line options into QDict or
Paolo Bonzini d9c8b5
QemuOpts.  This will be used to add back support for objects in
Paolo Bonzini d9c8b5
-readconfig.
Paolo Bonzini d9c8b5
Paolo Bonzini d9c8b5
Cc: Markus Armbruster <armbru@redhat.com>
Paolo Bonzini d9c8b5
Cc: qemu-stable@nongnu.org
Paolo Bonzini d9c8b5
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Paolo Bonzini d9c8b5
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo Bonzini d9c8b5
Message-Id: <20210524105752.3318299-3-pbonzini@redhat.com>
Paolo Bonzini d9c8b5
---
Paolo Bonzini d9c8b5
 include/block/qdict.h    |  2 -
Paolo Bonzini d9c8b5
 include/qapi/qmp/qdict.h |  3 ++
Paolo Bonzini d9c8b5
 softmmu/vl.c             | 83 ++++++++++++++++++++++++++++------------
Paolo Bonzini d9c8b5
 3 files changed, 62 insertions(+), 26 deletions(-)
Paolo Bonzini d9c8b5
Paolo Bonzini d9c8b5
diff --git a/include/block/qdict.h b/include/block/qdict.h
Paolo Bonzini d9c8b5
index d8cb502..ced2acf 100644
Paolo Bonzini d9c8b5
--- a/include/block/qdict.h
Paolo Bonzini d9c8b5
+++ b/include/block/qdict.h
Paolo Bonzini d9c8b5
@@ -20,8 +20,6 @@ void qdict_join(QDict *dest, QDict *src, bool overwrite);
Paolo Bonzini d9c8b5
 void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
Paolo Bonzini d9c8b5
 void qdict_array_split(QDict *src, QList **dst);
Paolo Bonzini d9c8b5
 int qdict_array_entries(QDict *src, const char *subqdict);
Paolo Bonzini d9c8b5
-QObject *qdict_crumple(const QDict *src, Error **errp);
Paolo Bonzini d9c8b5
-void qdict_flatten(QDict *qdict);
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
 typedef struct QDictRenames {
Paolo Bonzini d9c8b5
     const char *from;
Paolo Bonzini d9c8b5
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
Paolo Bonzini d9c8b5
index 9934539..d5b5430 100644
Paolo Bonzini d9c8b5
--- a/include/qapi/qmp/qdict.h
Paolo Bonzini d9c8b5
+++ b/include/qapi/qmp/qdict.h
Paolo Bonzini d9c8b5
@@ -64,4 +64,7 @@ const char *qdict_get_try_str(const QDict *qdict, const char *key);
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
 QDict *qdict_clone_shallow(const QDict *src);
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
+QObject *qdict_crumple(const QDict *src, Error **errp);
Paolo Bonzini d9c8b5
+void qdict_flatten(QDict *qdict);
Paolo Bonzini d9c8b5
+
Paolo Bonzini d9c8b5
 #endif /* QDICT_H */
Paolo Bonzini d9c8b5
diff --git a/softmmu/vl.c b/softmmu/vl.c
Paolo Bonzini d9c8b5
index da5042f..48d1f06 100644
Paolo Bonzini d9c8b5
--- a/softmmu/vl.c
Paolo Bonzini d9c8b5
+++ b/softmmu/vl.c
Paolo Bonzini d9c8b5
@@ -122,6 +122,7 @@
Paolo Bonzini d9c8b5
 #include "qapi/qapi-commands-misc.h"
Paolo Bonzini d9c8b5
 #include "qapi/qapi-visit-qom.h"
Paolo Bonzini d9c8b5
 #include "qapi/qapi-commands-ui.h"
Paolo Bonzini d9c8b5
+#include "qapi/qmp/qdict.h"
Paolo Bonzini d9c8b5
 #include "qapi/qmp/qerror.h"
Paolo Bonzini d9c8b5
 #include "sysemu/iothread.h"
Paolo Bonzini d9c8b5
 #include "qemu/guest-random.h"
Paolo Bonzini d9c8b5
@@ -2113,13 +2114,53 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
Paolo Bonzini d9c8b5
     return 0;
Paolo Bonzini d9c8b5
 }
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
+/*
Paolo Bonzini d9c8b5
+ * Return whether configuration group @group is stored in QemuOpts, or
Paolo Bonzini d9c8b5
+ * recorded as one or more QDicts by qemu_record_config_group.
Paolo Bonzini d9c8b5
+ */
Paolo Bonzini d9c8b5
+static bool is_qemuopts_group(const char *group)
Paolo Bonzini d9c8b5
+{
Paolo Bonzini d9c8b5
+    return true;
Paolo Bonzini d9c8b5
+}
Paolo Bonzini d9c8b5
+
Paolo Bonzini d9c8b5
+static void qemu_record_config_group(const char *group, QDict *dict,
Paolo Bonzini d9c8b5
+                                     bool from_json, Error **errp)
Paolo Bonzini d9c8b5
+{
Paolo Bonzini d9c8b5
+    abort();
Paolo Bonzini d9c8b5
+}
Paolo Bonzini d9c8b5
+
Paolo Bonzini d9c8b5
+/*
Paolo Bonzini d9c8b5
+ * Parse non-QemuOpts config file groups, pass the rest to
Paolo Bonzini d9c8b5
+ * qemu_config_do_parse.
Paolo Bonzini d9c8b5
+ */
Paolo Bonzini d9c8b5
+static void qemu_parse_config_group(const char *group, QDict *qdict,
Paolo Bonzini d9c8b5
+                                    void *opaque, Error **errp)
Paolo Bonzini d9c8b5
+{
Paolo Bonzini d9c8b5
+    QObject *crumpled;
Paolo Bonzini d9c8b5
+    if (is_qemuopts_group(group)) {
Paolo Bonzini d9c8b5
+        qemu_config_do_parse(group, qdict, opaque, errp);
Paolo Bonzini d9c8b5
+        return;
Paolo Bonzini d9c8b5
+    }
Paolo Bonzini d9c8b5
+
Paolo Bonzini d9c8b5
+    crumpled = qdict_crumple(qdict, errp);
Paolo Bonzini d9c8b5
+    if (!crumpled) {
Paolo Bonzini d9c8b5
+        return;
Paolo Bonzini d9c8b5
+    }
Paolo Bonzini d9c8b5
+    if (qobject_type(crumpled) != QTYPE_QDICT) {
Paolo Bonzini d9c8b5
+        assert(qobject_type(crumpled) == QTYPE_QLIST);
Paolo Bonzini d9c8b5
+        error_setg(errp, "Lists cannot be at top level of a configuration section");
Paolo Bonzini d9c8b5
+        return;
Paolo Bonzini d9c8b5
+    }
Paolo Bonzini d9c8b5
+    qemu_record_config_group(group, qobject_to(QDict, crumpled), false, errp);
Paolo Bonzini d9c8b5
+}
Paolo Bonzini d9c8b5
+
Paolo Bonzini d9c8b5
 static void qemu_read_default_config_file(Error **errp)
Paolo Bonzini d9c8b5
 {
Paolo Bonzini d9c8b5
     ERRP_GUARD();
Paolo Bonzini d9c8b5
     int ret;
Paolo Bonzini d9c8b5
     g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
-    ret = qemu_read_config_file(file, qemu_config_do_parse, errp);
Paolo Bonzini d9c8b5
+    ret = qemu_read_config_file(file, qemu_parse_config_group, errp);
Paolo Bonzini d9c8b5
     if (ret < 0) {
Paolo Bonzini d9c8b5
         if (ret == -ENOENT) {
Paolo Bonzini d9c8b5
             error_free(*errp);
Paolo Bonzini d9c8b5
@@ -2128,9 +2169,8 @@ static void qemu_read_default_config_file(Error **errp)
Paolo Bonzini d9c8b5
     }
Paolo Bonzini d9c8b5
 }
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
-static int qemu_set_option(const char *str)
Paolo Bonzini d9c8b5
+static void qemu_set_option(const char *str, Error **errp)
Paolo Bonzini d9c8b5
 {
Paolo Bonzini d9c8b5
-    Error *local_err = NULL;
Paolo Bonzini d9c8b5
     char group[64], id[64], arg[64];
Paolo Bonzini d9c8b5
     QemuOptsList *list;
Paolo Bonzini d9c8b5
     QemuOpts *opts;
Paolo Bonzini d9c8b5
@@ -2138,27 +2178,23 @@ static int qemu_set_option(const char *str)
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
     rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
Paolo Bonzini d9c8b5
     if (rc < 3 || str[offset] != '=') {
Paolo Bonzini d9c8b5
-        error_report("can't parse: \"%s\"", str);
Paolo Bonzini d9c8b5
-        return -1;
Paolo Bonzini d9c8b5
-    }
Paolo Bonzini d9c8b5
-
Paolo Bonzini d9c8b5
-    list = qemu_find_opts(group);
Paolo Bonzini d9c8b5
-    if (list == NULL) {
Paolo Bonzini d9c8b5
-        return -1;
Paolo Bonzini d9c8b5
-    }
Paolo Bonzini d9c8b5
-
Paolo Bonzini d9c8b5
-    opts = qemu_opts_find(list, id);
Paolo Bonzini d9c8b5
-    if (!opts) {
Paolo Bonzini d9c8b5
-        error_report("there is no %s \"%s\" defined",
Paolo Bonzini d9c8b5
-                     list->name, id);
Paolo Bonzini d9c8b5
-        return -1;
Paolo Bonzini d9c8b5
+        error_setg(errp, "can't parse: \"%s\"", str);
Paolo Bonzini d9c8b5
+        return;
Paolo Bonzini d9c8b5
     }
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
-    if (!qemu_opt_set(opts, arg, str + offset + 1, &local_err)) {
Paolo Bonzini d9c8b5
-        error_report_err(local_err);
Paolo Bonzini d9c8b5
-        return -1;
Paolo Bonzini d9c8b5
+    if (!is_qemuopts_group(group)) {
Paolo Bonzini d9c8b5
+        error_setg(errp, "-set is not supported with %s", group);
Paolo Bonzini d9c8b5
+    } else {
Paolo Bonzini d9c8b5
+        list = qemu_find_opts_err(group, errp);
Paolo Bonzini d9c8b5
+        if (list) {
Paolo Bonzini d9c8b5
+            opts = qemu_opts_find(list, id);
Paolo Bonzini d9c8b5
+            if (!opts) {
Paolo Bonzini d9c8b5
+                error_setg(errp, "there is no %s \"%s\" defined", group, id);
Paolo Bonzini d9c8b5
+                return;
Paolo Bonzini d9c8b5
+            }
Paolo Bonzini d9c8b5
+            qemu_opt_set(opts, arg, str + offset + 1, errp);
Paolo Bonzini d9c8b5
+        }
Paolo Bonzini d9c8b5
     }
Paolo Bonzini d9c8b5
-    return 0;
Paolo Bonzini d9c8b5
 }
Paolo Bonzini d9c8b5
 
Paolo Bonzini d9c8b5
 static void user_register_global_props(void)
Paolo Bonzini d9c8b5
@@ -2752,8 +2788,7 @@ void qemu_init(int argc, char **argv, char **envp)
Paolo Bonzini d9c8b5
                 }
Paolo Bonzini d9c8b5
                 break;
Paolo Bonzini d9c8b5
             case QEMU_OPTION_set:
Paolo Bonzini d9c8b5
-                if (qemu_set_option(optarg) != 0)
Paolo Bonzini d9c8b5
-                    exit(1);
Paolo Bonzini d9c8b5
+                qemu_set_option(optarg, &error_fatal);
Paolo Bonzini d9c8b5
                 break;
Paolo Bonzini d9c8b5
             case QEMU_OPTION_global:
Paolo Bonzini d9c8b5
                 if (qemu_global_option(optarg) != 0)
Paolo Bonzini d9c8b5
@@ -3385,7 +3420,7 @@ void qemu_init(int argc, char **argv, char **envp)
Paolo Bonzini d9c8b5
                 qemu_plugin_opt_parse(optarg, &plugin_list);
Paolo Bonzini d9c8b5
                 break;
Paolo Bonzini d9c8b5
             case QEMU_OPTION_readconfig:
Paolo Bonzini d9c8b5
-                qemu_read_config_file(optarg, qemu_config_do_parse, &error_fatal);
Paolo Bonzini d9c8b5
+                qemu_read_config_file(optarg, qemu_parse_config_group, &error_fatal);
Paolo Bonzini d9c8b5
                 break;
Paolo Bonzini d9c8b5
             case QEMU_OPTION_spice:
Paolo Bonzini d9c8b5
                 olist = qemu_find_opts_err("spice", NULL);
Paolo Bonzini d9c8b5
-- 
Paolo Bonzini d9c8b5
2.31.1
Paolo Bonzini d9c8b5