Kevin Wolf <kwolf@xxxxxxxxxx> writes: > The implementation for --object can be shared between > qemu-storage-daemon and other binaries, so move it into a function in > qom/object_interfaces.c that is accessible from everywhere. > > This also requires moving the implementation of qmp_object_add() into a > new user_creatable_add_qapi(), because qom/qom-qmp-cmds.c is not linked > for tools. > > user_creatable_print_help_from_qdict() can become static now. > > Signed-off-by: Kevin Wolf <kwolf@xxxxxxxxxx> > Acked-by: Peter Krempa <pkrempa@xxxxxxxxxx> > Reviewed-by: Eric Blake <eblake@xxxxxxxxxx> > --- > include/qom/object_interfaces.h | 41 +++++++++++++++-------- > qom/object_interfaces.c | 50 +++++++++++++++++++++++++++- > qom/qom-qmp-cmds.c | 20 +---------- > storage-daemon/qemu-storage-daemon.c | 24 ++----------- > 4 files changed, 80 insertions(+), 55 deletions(-) > > diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h > index 5299603f50..1e6c51b541 100644 > --- a/include/qom/object_interfaces.h > +++ b/include/qom/object_interfaces.h > @@ -2,6 +2,7 @@ > #define OBJECT_INTERFACES_H > > #include "qom/object.h" > +#include "qapi/qapi-types-qom.h" > #include "qapi/visitor.h" > > #define TYPE_USER_CREATABLE "user-creatable" > @@ -86,6 +87,18 @@ Object *user_creatable_add_type(const char *type, const char *id, > const QDict *qdict, > Visitor *v, Error **errp); > > +/** > + * user_creatable_add_qapi: > + * @options: the object definition > + * @errp: if an error occurs, a pointer to an area to store the error > + * > + * Create an instance of the user creatable object according to the > + * options passed in @opts as described in the QAPI schema documentation. > + * > + * Returns: the newly created object or NULL on error > + */ > +void user_creatable_add_qapi(ObjectOptions *options, Error **errp); > + > /** > * user_creatable_add_opts: > * @opts: the object definition > @@ -131,6 +144,21 @@ typedef bool (*user_creatable_add_opts_predicate)(const char *type); > int user_creatable_add_opts_foreach(void *opaque, > QemuOpts *opts, Error **errp); > > +/** > + * user_creatable_process_cmdline: > + * @optarg: the object definition string as passed on the command line > + * > + * Create an instance of the user creatable object by parsing optarg > + * with a keyval parser and implicit key 'qom-type', converting the > + * result to ObjectOptions and calling into qmp_object_add(). > + * > + * If a help option is given, print help instead and exit. > + * > + * This function is only meant to be called during command line parsing. > + * It exits the process on failure or after printing help. > + */ > +void user_creatable_process_cmdline(const char *optarg); > + > /** > * user_creatable_print_help: > * @type: the QOM type to be added > @@ -145,19 +173,6 @@ int user_creatable_add_opts_foreach(void *opaque, > */ > bool user_creatable_print_help(const char *type, QemuOpts *opts); > > -/** > - * user_creatable_print_help_from_qdict: > - * @args: options to create > - * > - * Prints help considering the other options given in @args (if "qom-type" is > - * given and valid, print properties for the type, otherwise print valid types) > - * > - * In contrast to user_creatable_print_help(), this function can't return that > - * no help was requested. It should only be called if we know that help is > - * requested and it will always print some help. > - */ > -void user_creatable_print_help_from_qdict(QDict *args); > - > /** > * user_creatable_del: > * @id: the unique ID for the object > diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c > index 02c3934329..2eaf9971f5 100644 > --- a/qom/object_interfaces.c > +++ b/qom/object_interfaces.c > @@ -2,10 +2,13 @@ > > #include "qemu/cutils.h" > #include "qapi/error.h" > +#include "qapi/qapi-commands-qom.h" > +#include "qapi/qapi-visit-qom.h" > #include "qapi/qmp/qdict.h" > #include "qapi/qmp/qerror.h" > #include "qapi/qmp/qjson.h" > #include "qapi/qobject-input-visitor.h" > +#include "qapi/qobject-output-visitor.h" > #include "qom/object_interfaces.h" > #include "qemu/help_option.h" > #include "qemu/id.h" > @@ -113,6 +116,29 @@ out: > return obj; > } > > +void user_creatable_add_qapi(ObjectOptions *options, Error **errp) > +{ > + Visitor *v; > + QObject *qobj; > + QDict *props; > + Object *obj; > + > + v = qobject_output_visitor_new(&qobj); > + visit_type_ObjectOptions(v, NULL, &options, &error_abort); > + visit_complete(v, &qobj); > + visit_free(v); > + > + props = qobject_to(QDict, qobj); > + qdict_del(props, "qom-type"); > + qdict_del(props, "id"); > + > + v = qobject_input_visitor_new(QOBJECT(props)); > + obj = user_creatable_add_type(ObjectType_str(options->qom_type), > + options->id, props, v, errp); > + object_unref(obj); > + visit_free(v); > +} > + Observation, not objection: 1. QMP core parses JSON text into QObject, passes to generated marshaller. 2. Marshaller converts QObject to ObjectOptions with the QObject input visitor, passes to qmp_object_add(). 3. qmp_object_add() wraps around user_creatable_add_qapi(). 4. user_creatable_add_qapi() converts right back to QObject with the QObject output visitor. It splits the result into qom_type, id and the rest, and passes all three to user_creatable_add_type(). 5. user_creatable_add_type() performs a virtual visit with the QObject input visitor. The outermost object it visits itself, its children it visits by calling object_property_set(). I sure hope we wouldn't write it this way from scratch :) I think your patch is a reasonable step towards a QOM that is at peace with QAPI. But there's plenty of work left. [...]