From: Anthony Liguori <aligu...@us.ibm.com> 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 <aligu...@us.ibm.com> --- qemu-config.c | 10 ++++++++++ qemu-options.hx | 8 ++++++++ vl.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 0 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index cd1ec21..d695bdf 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -653,6 +653,15 @@ QemuOptsList qemu_boot_opts = { }, }; +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, @@ -669,6 +678,7 @@ static QemuOptsList *vm_config_groups[32] = { &qemu_boot_opts, &qemu_iscsi_opts, &qemu_sandbox_opts, + &qemu_object_opts, NULL, }; diff --git a/qemu-options.hx b/qemu-options.hx index 46f0539..b72151e 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2852,6 +2852,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 diff --git a/vl.c b/vl.c index ee3c43a..eabf47b 100644 --- a/vl.c +++ b/vl.c @@ -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 @@ -2357,6 +2358,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(); @@ -3308,6 +3356,9 @@ int main(int argc, char **argv, char **envp) if (!opts) { exit(0); } + break; + case QEMU_OPTION_object: + opts = qemu_opts_parse(qemu_find_opts("object"), optarg, 1); break; default: os_parse_cmd_args(popt->index, optarg); @@ -3319,6 +3370,9 @@ int main(int argc, char **argv, char **envp) if (qemu_opts_foreach(qemu_find_opts("sandbox"), parse_sandbox, NULL, 0)) { exit(1); } + if (qemu_opts_foreach(qemu_find_opts("object"), object_create, NULL, 0) != 0) { + exit(1); + } if (machine == NULL) { fprintf(stderr, "No machine found.\n"); -- 1.7.7.6