Skip to content

Commit

Permalink
qapi/qom: QAPIfy object-add
Browse files Browse the repository at this point in the history
This converts object-add from 'gen': false to the ObjectOptions QAPI
type. As an immediate benefit, clients can now use QAPI schema
introspection for user creatable QOM objects.

It is also the first step towards making the QAPI schema the only
external interface for the creation of user creatable objects. Once all
other places (HMP and command lines of the system emulator and all
tools) go through QAPI, too, some object implementations can be
simplified because some checks (e.g. that mandatory options are set) are
already performed by QAPI, and in another step, QOM boilerplate code
could be generated from the schema.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
  • Loading branch information
kevmw committed Mar 15, 2021
1 parent 17cdbea commit 2ff24f6
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 31 deletions.
16 changes: 8 additions & 8 deletions hw/block/xen-block.c
Expand Up @@ -836,17 +836,17 @@ static XenBlockIOThread *xen_block_iothread_create(const char *id,
{
ERRP_GUARD();
XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
QDict *opts;
QObject *ret_data = NULL;
ObjectOptions *opts;

iothread->id = g_strdup(id);

opts = qdict_new();
qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
qdict_put_str(opts, "id", id);
qmp_object_add(opts, &ret_data, errp);
qobject_unref(opts);
qobject_unref(ret_data);
opts = g_new(ObjectOptions, 1);
*opts = (ObjectOptions) {
.qom_type = OBJECT_TYPE_IOTHREAD,
.id = g_strdup(id),
};
qmp_object_add(opts, errp);
qapi_free_ObjectOptions(opts);

if (*errp) {
g_free(iothread->id);
Expand Down
7 changes: 0 additions & 7 deletions include/qom/object_interfaces.h
Expand Up @@ -196,11 +196,4 @@ bool user_creatable_del(const char *id, Error **errp);
*/
void user_creatable_cleanup(void);

/**
* qmp_object_add:
*
* QMP command handler for object-add. See the QAPI schema for documentation.
*/
void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp);

#endif
2 changes: 0 additions & 2 deletions monitor/misc.c
Expand Up @@ -235,8 +235,6 @@ static void monitor_init_qmp_commands(void)
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
qmp_register_command(&qmp_commands, "device_add", qmp_device_add,
QCO_NO_OPTIONS);
qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
QCO_NO_OPTIONS);

QTAILQ_INIT(&qmp_cap_negotiation_commands);
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
Expand Down
11 changes: 1 addition & 10 deletions qapi/qom.json
Expand Up @@ -846,13 +846,6 @@
#
# Create a QOM object.
#
# @qom-type: the class name for the object to be created
#
# @id: the name of the new object
#
# Additional arguments depend on qom-type and are passed to the backend
# unchanged.
#
# Returns: Nothing on success
# Error if @qom-type is not a valid class name
#
Expand All @@ -866,9 +859,7 @@
# <- { "return": {} }
#
##
{ 'command': 'object-add',
'data': {'qom-type': 'str', 'id': 'str'},
'gen': false } # so we can get the additional arguments
{ 'command': 'object-add', 'data': 'ObjectOptions', 'boxed': true }

##
# @object-del:
Expand Down
25 changes: 23 additions & 2 deletions qom/qom-qmp-cmds.c
Expand Up @@ -19,8 +19,11 @@
#include "qapi/error.h"
#include "qapi/qapi-commands-qdev.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/qobject-input-visitor.h"
#include "qapi/qobject-output-visitor.h"
#include "qemu/cutils.h"
#include "qom/object_interfaces.h"
#include "qom/qom-qobject.h"
Expand Down Expand Up @@ -223,9 +226,27 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
return prop_list;
}

void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
void qmp_object_add(ObjectOptions *options, Error **errp)
{
user_creatable_add_dict(qdict, false, 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);
}

void qmp_object_del(const char *id, Error **errp)
Expand Down
2 changes: 0 additions & 2 deletions storage-daemon/qemu-storage-daemon.c
Expand Up @@ -148,8 +148,6 @@ static void init_qmp_commands(void)
qmp_init_marshal(&qmp_commands);
qmp_register_command(&qmp_commands, "query-qmp-schema",
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
QCO_NO_OPTIONS);

QTAILQ_INIT(&qmp_cap_negotiation_commands);
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
Expand Down

0 comments on commit 2ff24f6

Please sign in to comment.