mirror of https://gitee.com/openkylin/libvirt.git
qemu: Probe GIC capabilities
QEMU introduced the query-gic-capabilities QMP command with commit 4468d4e0f383: use the command, if available, to probe available GIC capabilities. The information obtained is stored in a virQEMUCaps instance, and will be later used to fill in a virDomainCaps instance.
This commit is contained in:
parent
29980231db
commit
12209ba5bd
|
@ -358,6 +358,9 @@ struct _virQEMUCaps {
|
|||
char **machineTypes;
|
||||
char **machineAliases;
|
||||
unsigned int *machineMaxCpus;
|
||||
|
||||
size_t ngicCapabilities;
|
||||
virGICCapability *gicCapabilities;
|
||||
};
|
||||
|
||||
struct virQEMUCapsSearchData {
|
||||
|
@ -2082,6 +2085,8 @@ void virQEMUCapsDispose(void *obj)
|
|||
|
||||
VIR_FREE(qemuCaps->package);
|
||||
VIR_FREE(qemuCaps->binary);
|
||||
|
||||
VIR_FREE(qemuCaps->gicCapabilities);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2696,6 +2701,34 @@ virQEMUCapsProbeQMPMigrationCapabilities(virQEMUCapsPtr qemuCaps,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* virQEMUCapsProbeQMPGICCapabilities:
|
||||
* @qemuCaps: QEMU binary capabilities
|
||||
* @mon: QEMU monitor
|
||||
*
|
||||
* Use @mon to obtain information about the GIC capabilities for the
|
||||
* corresponding QEMU binary, and store them in @qemuCaps.
|
||||
*
|
||||
* Returns: 0 on success, <0 on failure
|
||||
*/
|
||||
static int
|
||||
virQEMUCapsProbeQMPGICCapabilities(virQEMUCapsPtr qemuCaps,
|
||||
qemuMonitorPtr mon)
|
||||
{
|
||||
virGICCapability *caps = NULL;
|
||||
int ncaps;
|
||||
|
||||
if ((ncaps = qemuMonitorGetGICCapabilities(mon, &caps)) < 0)
|
||||
return -1;
|
||||
|
||||
VIR_FREE(qemuCaps->gicCapabilities);
|
||||
|
||||
qemuCaps->gicCapabilities = caps;
|
||||
qemuCaps->ngicCapabilities = ncaps;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
|
||||
qemuMonitorPtr mon)
|
||||
{
|
||||
|
@ -3047,6 +3080,9 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
|
|||
VIR_FREE(qemuCaps->machineAliases);
|
||||
VIR_FREE(qemuCaps->machineMaxCpus);
|
||||
qemuCaps->nmachineTypes = 0;
|
||||
|
||||
VIR_FREE(qemuCaps->gicCapabilities);
|
||||
qemuCaps->ngicCapabilities = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3411,6 +3447,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
|
|||
if (virQEMUCapsProbeQMPMigrationCapabilities(qemuCaps, mon) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* GIC capabilities, eg. available GIC versions */
|
||||
if ((qemuCaps->arch == VIR_ARCH_AARCH64 ||
|
||||
qemuCaps->arch == VIR_ARCH_ARMV7L) &&
|
||||
virQEMUCapsProbeQMPGICCapabilities(qemuCaps, mon) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
return ret;
|
||||
|
|
|
@ -3582,6 +3582,23 @@ qemuMonitorSetMigrationCapability(qemuMonitorPtr mon,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuMonitorGetGICCapabilities:
|
||||
* @mon: QEMU monitor
|
||||
* @capabilities: where to store the GIC capabilities
|
||||
*
|
||||
* See qemuMonitorJSONGetGICCapabilities().
|
||||
*/
|
||||
int
|
||||
qemuMonitorGetGICCapabilities(qemuMonitorPtr mon,
|
||||
virGICCapability **capabilities)
|
||||
{
|
||||
QEMU_CHECK_MONITOR_JSON(mon);
|
||||
|
||||
return qemuMonitorJSONGetGICCapabilities(mon, capabilities);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuMonitorNBDServerStart(qemuMonitorPtr mon,
|
||||
const char *host,
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
# include "virnetdev.h"
|
||||
# include "device_conf.h"
|
||||
# include "cpu/cpu.h"
|
||||
# include "util/virgic.h"
|
||||
|
||||
typedef struct _qemuMonitor qemuMonitor;
|
||||
typedef qemuMonitor *qemuMonitorPtr;
|
||||
|
@ -583,6 +584,9 @@ int qemuMonitorSetMigrationCapability(qemuMonitorPtr mon,
|
|||
qemuMonitorMigrationCaps capability,
|
||||
bool state);
|
||||
|
||||
int qemuMonitorGetGICCapabilities(qemuMonitorPtr mon,
|
||||
virGICCapability **capabilities);
|
||||
|
||||
typedef enum {
|
||||
QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0,
|
||||
QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 1 << 1, /* migration with non-shared storage with full disk copy */
|
||||
|
|
|
@ -5855,6 +5855,121 @@ qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuMonitorJSONGetGICCapabilities:
|
||||
* @mon: QEMU JSON monitor
|
||||
* @capabilities: where to store the GIC capabilities
|
||||
*
|
||||
* Use @mon to obtain information about the GIC capabilities for the
|
||||
* corresponding QEMU binary, and store them in @capabilities.
|
||||
*
|
||||
* If the QEMU binary has no GIC capabilities, or if GIC capabilities could
|
||||
* not be determined due to the lack of 'query-gic-capabilities' QMP command,
|
||||
* a NULL pointer will be returned instead of an empty array.
|
||||
*
|
||||
* Returns: the number of GIC capabilities obtained from the monitor,
|
||||
* <0 on failure
|
||||
*/
|
||||
int
|
||||
qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon,
|
||||
virGICCapability **capabilities)
|
||||
{
|
||||
int ret;
|
||||
virJSONValuePtr cmd;
|
||||
virJSONValuePtr reply = NULL;
|
||||
virJSONValuePtr caps;
|
||||
virGICCapability *list = NULL;
|
||||
size_t i;
|
||||
ssize_t n;
|
||||
|
||||
*capabilities = NULL;
|
||||
|
||||
if (!(cmd = qemuMonitorJSONMakeCommand("query-gic-capabilities",
|
||||
NULL)))
|
||||
return -1;
|
||||
|
||||
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
|
||||
|
||||
if (ret == 0) {
|
||||
/* If the 'query-gic-capabilities' QMP command was not available
|
||||
* we simply successfully return zero capabilities.
|
||||
* This is the case for QEMU <2.6 and all non-ARM architectures */
|
||||
if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
|
||||
goto cleanup;
|
||||
ret = qemuMonitorJSONCheckError(cmd, reply);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = -1;
|
||||
|
||||
if (!(caps = virJSONValueObjectGetArray(reply, "return")) ||
|
||||
(n = virJSONValueArraySize(caps)) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing GIC capabilities"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* If the returned array was empty we have to return successfully */
|
||||
if (n == 0) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC_N(list, n) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
virJSONValuePtr cap = virJSONValueArrayGet(caps, i);
|
||||
int version;
|
||||
bool kernel;
|
||||
bool emulated;
|
||||
|
||||
if (!cap || cap->type != VIR_JSON_TYPE_OBJECT) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing entry in GIC capabilities list"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetNumberInt(cap, "version", &version) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing GIC version"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetBoolean(cap, "kernel", &kernel) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing in-kernel GIC information"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virJSONValueObjectGetBoolean(cap, "emulated", &emulated) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing emulated GIC information"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
list[i].version = version;
|
||||
if (kernel)
|
||||
list[i].implementation |= VIR_GIC_IMPLEMENTATION_KERNEL;
|
||||
if (emulated)
|
||||
list[i].implementation |= VIR_GIC_IMPLEMENTATION_EMULATED;
|
||||
}
|
||||
|
||||
ret = n;
|
||||
*capabilities = list;
|
||||
|
||||
cleanup:
|
||||
if (ret < 0)
|
||||
VIR_FREE(list);
|
||||
virJSONValueFree(cmd);
|
||||
virJSONValueFree(reply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static virJSONValuePtr
|
||||
qemuMonitorJSONBuildInetSocketAddress(const char *host,
|
||||
const char *port)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
# include "qemu_monitor.h"
|
||||
# include "virbitmap.h"
|
||||
# include "cpu/cpu.h"
|
||||
# include "util/virgic.h"
|
||||
|
||||
int qemuMonitorJSONIOProcess(qemuMonitorPtr mon,
|
||||
const char *data,
|
||||
|
@ -142,6 +143,9 @@ int qemuMonitorJSONSetMigrationCapability(qemuMonitorPtr mon,
|
|||
qemuMonitorMigrationCaps capability,
|
||||
bool state);
|
||||
|
||||
int qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon,
|
||||
virGICCapability **capabilities);
|
||||
|
||||
int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
|
||||
unsigned int flags,
|
||||
const char *uri);
|
||||
|
|
|
@ -38,4 +38,17 @@ VIR_ENUM_DECL(virGICVersion);
|
|||
/* Consider GIC v2 the default */
|
||||
# define VIR_GIC_VERSION_DEFAULT VIR_GIC_VERSION_2
|
||||
|
||||
typedef enum {
|
||||
VIR_GIC_IMPLEMENTATION_NONE = 0,
|
||||
VIR_GIC_IMPLEMENTATION_KERNEL = (1 << 1),
|
||||
VIR_GIC_IMPLEMENTATION_EMULATED = (1 << 2)
|
||||
} virGICImplementation;
|
||||
|
||||
typedef struct _virGICCapability virGICCapability;
|
||||
typedef virGICCapability *virGICCapabilityPtr;
|
||||
struct _virGICCapability {
|
||||
virGICVersion version;
|
||||
virGICImplementation implementation;
|
||||
};
|
||||
|
||||
#endif /* __VIR_GIC_H__ */
|
||||
|
|
Loading…
Reference in New Issue