mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: caps: Move QAPI schema related code into separate file
Extract the code into qemu_qapi.c/h so that we separate it from various parts of the code. Signed-off-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
9be9e26b74
commit
367697c54c
@ -141,6 +141,7 @@ src/qemu/qemu_monitor_json.c
|
|||||||
src/qemu/qemu_monitor_text.c
|
src/qemu/qemu_monitor_text.c
|
||||||
src/qemu/qemu_parse_command.c
|
src/qemu/qemu_parse_command.c
|
||||||
src/qemu/qemu_process.c
|
src/qemu/qemu_process.c
|
||||||
|
src/qemu/qemu_qapi.c
|
||||||
src/remote/remote_client_bodies.h
|
src/remote/remote_client_bodies.h
|
||||||
src/remote/remote_daemon.c
|
src/remote/remote_daemon.c
|
||||||
src/remote/remote_daemon_config.c
|
src/remote/remote_daemon_config.c
|
||||||
|
@ -46,6 +46,8 @@ QEMU_DRIVER_SOURCES = \
|
|||||||
qemu/qemu_capspriv.h \
|
qemu/qemu_capspriv.h \
|
||||||
qemu/qemu_security.c \
|
qemu/qemu_security.c \
|
||||||
qemu/qemu_security.h \
|
qemu/qemu_security.h \
|
||||||
|
qemu/qemu_qapi.c \
|
||||||
|
qemu/qemu_qapi.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "qemu_domain.h"
|
#include "qemu_domain.h"
|
||||||
#define __QEMU_CAPSPRIV_H_ALLOW__
|
#define __QEMU_CAPSPRIV_H_ALLOW__
|
||||||
#include "qemu_capspriv.h"
|
#include "qemu_capspriv.h"
|
||||||
|
#include "qemu_qapi.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -4564,163 +4565,6 @@ virQEMUCapsInitQMPBasicArch(virQEMUCapsPtr qemuCaps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virQEMUCapsQMPSchemaObjectGetType:
|
|
||||||
* @field: name of the object containing the requested type
|
|
||||||
* @name: name of the requested type
|
|
||||||
* @namefield: name of the object property holding @name
|
|
||||||
*
|
|
||||||
* Helper that selects the type of a QMP schema object member or it's variant
|
|
||||||
* member. Returns the type string on success or NULL on error.
|
|
||||||
*/
|
|
||||||
static const char *
|
|
||||||
virQEMUCapsQMPSchemaObjectGetType(const char *field,
|
|
||||||
const char *name,
|
|
||||||
const char *namefield,
|
|
||||||
virJSONValuePtr elem)
|
|
||||||
{
|
|
||||||
virJSONValuePtr arr;
|
|
||||||
virJSONValuePtr cur;
|
|
||||||
const char *curname;
|
|
||||||
const char *type;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!(arr = virJSONValueObjectGetArray(elem, field)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < virJSONValueArraySize(arr); i++) {
|
|
||||||
if (!(cur = virJSONValueArrayGet(arr, i)) ||
|
|
||||||
!(curname = virJSONValueObjectGetString(cur, namefield)) ||
|
|
||||||
!(type = virJSONValueObjectGetString(cur, "type")))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (STREQ(name, curname))
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static virJSONValuePtr
|
|
||||||
virQEMUCapsQMPSchemaTraverse(const char *baseName,
|
|
||||||
char **query,
|
|
||||||
virHashTablePtr schema)
|
|
||||||
{
|
|
||||||
virJSONValuePtr base;
|
|
||||||
const char *metatype;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!(base = virHashLookup(schema, baseName)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!*query)
|
|
||||||
return base;
|
|
||||||
|
|
||||||
if (!(metatype = virJSONValueObjectGetString(base, "meta-type")))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* flatten arrays by default */
|
|
||||||
if (STREQ(metatype, "array")) {
|
|
||||||
if (!(baseName = virJSONValueObjectGetString(base, "element-type")))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
} else if (STREQ(metatype, "object")) {
|
|
||||||
if (**query == '+')
|
|
||||||
baseName = virQEMUCapsQMPSchemaObjectGetType("variants",
|
|
||||||
*query + 1,
|
|
||||||
"case", base);
|
|
||||||
else
|
|
||||||
baseName = virQEMUCapsQMPSchemaObjectGetType("members",
|
|
||||||
*query,
|
|
||||||
"name", base);
|
|
||||||
|
|
||||||
if (!baseName)
|
|
||||||
return NULL;
|
|
||||||
} else if (STREQ(metatype, "command") ||
|
|
||||||
STREQ(metatype, "event")) {
|
|
||||||
if (!(baseName = virJSONValueObjectGetString(base, *query)))
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
/* alternates, basic types and enums can't be entered */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
query++;
|
|
||||||
} while (*query);
|
|
||||||
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virQEMUCapsQMPSchemaGetByPath:
|
|
||||||
* @query: string specifying the required data type (see below)
|
|
||||||
* @schema: hash table containing the schema data
|
|
||||||
* @entry: filled with the located schema object requested by @query
|
|
||||||
*
|
|
||||||
* Retrieves the requested schema entry specified by @query to @entry. The
|
|
||||||
* @query parameter has the following syntax which is very closely tied to the
|
|
||||||
* qemu schema syntax entries separated by slashes with a few special characters:
|
|
||||||
*
|
|
||||||
* "command_or_event/attribute/subattribute/+variant_discriminator/subattribute"
|
|
||||||
*
|
|
||||||
* command_or_event: name of the event or attribute to introspect
|
|
||||||
* attribute: selects whether arguments or return type should be introspected
|
|
||||||
* ("arg-type" or "ret-type" for commands, "arg-type" for events)
|
|
||||||
* subattribute: specifies member name of object types
|
|
||||||
* +variant_discriminator: In the case of unionized objects, select a
|
|
||||||
* specific case to introspect.
|
|
||||||
*
|
|
||||||
* Array types are automatically flattened to the singular type. Alternate
|
|
||||||
* types are currently not supported.
|
|
||||||
*
|
|
||||||
* The above types can be chained arbitrarily using slashes to construct any
|
|
||||||
* path into the schema tree.
|
|
||||||
*
|
|
||||||
* Returns 0 on success (including if the requested schema was not found) and
|
|
||||||
* fills @entry appropriately. On failure returns -1 and sets an appropriate
|
|
||||||
* error message.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
virQEMUCapsQMPSchemaGetByPath(const char *query,
|
|
||||||
virHashTablePtr schema,
|
|
||||||
virJSONValuePtr *entry)
|
|
||||||
{
|
|
||||||
char **elems = NULL;
|
|
||||||
|
|
||||||
*entry = NULL;
|
|
||||||
|
|
||||||
if (!(elems = virStringSplit(query, "/", 0)))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!*elems) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed query string"));
|
|
||||||
virStringListFree(elems);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*entry = virQEMUCapsQMPSchemaTraverse(*elems, elems + 1, schema);
|
|
||||||
|
|
||||||
virStringListFree(elems);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool
|
|
||||||
virQEMUCapsQMPSchemaQueryPath(const char *query,
|
|
||||||
virHashTablePtr schema)
|
|
||||||
{
|
|
||||||
virJSONValuePtr entry;
|
|
||||||
|
|
||||||
if (virQEMUCapsQMPSchemaGetByPath(query, schema, &entry))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return !!entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCapsPtr qemuCaps,
|
virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCapsPtr qemuCaps,
|
||||||
qemuMonitorPtr mon)
|
qemuMonitorPtr mon)
|
||||||
|
187
src/qemu/qemu_qapi.c
Normal file
187
src/qemu/qemu_qapi.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* qemu_qapi.c: helper functions for QEMU QAPI schema handling
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "qemu_qapi.h"
|
||||||
|
|
||||||
|
#include "viralloc.h"
|
||||||
|
#include "virstring.h"
|
||||||
|
#include "virerror.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
|
|
||||||
|
VIR_LOG_INIT("qemu.qemu_qapi");
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virQEMUCapsQMPSchemaObjectGetType:
|
||||||
|
* @field: name of the object containing the requested type
|
||||||
|
* @name: name of the requested type
|
||||||
|
* @namefield: name of the object property holding @name
|
||||||
|
*
|
||||||
|
* Helper that selects the type of a QMP schema object member or it's variant
|
||||||
|
* member. Returns the type string on success or NULL on error.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
virQEMUCapsQMPSchemaObjectGetType(const char *field,
|
||||||
|
const char *name,
|
||||||
|
const char *namefield,
|
||||||
|
virJSONValuePtr elem)
|
||||||
|
{
|
||||||
|
virJSONValuePtr arr;
|
||||||
|
virJSONValuePtr cur;
|
||||||
|
const char *curname;
|
||||||
|
const char *type;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!(arr = virJSONValueObjectGetArray(elem, field)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < virJSONValueArraySize(arr); i++) {
|
||||||
|
if (!(cur = virJSONValueArrayGet(arr, i)) ||
|
||||||
|
!(curname = virJSONValueObjectGetString(cur, namefield)) ||
|
||||||
|
!(type = virJSONValueObjectGetString(cur, "type")))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (STREQ(name, curname))
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static virJSONValuePtr
|
||||||
|
virQEMUCapsQMPSchemaTraverse(const char *baseName,
|
||||||
|
char **query,
|
||||||
|
virHashTablePtr schema)
|
||||||
|
{
|
||||||
|
virJSONValuePtr base;
|
||||||
|
const char *metatype;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (!(base = virHashLookup(schema, baseName)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!*query)
|
||||||
|
return base;
|
||||||
|
|
||||||
|
if (!(metatype = virJSONValueObjectGetString(base, "meta-type")))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* flatten arrays by default */
|
||||||
|
if (STREQ(metatype, "array")) {
|
||||||
|
if (!(baseName = virJSONValueObjectGetString(base, "element-type")))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
} else if (STREQ(metatype, "object")) {
|
||||||
|
if (**query == '+')
|
||||||
|
baseName = virQEMUCapsQMPSchemaObjectGetType("variants",
|
||||||
|
*query + 1,
|
||||||
|
"case", base);
|
||||||
|
else
|
||||||
|
baseName = virQEMUCapsQMPSchemaObjectGetType("members",
|
||||||
|
*query,
|
||||||
|
"name", base);
|
||||||
|
|
||||||
|
if (!baseName)
|
||||||
|
return NULL;
|
||||||
|
} else if (STREQ(metatype, "command") ||
|
||||||
|
STREQ(metatype, "event")) {
|
||||||
|
if (!(baseName = virJSONValueObjectGetString(base, *query)))
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
/* alternates, basic types and enums can't be entered */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
query++;
|
||||||
|
} while (*query);
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virQEMUCapsQMPSchemaGetByPath:
|
||||||
|
* @query: string specifying the required data type (see below)
|
||||||
|
* @schema: hash table containing the schema data
|
||||||
|
* @entry: filled with the located schema object requested by @query
|
||||||
|
*
|
||||||
|
* Retrieves the requested schema entry specified by @query to @entry. The
|
||||||
|
* @query parameter has the following syntax which is very closely tied to the
|
||||||
|
* qemu schema syntax entries separated by slashes with a few special characters:
|
||||||
|
*
|
||||||
|
* "command_or_event/attribute/subattribute/+variant_discriminator/subattribute"
|
||||||
|
*
|
||||||
|
* command_or_event: name of the event or attribute to introspect
|
||||||
|
* attribute: selects whether arguments or return type should be introspected
|
||||||
|
* ("arg-type" or "ret-type" for commands, "arg-type" for events)
|
||||||
|
* subattribute: specifies member name of object types
|
||||||
|
* +variant_discriminator: In the case of unionized objects, select a
|
||||||
|
* specific case to introspect.
|
||||||
|
*
|
||||||
|
* Array types are automatically flattened to the singular type. Alternate
|
||||||
|
* types are currently not supported.
|
||||||
|
*
|
||||||
|
* The above types can be chained arbitrarily using slashes to construct any
|
||||||
|
* path into the schema tree.
|
||||||
|
*
|
||||||
|
* Returns 0 on success (including if the requested schema was not found) and
|
||||||
|
* fills @entry appropriately. On failure returns -1 and sets an appropriate
|
||||||
|
* error message.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virQEMUCapsQMPSchemaGetByPath(const char *query,
|
||||||
|
virHashTablePtr schema,
|
||||||
|
virJSONValuePtr *entry)
|
||||||
|
{
|
||||||
|
char **elems = NULL;
|
||||||
|
|
||||||
|
*entry = NULL;
|
||||||
|
|
||||||
|
if (!(elems = virStringSplit(query, "/", 0)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!*elems) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed query string"));
|
||||||
|
virStringListFree(elems);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*entry = virQEMUCapsQMPSchemaTraverse(*elems, elems + 1, schema);
|
||||||
|
|
||||||
|
virStringListFree(elems);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
virQEMUCapsQMPSchemaQueryPath(const char *query,
|
||||||
|
virHashTablePtr schema)
|
||||||
|
{
|
||||||
|
virJSONValuePtr entry;
|
||||||
|
|
||||||
|
if (virQEMUCapsQMPSchemaGetByPath(query, schema, &entry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !!entry;
|
||||||
|
}
|
36
src/qemu/qemu_qapi.h
Normal file
36
src/qemu/qemu_qapi.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* qemu_qapi.h: helper functions for QEMU QAPI schema
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __QEMU_QAPI_H__
|
||||||
|
# define __QEMU_QAPI_H__
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
|
||||||
|
# include "virhash.h"
|
||||||
|
# include "virjson.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
virQEMUCapsQMPSchemaGetByPath(const char *query,
|
||||||
|
virHashTablePtr schema,
|
||||||
|
virJSONValuePtr *entry);
|
||||||
|
|
||||||
|
bool
|
||||||
|
virQEMUCapsQMPSchemaQueryPath(const char *query,
|
||||||
|
virHashTablePtr schema);
|
||||||
|
|
||||||
|
#endif /* __QEMU_QAPI_H__ */
|
Loading…
Reference in New Issue
Block a user