monitor: Drop query-qmp-schema 'gen': false hack

QMP commands return their response as a generated QAPI type, which the
monitor core converts to JSON via QObject.

query-qmp-schema's response is the generated introspection data.  This
is a QLitObject since commit 7d0f982bfb "qapi: generate a literal
qobject for introspection", v2.12).  Before, it was a string.  Instead
of converting QLitObject / string -> QObject -> QAPI type
SchemaInfoList -> QObject -> JSON, we take a shortcut: the command is
'gen': false, so it can return the QObject instead of the QAPI type.
Slightly simpler and more efficient.

The next commit will filter the response for output policy, and this
is easier in the SchemaInfoList representation.  Drop the shortcut.

This replaces the manual command registration by a generated one.  The
manual registration makes the command available before the machine is
built by passing flag QCO_ALLOW_PRECONFIG.  To keep it available
there, we need need to add 'allow-preconfig': true to its definition
in the schema.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20210318155519.1224118-7-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2021-03-18 16:55:14 +01:00
parent a291a38fa1
commit 624fa80c8c
5 changed files with 18 additions and 20 deletions

View File

@ -231,8 +231,6 @@ static void monitor_init_qmp_commands(void)
qmp_init_marshal(&qmp_commands); 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, "device_add", qmp_device_add, qmp_register_command(&qmp_commands, "device_add", qmp_device_add,
QCO_NO_OPTIONS); QCO_NO_OPTIONS);

View File

@ -183,7 +183,4 @@ void help_cmd(Monitor *mon, const char *name);
void handle_hmp_command(MonitorHMP *mon, const char *cmdline); void handle_hmp_command(MonitorHMP *mon, const char *cmdline);
int hmp_compare_cmd(const char *name, const char *list); int hmp_compare_cmd(const char *name, const char *list);
void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
Error **errp);
#endif #endif

View File

@ -26,10 +26,14 @@
#include "monitor-internal.h" #include "monitor-internal.h"
#include "qemu-version.h" #include "qemu-version.h"
#include "qapi/compat-policy.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qapi-commands-control.h" #include "qapi/qapi-commands-control.h"
#include "qapi/qapi-commands-introspect.h"
#include "qapi/qapi-emit-events.h" #include "qapi/qapi-emit-events.h"
#include "qapi/qapi-introspect.h" #include "qapi/qapi-introspect.h"
#include "qapi/qapi-visit-introspect.h"
#include "qapi/qobject-input-visitor.h"
/* /*
* Accept QMP capabilities in @list for @mon. * Accept QMP capabilities in @list for @mon.
@ -130,17 +134,18 @@ CommandInfoList *qmp_query_commands(Error **errp)
return list; return list;
} }
/* SchemaInfoList *qmp_query_qmp_schema(Error **errp)
* Minor hack: generated marshalling suppressed for this command
* ('gen': false in the schema) so we can parse the JSON string
* directly into QObject instead of first parsing it with
* visit_type_SchemaInfoList() into a SchemaInfoList, then marshal it
* to QObject with generated output marshallers, every time. Instead,
* we do it in test-qobject-input-visitor.c, just to make sure
* qapi-gen.py's output actually conforms to the schema.
*/
void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
Error **errp)
{ {
*ret_data = qobject_from_qlit(&qmp_schema_qlit); QObject *obj = qobject_from_qlit(&qmp_schema_qlit);
Visitor *v = qobject_input_visitor_new(obj);
SchemaInfoList *schema = NULL;
/* test_visitor_in_qmp_introspect() ensures this can't fail */
visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
g_assert(schema);
qobject_unref(obj);
visit_free(v);
return schema;
} }

View File

@ -49,7 +49,7 @@
## ##
{ 'command': 'query-qmp-schema', { 'command': 'query-qmp-schema',
'returns': [ 'SchemaInfo' ], 'returns': [ 'SchemaInfo' ],
'gen': false } # just to simplify qmp_query_json() 'allow-preconfig': true }
## ##
# @SchemaMetaType: # @SchemaMetaType:

View File

@ -137,8 +137,6 @@ extern QemuOptsList qemu_chardev_opts;
static void init_qmp_commands(void) static void init_qmp_commands(void)
{ {
qmp_init_marshal(&qmp_commands); qmp_init_marshal(&qmp_commands);
qmp_register_command(&qmp_commands, "query-qmp-schema",
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
QTAILQ_INIT(&qmp_cap_negotiation_commands); QTAILQ_INIT(&qmp_cap_negotiation_commands);
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities", qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",