The current object_add HMP syntax only allows for creation of objects with scalar properties, or a list with a fixed scalar element type. Objects which have properties that are represented as structs in the QAPI schema cannot be created using -object.
This is a design limitation of the way the OptsVisitor is written. It simply iterates over the QemuOpts values as a flat list. The support for lists is enabled by allowing the same key to be repeated in the opts string. The QObjectInputVisitor now has functionality that allows it to replace OptsVisitor, maintaining full backwards compatibility for previous CLI syntax, while also allowing use of new syntax for structs. Thus -object can now support non-scalar properties, for example the QMP object: { "execute": "object-add", "arguments": { "qom-type": "demo", "id": "demo0", "parameters": { "foo": [ { "bar": "one", "wizz": "1" }, { "bar": "two", "wizz": "2" } ] } } } Would be creatable via the HMP now using object_add demo,id=demo0,\ foo.0.bar=one,foo.0.wizz=1,\ foo.1.bar=two,foo.1.wizz=2 Notice that this syntax is intentionally compatible with that currently used by block drivers. NB the indentation seen here after line continuations should not be used in reality, it is just for clarity in this commit message. Signed-off-by: Daniel P. Berrange <berra...@redhat.com> --- hmp.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/hmp.c b/hmp.c index 336e7bf..b32d8c8 100644 --- a/hmp.c +++ b/hmp.c @@ -25,7 +25,7 @@ #include "qemu/sockets.h" #include "monitor/monitor.h" #include "monitor/qdev.h" -#include "qapi/opts-visitor.h" +#include "qapi/qobject-input-visitor.h" #include "qapi/qmp/qerror.h" #include "qapi/string-output-visitor.h" #include "qapi/util.h" @@ -1696,21 +1696,30 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict) void hmp_object_add(Monitor *mon, const QDict *qdict) { Error *err = NULL; - QemuOpts *opts; Visitor *v; Object *obj = NULL; + QObject *pobj; - opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err); + pobj = qdict_crumple(qdict, true, &err); if (err) { - hmp_handle_error(mon, &err); - return; + goto cleanup; } - v = opts_visitor_new(opts); - obj = user_creatable_add(qdict, v, &err); + /* + * We need autocreate_list=true + permit_int_ranges=true + * in order to maintain compat with OptsVisitor creation + * of the 'numa' object which had an int16List property. + * + * We need autocreate_structs=1, because at the CLI level + * we have the object type + properties in the same flat + * struct, even though at the QMP level they are nested. + */ + v = qobject_input_visitor_new_autocast(pobj, true, 1, true); + obj = user_creatable_add(qobject_to_qdict(pobj), v, &err); visit_free(v); - qemu_opts_del(opts); + cleanup: + qobject_decref(pobj); if (err) { hmp_handle_error(mon, &err); } -- 2.7.4