add missing patches
This commit is contained in:
parent
169bee2e2a
commit
d9c8b54b44
@ -0,0 +1,46 @@
|
|||||||
|
From 7de096767b5e65d105168fbd5130397f9fbda626 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Date: Tue, 18 May 2021 12:35:31 +0200
|
||||||
|
Subject: [PATCH 1/5] vl: allow not specifying size in -m when using -M
|
||||||
|
memory-backend
|
||||||
|
|
||||||
|
Starting in QEMU 6.0's commit f5c9fcb82d ("vl: separate
|
||||||
|
qemu_create_machine", 2020-12-10), a function have_custom_ram_size()
|
||||||
|
replaced the return value of set_memory_options().
|
||||||
|
|
||||||
|
The purpose of the return value was to record the presence of
|
||||||
|
"-m size", and if it was not there, change the default RAM
|
||||||
|
size to the size of the memory backend passed with "-M
|
||||||
|
memory-backend".
|
||||||
|
|
||||||
|
With that commit, however, have_custom_ram_size() is now queried only
|
||||||
|
after set_memory_options has stored the fixed-up RAM size in QemuOpts for
|
||||||
|
"future use". This was actually the only future use of the fixed-up RAM
|
||||||
|
size, so remove that code and fix the bug.
|
||||||
|
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Fixes: f5c9fcb82d ("vl: separate qemu_create_machine", 2020-12-10)
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||||
|
Message-Id: <20210518103531.104162-1-pbonzini@redhat.com>
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
---
|
||||||
|
softmmu/vl.c | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||||
|
index aadb526..29d6415 100644
|
||||||
|
--- a/softmmu/vl.c
|
||||||
|
+++ b/softmmu/vl.c
|
||||||
|
@@ -2025,8 +2025,6 @@ static void set_memory_options(MachineClass *mc)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* store value for the future use */
|
||||||
|
- qemu_opt_set_number(opts, "size", ram_size, &error_abort);
|
||||||
|
maxram_size = ram_size;
|
||||||
|
|
||||||
|
if (qemu_opt_get(opts, "maxmem")) {
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
120
0002-qemu-config-load-modules-when-instantiating-option-g.patch
Normal file
120
0002-qemu-config-load-modules-when-instantiating-option-g.patch
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
From 7b861d20e22278fc5915f03d77b83e07ba44d440 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Date: Tue, 18 May 2021 09:15:42 -0400
|
||||||
|
Subject: [PATCH 2/5] qemu-config: load modules when instantiating option
|
||||||
|
groups
|
||||||
|
|
||||||
|
Right now the SPICE module is special cased to be loaded when processing
|
||||||
|
of the -spice command line option. However, the spice option group
|
||||||
|
can also be brought in via -readconfig, in which case the module is
|
||||||
|
not loaded.
|
||||||
|
|
||||||
|
Add a generic hook to load modules that provide a QemuOpts group,
|
||||||
|
and use it for the "spice" and "iscsi" groups.
|
||||||
|
|
||||||
|
Fixes: #194
|
||||||
|
Fixes: https://bugs.launchpad.net/qemu/+bug/1910696
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Message-Id: <20210518131542.2941207-1-pbonzini@redhat.com>
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
---
|
||||||
|
include/qemu/config-file.h | 2 +-
|
||||||
|
softmmu/vl.c | 21 +++++++++++++++++----
|
||||||
|
stubs/meson.build | 1 +
|
||||||
|
stubs/module-opts.c | 6 ++++++
|
||||||
|
util/qemu-config.c | 1 +
|
||||||
|
5 files changed, 26 insertions(+), 5 deletions(-)
|
||||||
|
create mode 100644 stubs/module-opts.c
|
||||||
|
|
||||||
|
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
|
||||||
|
index 8d3e53a..0500b36 100644
|
||||||
|
--- a/include/qemu/config-file.h
|
||||||
|
+++ b/include/qemu/config-file.h
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
#ifndef QEMU_CONFIG_FILE_H
|
||||||
|
#define QEMU_CONFIG_FILE_H
|
||||||
|
|
||||||
|
-
|
||||||
|
+void qemu_load_module_for_opts(const char *group);
|
||||||
|
QemuOptsList *qemu_find_opts(const char *group);
|
||||||
|
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
|
||||||
|
QemuOpts *qemu_find_opts_singleton(const char *group);
|
||||||
|
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||||
|
index 29d6415..4641f08 100644
|
||||||
|
--- a/softmmu/vl.c
|
||||||
|
+++ b/softmmu/vl.c
|
||||||
|
@@ -2613,6 +2613,23 @@ void qmp_x_exit_preconfig(Error **errp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef CONFIG_MODULES
|
||||||
|
+void qemu_load_module_for_opts(const char *group)
|
||||||
|
+{
|
||||||
|
+ static bool spice_tried = false;
|
||||||
|
+ if (g_str_equal(group, "spice") && !spice_tried) {
|
||||||
|
+ ui_module_load_one("spice-core");
|
||||||
|
+ spice_tried = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ static bool iscsi_tried = false;
|
||||||
|
+ if (g_str_equal(group, "iscsi") && !iscsi_tried) {
|
||||||
|
+ block_module_load_one("iscsi");
|
||||||
|
+ iscsi_tried = true;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
void qemu_init(int argc, char **argv, char **envp)
|
||||||
|
{
|
||||||
|
QemuOpts *opts;
|
||||||
|
@@ -3372,10 +3389,6 @@ void qemu_init(int argc, char **argv, char **envp)
|
||||||
|
break;
|
||||||
|
case QEMU_OPTION_spice:
|
||||||
|
olist = qemu_find_opts_err("spice", NULL);
|
||||||
|
- if (!olist) {
|
||||||
|
- ui_module_load_one("spice-core");
|
||||||
|
- olist = qemu_find_opts("spice");
|
||||||
|
- }
|
||||||
|
if (!olist) {
|
||||||
|
error_report("spice support is disabled");
|
||||||
|
exit(1);
|
||||||
|
diff --git a/stubs/meson.build b/stubs/meson.build
|
||||||
|
index be6f6d6..5555b69 100644
|
||||||
|
--- a/stubs/meson.build
|
||||||
|
+++ b/stubs/meson.build
|
||||||
|
@@ -22,6 +22,7 @@ stub_ss.add(files('isa-bus.c'))
|
||||||
|
stub_ss.add(files('is-daemonized.c'))
|
||||||
|
stub_ss.add(when: 'CONFIG_LINUX_AIO', if_true: files('linux-aio.c'))
|
||||||
|
stub_ss.add(files('migr-blocker.c'))
|
||||||
|
+stub_ss.add(files('module-opts.c'))
|
||||||
|
stub_ss.add(files('monitor.c'))
|
||||||
|
stub_ss.add(files('monitor-core.c'))
|
||||||
|
stub_ss.add(files('pci-bus.c'))
|
||||||
|
diff --git a/stubs/module-opts.c b/stubs/module-opts.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..a7d0e4a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/stubs/module-opts.c
|
||||||
|
@@ -0,0 +1,6 @@
|
||||||
|
+#include "qemu/osdep.h"
|
||||||
|
+#include "qemu/config-file.h"
|
||||||
|
+
|
||||||
|
+void qemu_load_module_for_opts(const char *group)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
diff --git a/util/qemu-config.c b/util/qemu-config.c
|
||||||
|
index 670bd6e..34974c4 100644
|
||||||
|
--- a/util/qemu-config.c
|
||||||
|
+++ b/util/qemu-config.c
|
||||||
|
@@ -16,6 +16,7 @@ static QemuOptsList *find_list(QemuOptsList **lists, const char *group,
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
+ qemu_load_module_for_opts(group);
|
||||||
|
for (i = 0; lists[i] != NULL; i++) {
|
||||||
|
if (strcmp(lists[i]->name, group) == 0)
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
236
0003-qemu-config-parse-configuration-files-to-a-QDict.patch
Normal file
236
0003-qemu-config-parse-configuration-files-to-a-QDict.patch
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
From a0520e180e6f235b8a3a531b0756e45cbfe36e15 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Date: Tue, 18 May 2021 11:40:57 -0400
|
||||||
|
Subject: [PATCH 3/5] qemu-config: parse configuration files to a QDict
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
This is useful for -readconfig to support keyval-based options;
|
||||||
|
getting a QDict from the parser removes a roundtrip from
|
||||||
|
QDict to QemuOpts and then back to QDict.
|
||||||
|
|
||||||
|
Unfortunately there is a disadvantage in that semantic errors will
|
||||||
|
point to the last line of the group, because the entries of the QDict
|
||||||
|
do not have a location attached.
|
||||||
|
|
||||||
|
Cc: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Cc: Markus Armbruster <armbru@redhat.com>
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Message-Id: <20210524105752.3318299-2-pbonzini@redhat.com>
|
||||||
|
---
|
||||||
|
include/qemu/config-file.h | 7 ++-
|
||||||
|
softmmu/vl.c | 4 +-
|
||||||
|
util/qemu-config.c | 97 ++++++++++++++++++++++++++------------
|
||||||
|
3 files changed, 75 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
|
||||||
|
index 0500b36..f605423 100644
|
||||||
|
--- a/include/qemu/config-file.h
|
||||||
|
+++ b/include/qemu/config-file.h
|
||||||
|
@@ -1,6 +1,8 @@
|
||||||
|
#ifndef QEMU_CONFIG_FILE_H
|
||||||
|
#define QEMU_CONFIG_FILE_H
|
||||||
|
|
||||||
|
+typedef void QEMUConfigCB(const char *group, QDict *qdict, void *opaque, Error **errp);
|
||||||
|
+
|
||||||
|
void qemu_load_module_for_opts(const char *group);
|
||||||
|
QemuOptsList *qemu_find_opts(const char *group);
|
||||||
|
QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
|
||||||
|
@@ -14,7 +16,10 @@ 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 4641f08..da5042f 100644
|
||||||
|
--- a/softmmu/vl.c
|
||||||
|
+++ b/softmmu/vl.c
|
||||||
|
@@ -2119,7 +2119,7 @@ static void qemu_read_default_config_file(Error **errp)
|
||||||
|
int ret;
|
||||||
|
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
|
||||||
|
|
||||||
|
- ret = qemu_read_config_file(file, errp);
|
||||||
|
+ ret = qemu_read_config_file(file, qemu_config_do_parse, errp);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (ret == -ENOENT) {
|
||||||
|
error_free(*errp);
|
||||||
|
@@ -3385,7 +3385,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 34974c4..f6eaff9 100644
|
||||||
|
--- a/util/qemu-config.c
|
||||||
|
+++ b/util/qemu-config.c
|
||||||
|
@@ -2,6 +2,7 @@
|
||||||
|
#include "block/qdict.h" /* for qdict_extract_subqdict() */
|
||||||
|
#include "qapi/error.h"
|
||||||
|
#include "qapi/qapi-commands-misc.h"
|
||||||
|
+#include "qapi/qmp/qerror.h"
|
||||||
|
#include "qapi/qmp/qdict.h"
|
||||||
|
#include "qapi/qmp/qlist.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
|
@@ -351,19 +352,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;
|
||||||
|
@@ -372,39 +373,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");
|
||||||
|
@@ -417,11 +418,47 @@ int qemu_config_parse(FILE *fp, QemuOptsList **lists, const char *fname, Error *
|
||||||
|
}
|
||||||
|
res = count;
|
||||||
|
out:
|
||||||
|
+ if (qdict) {
|
||||||
|
+ cb(group, qdict, opaque, errp);
|
||||||
|
+ qobject_unref(qdict);
|
||||||
|
+ }
|
||||||
|
loc_pop(&loc);
|
||||||
|
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;
|
||||||
|
+ const QDictEntry *unrecognized;
|
||||||
|
+
|
||||||
|
+ list = find_list(lists, group, errp);
|
||||||
|
+ if (!list) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ opts = qemu_opts_create(list, id, 1, errp);
|
||||||
|
+ if (!opts) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (!qemu_opts_absorb_qdict(opts, qdict, errp)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ unrecognized = qdict_first(qdict);
|
||||||
|
+ if (unrecognized) {
|
||||||
|
+ error_setg(errp, QERR_INVALID_PARAMETER, unrecognized->key);
|
||||||
|
+ qemu_opts_del(opts);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+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;
|
||||||
|
@@ -431,7 +468,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.31.1
|
||||||
|
|
187
0004-vl-plumb-keyval-based-options-into-readconfig.patch
Normal file
187
0004-vl-plumb-keyval-based-options-into-readconfig.patch
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
From 8eef1078eff6fc5cc045684486d228153463dac2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Date: Tue, 18 May 2021 11:40:58 -0400
|
||||||
|
Subject: [PATCH 4/5] vl: plumb keyval-based options into -readconfig
|
||||||
|
|
||||||
|
Let -readconfig support parsing command line options into QDict or
|
||||||
|
QemuOpts. This will be used to add back support for objects in
|
||||||
|
-readconfig.
|
||||||
|
|
||||||
|
Cc: Markus Armbruster <armbru@redhat.com>
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Message-Id: <20210524105752.3318299-3-pbonzini@redhat.com>
|
||||||
|
---
|
||||||
|
include/block/qdict.h | 2 -
|
||||||
|
include/qapi/qmp/qdict.h | 3 ++
|
||||||
|
softmmu/vl.c | 83 ++++++++++++++++++++++++++++------------
|
||||||
|
3 files changed, 62 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/include/block/qdict.h b/include/block/qdict.h
|
||||||
|
index d8cb502..ced2acf 100644
|
||||||
|
--- a/include/block/qdict.h
|
||||||
|
+++ b/include/block/qdict.h
|
||||||
|
@@ -20,8 +20,6 @@ void qdict_join(QDict *dest, QDict *src, bool overwrite);
|
||||||
|
void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start);
|
||||||
|
void qdict_array_split(QDict *src, QList **dst);
|
||||||
|
int qdict_array_entries(QDict *src, const char *subqdict);
|
||||||
|
-QObject *qdict_crumple(const QDict *src, Error **errp);
|
||||||
|
-void qdict_flatten(QDict *qdict);
|
||||||
|
|
||||||
|
typedef struct QDictRenames {
|
||||||
|
const char *from;
|
||||||
|
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
|
||||||
|
index 9934539..d5b5430 100644
|
||||||
|
--- a/include/qapi/qmp/qdict.h
|
||||||
|
+++ b/include/qapi/qmp/qdict.h
|
||||||
|
@@ -64,4 +64,7 @@ const char *qdict_get_try_str(const QDict *qdict, const char *key);
|
||||||
|
|
||||||
|
QDict *qdict_clone_shallow(const QDict *src);
|
||||||
|
|
||||||
|
+QObject *qdict_crumple(const QDict *src, Error **errp);
|
||||||
|
+void qdict_flatten(QDict *qdict);
|
||||||
|
+
|
||||||
|
#endif /* QDICT_H */
|
||||||
|
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||||
|
index da5042f..48d1f06 100644
|
||||||
|
--- a/softmmu/vl.c
|
||||||
|
+++ b/softmmu/vl.c
|
||||||
|
@@ -122,6 +122,7 @@
|
||||||
|
#include "qapi/qapi-commands-misc.h"
|
||||||
|
#include "qapi/qapi-visit-qom.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"
|
||||||
|
@@ -2113,13 +2114,53 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Return whether configuration group @group is stored in QemuOpts, or
|
||||||
|
+ * recorded as one or more QDicts by qemu_record_config_group.
|
||||||
|
+ */
|
||||||
|
+static bool is_qemuopts_group(const char *group)
|
||||||
|
+{
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void qemu_record_config_group(const char *group, QDict *dict,
|
||||||
|
+ bool from_json, Error **errp)
|
||||||
|
+{
|
||||||
|
+ abort();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * 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)
|
||||||
|
+{
|
||||||
|
+ QObject *crumpled;
|
||||||
|
+ if (is_qemuopts_group(group)) {
|
||||||
|
+ qemu_config_do_parse(group, qdict, opaque, errp);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ crumpled = qdict_crumple(qdict, errp);
|
||||||
|
+ if (!crumpled) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ if (qobject_type(crumpled) != QTYPE_QDICT) {
|
||||||
|
+ assert(qobject_type(crumpled) == QTYPE_QLIST);
|
||||||
|
+ error_setg(errp, "Lists cannot be at top level of a configuration section");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ qemu_record_config_group(group, qobject_to(QDict, crumpled), false, errp);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void qemu_read_default_config_file(Error **errp)
|
||||||
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
|
int ret;
|
||||||
|
g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf");
|
||||||
|
|
||||||
|
- ret = qemu_read_config_file(file, qemu_config_do_parse, errp);
|
||||||
|
+ ret = qemu_read_config_file(file, qemu_parse_config_group, errp);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (ret == -ENOENT) {
|
||||||
|
error_free(*errp);
|
||||||
|
@@ -2128,9 +2169,8 @@ static void qemu_read_default_config_file(Error **errp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int qemu_set_option(const char *str)
|
||||||
|
+static void qemu_set_option(const char *str, Error **errp)
|
||||||
|
{
|
||||||
|
- Error *local_err = NULL;
|
||||||
|
char group[64], id[64], arg[64];
|
||||||
|
QemuOptsList *list;
|
||||||
|
QemuOpts *opts;
|
||||||
|
@@ -2138,27 +2178,23 @@ static int qemu_set_option(const char *str)
|
||||||
|
|
||||||
|
rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
|
||||||
|
if (rc < 3 || str[offset] != '=') {
|
||||||
|
- error_report("can't parse: \"%s\"", str);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- list = qemu_find_opts(group);
|
||||||
|
- if (list == NULL) {
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- opts = qemu_opts_find(list, id);
|
||||||
|
- if (!opts) {
|
||||||
|
- error_report("there is no %s \"%s\" defined",
|
||||||
|
- list->name, id);
|
||||||
|
- return -1;
|
||||||
|
+ error_setg(errp, "can't parse: \"%s\"", str);
|
||||||
|
+ return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!qemu_opt_set(opts, arg, str + offset + 1, &local_err)) {
|
||||||
|
- error_report_err(local_err);
|
||||||
|
- return -1;
|
||||||
|
+ if (!is_qemuopts_group(group)) {
|
||||||
|
+ error_setg(errp, "-set is not supported with %s", group);
|
||||||
|
+ } else {
|
||||||
|
+ list = qemu_find_opts_err(group, errp);
|
||||||
|
+ if (list) {
|
||||||
|
+ opts = qemu_opts_find(list, id);
|
||||||
|
+ if (!opts) {
|
||||||
|
+ error_setg(errp, "there is no %s \"%s\" defined", group, id);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ qemu_opt_set(opts, arg, str + offset + 1, errp);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void user_register_global_props(void)
|
||||||
|
@@ -2752,8 +2788,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QEMU_OPTION_set:
|
||||||
|
- if (qemu_set_option(optarg) != 0)
|
||||||
|
- exit(1);
|
||||||
|
+ qemu_set_option(optarg, &error_fatal);
|
||||||
|
break;
|
||||||
|
case QEMU_OPTION_global:
|
||||||
|
if (qemu_global_option(optarg) != 0)
|
||||||
|
@@ -3385,7 +3420,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);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
87
0005-vl-plug-object-back-into-readconfig.patch
Normal file
87
0005-vl-plug-object-back-into-readconfig.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
From 10b889b529490efb228667505bab851e8e406c67 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Date: Tue, 18 May 2021 11:40:59 -0400
|
||||||
|
Subject: [PATCH 5/5] vl: plug -object back into -readconfig
|
||||||
|
|
||||||
|
Commit bc2f4fcb1d ("qom: move user_creatable_add_opts logic to vl.c
|
||||||
|
and QAPIfy it", 2021-03-19) switched the creation of objects from
|
||||||
|
qemu_opts_foreach to a bespoke QTAILQ in preparation for supporting JSON
|
||||||
|
syntax in -object.
|
||||||
|
|
||||||
|
Unfortunately in doing so it lost support for [object] stanzas in
|
||||||
|
configuration files and also for "-set object.ID.KEY=VAL". The latter
|
||||||
|
is hard to re-establish and probably best solved by deprecating -set.
|
||||||
|
This patch uses the infrastructure introduced by the previous two
|
||||||
|
patches in order to parse QOM objects correctly from configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
Cc: Markus Armbruster <armbru@redhat.com>
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
|
||||||
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
Message-Id: <20210524105752.3318299-4-pbonzini@redhat.com>
|
||||||
|
---
|
||||||
|
softmmu/vl.c | 24 ++++++++++++++++++------
|
||||||
|
1 file changed, 18 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/softmmu/vl.c b/softmmu/vl.c
|
||||||
|
index 48d1f06..d282dea 100644
|
||||||
|
--- a/softmmu/vl.c
|
||||||
|
+++ b/softmmu/vl.c
|
||||||
|
@@ -1709,9 +1709,15 @@ static void object_option_foreach_add(bool (*type_opt_predicate)(const char *))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void object_option_add_visitor(Visitor *v)
|
||||||
|
+{
|
||||||
|
+ ObjectOption *opt = g_new0(ObjectOption, 1);
|
||||||
|
+ visit_type_ObjectOptions(v, NULL, &opt->opts, &error_fatal);
|
||||||
|
+ QTAILQ_INSERT_TAIL(&object_opts, opt, next);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void object_option_parse(const char *optarg)
|
||||||
|
{
|
||||||
|
- ObjectOption *opt;
|
||||||
|
QemuOpts *opts;
|
||||||
|
const char *type;
|
||||||
|
Visitor *v;
|
||||||
|
@@ -1739,11 +1745,8 @@ static void object_option_parse(const char *optarg)
|
||||||
|
v = opts_visitor_new(opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
- opt = g_new0(ObjectOption, 1);
|
||||||
|
- visit_type_ObjectOptions(v, NULL, &opt->opts, &error_fatal);
|
||||||
|
+ object_option_add_visitor(v);
|
||||||
|
visit_free(v);
|
||||||
|
-
|
||||||
|
- QTAILQ_INSERT_TAIL(&object_opts, opt, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2120,13 +2123,22 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp)
|
||||||
|
*/
|
||||||
|
static bool is_qemuopts_group(const char *group)
|
||||||
|
{
|
||||||
|
+ if (g_str_equal(group, "object")) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qemu_record_config_group(const char *group, QDict *dict,
|
||||||
|
bool from_json, Error **errp)
|
||||||
|
{
|
||||||
|
- abort();
|
||||||
|
+ if (g_str_equal(group, "object")) {
|
||||||
|
+ Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict));
|
||||||
|
+ object_option_add_visitor(v);
|
||||||
|
+ visit_free(v);
|
||||||
|
+ } else {
|
||||||
|
+ abort();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user