@@ -678,6 +678,15 @@ 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 *vm_config_groups[32] = {
&qemu_drive_opts,
&qemu_chardev_opts,
@@ -695,6 +704,7 @@ static QemuOptsList *vm_config_groups[32] = {
&qemu_iscsi_opts,
&qemu_sandbox_opts,
&qemu_add_fd_opts,
+ &qemu_object_opts,
NULL,
};
@@ -2888,6 +2888,14 @@ STEXI
Enable FIPS 140-2 compliance mode.
ETEXI
+DEF("object", HAS_ARG, QEMU_OPTION_object,
+ "-object TYPENAME[,PROP1=VALUE1,...]\n"
+ " create an new object of type TYPENAME setting properties\n"
+ " in the order they are specified. Note that the 'id'\n"
+ " property must be set. These objects are placed in the\n"
+ " '/objects' path.\n",
+ QEMU_ARCH_ALL)
+
HXCOMM This is the last statement. Insert new options before this line!
STEXI
@end table
@@ -168,6 +168,7 @@ int main(int argc, char **argv)
#include "osdep.h"
#include "ui/qemu-spice.h"
+#include "qapi/string-input-visitor.h"
//#define DEBUG_NET
//#define DEBUG_SLIRP
@@ -2441,6 +2442,53 @@ static void free_and_trace(gpointer mem)
free(mem);
}
+static int object_set_property(const char *name, const char *value, void *opaque)
+{
+ Object *obj = OBJECT(opaque);
+ StringInputVisitor *siv;
+ Error *local_err = NULL;
+
+ if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0) {
+ return 0;
+ }
+
+ siv = string_input_visitor_new(value);
+ object_property_set(obj, string_input_get_visitor(siv), name, &local_err);
+ string_input_visitor_cleanup(siv);
+
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int object_create(QemuOpts *opts, void *opaque)
+{
+ const char *type = qemu_opt_get(opts, "qom-type");
+ const char *id = qemu_opts_id(opts);
+ Object *obj;
+
+ g_assert(type != NULL);
+
+ if (id == NULL) {
+ qerror_report(QERR_MISSING_PARAMETER, "id");
+ return -1;
+ }
+
+ obj = object_new(type);
+ if (qemu_opt_foreach(opts, object_set_property, obj, 1) < 0) {
+ return -1;
+ }
+
+ object_property_add_child(container_get(object_get_root(), "/objects"),
+ id, obj, NULL);
+
+ return 0;
+}
+
int qemu_init_main_loop(void)
{
return main_loop_init();
@@ -3411,6 +3459,9 @@ int main(int argc, char **argv, char **envp)
exit(1);
#endif
break;
+ case QEMU_OPTION_object:
+ opts = qemu_opts_parse(qemu_find_opts("object"), optarg, 1);
+ break;
default:
os_parse_cmd_args(popt->index, optarg);
}
@@ -3441,6 +3492,11 @@ int main(int argc, char **argv, char **envp)
qemu_set_version(machine->hw_version);
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create, NULL, 0) != 0) {
+ exit(1);
+ }
+
/* Init CPU def lists, based on config
* - Must be called after all the qemu_read_config_file() calls
* - Must be called before list_cpus()
This will create a new QOM object in the '/objects' path. Note that properties are set in order which allows for simple objects to be initialized entirely with this option and then realized. This option is roughly equivalent to -device but for things that are not devices. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> --- qemu-config.c | 10 ++++++++++ qemu-options.hx | 8 ++++++++ vl.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+)