qapi: Implement deprecated-output=hide for QMP introspection

This policy suppresses deprecated bits in output, and thus permits
"testing the future".  Implement it for QMP command query-qmp-schema:
suppress information on deprecated commands, events and object type
members, i.e. anything that has the special feature flag "deprecated".

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20210318155519.1224118-8-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2021-03-18 16:55:15 +01:00
parent 624fa80c8c
commit 2df68d777c
1 changed files with 71 additions and 0 deletions

View File

@ -134,6 +134,74 @@ CommandInfoList *qmp_query_commands(Error **errp)
return list;
}
static void *split_off_generic_list(void *list,
bool (*splitp)(void *elt),
void **part)
{
GenericList *keep = NULL, **keep_tailp = &keep;
GenericList *split = NULL, **split_tailp = &split;
GenericList *tail;
for (tail = list; tail; tail = tail->next) {
if (splitp(tail)) {
*split_tailp = tail;
split_tailp = &tail->next;
} else {
*keep_tailp = tail;
keep_tailp = &tail->next;
}
}
*keep_tailp = *split_tailp = NULL;
*part = split;
return keep;
}
static bool is_in(const char *s, strList *list)
{
strList *tail;
for (tail = list; tail; tail = tail->next) {
if (!strcmp(tail->value, s)) {
return true;
}
}
return false;
}
static bool is_entity_deprecated(void *link)
{
return is_in("deprecated", ((SchemaInfoList *)link)->value->features);
}
static bool is_member_deprecated(void *link)
{
return is_in("deprecated",
((SchemaInfoObjectMemberList *)link)->value->features);
}
static SchemaInfoList *zap_deprecated(SchemaInfoList *schema)
{
void *to_zap;
SchemaInfoList *tail;
SchemaInfo *ent;
schema = split_off_generic_list(schema, is_entity_deprecated, &to_zap);
qapi_free_SchemaInfoList(to_zap);
for (tail = schema; tail; tail = tail->next) {
ent = tail->value;
if (ent->meta_type == SCHEMA_META_TYPE_OBJECT) {
ent->u.object.members
= split_off_generic_list(ent->u.object.members,
is_member_deprecated, &to_zap);
qapi_free_SchemaInfoObjectMemberList(to_zap);
}
}
return schema;
}
SchemaInfoList *qmp_query_qmp_schema(Error **errp)
{
QObject *obj = qobject_from_qlit(&qmp_schema_qlit);
@ -147,5 +215,8 @@ SchemaInfoList *qmp_query_qmp_schema(Error **errp)
qobject_unref(obj);
visit_free(v);
if (compat_policy.deprecated_output == COMPAT_POLICY_OUTPUT_HIDE) {
return zap_deprecated(schema);
}
return schema;
}