@@ -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
@@ -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;
}
@@ -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!
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(-)