"Daniel P. Berrange" <berra...@redhat.com> writes: > 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
autocreate_struct_levels=1 Same in previous patch. > + * 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); > }