From e261987c5a84f22dfd57554bd5ce5c4033c822d6 Mon Sep 17 00:00:00 2001 From: Taku Izumi Date: Fri, 24 Jun 2011 17:56:21 +0900 Subject: [PATCH] vcpupin: introduce the new libvirt API (virDomainGetVcpupinInfo) This patch introduces a new libvirt API (virDomainGetVcpupinInfo), as a counterpart to virDomainPinVcpuFlags. We can use virDomainGetVcpus API to retrieve CPU affinity information, but can't use this API against inactive domains (at least in case of KVM), as it lacks a flags parameter. The usual thing is to add a new virDomainGetVcpusFlags, but that API name is already occupied by the counterpart to virDomainGetMaxVcpus, which has a completely different signature. The virDomainGetVcpupinInfo is the new API to retrieve CPU affinity information of active and inactive domains. While the usual convention is to list an array before its length, this API violates that rule in order to be more like virDomainGetVcpus (where maxinfo was doing double-duty as the length of two different arrays). Signed-off-by: Taku Izumi --- include/libvirt/libvirt.h.in | 6 +++ src/driver.h | 8 ++++ src/libvirt.c | 73 +++++++++++++++++++++++++++++++++++- src/libvirt_public.syms | 1 + 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 229c3cd1e6..4f9f158e1e 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1266,6 +1266,12 @@ int virDomainPinVcpuFlags (virDomainPtr domain, int maplen, unsigned int flags); +int virDomainGetVcpupinInfo (virDomainPtr domain, + int ncpumaps, + unsigned char *cpumaps, + int maplen, + unsigned int flags); + /** * VIR_USE_CPU: * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN/OUT) diff --git a/src/driver.h b/src/driver.h index b02989bd60..c15d0dd33e 100644 --- a/src/driver.h +++ b/src/driver.h @@ -239,6 +239,13 @@ typedef int unsigned char *cpumap, int maplen, unsigned int flags); +typedef int + (*virDrvDomainGetVcpupinInfo) (virDomainPtr domain, + int ncpumaps, + unsigned char *cpumaps, + int maplen, + unsigned int flags); + typedef int (*virDrvDomainGetVcpus) (virDomainPtr domain, virVcpuInfoPtr info, @@ -706,6 +713,7 @@ struct _virDriver { virDrvDomainGetVcpusFlags domainGetVcpusFlags; virDrvDomainPinVcpu domainPinVcpu; virDrvDomainPinVcpuFlags domainPinVcpuFlags; + virDrvDomainGetVcpupinInfo domainGetVcpupinInfo; virDrvDomainGetVcpus domainGetVcpus; virDrvDomainGetMaxVcpus domainGetMaxVcpus; virDrvDomainGetSecurityLabel domainGetSecurityLabel; diff --git a/src/libvirt.c b/src/libvirt.c index 9fe9a6924e..46a448b260 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -7061,6 +7061,8 @@ error: * just live or both live and persistent state is changed. * Not all hypervisors can support all flag combinations. * + * See also virDomainGetVcpupinInfo for querying this information. + * * Returns 0 in case of success, -1 in case of failure. * */ @@ -7109,6 +7111,71 @@ error: } +/** + * virDomainGetVcpupinInfo: + * @domain: pointer to domain object, or NULL for Domain0 + * @ncpumaps: the number of cpumap (listed first to match virDomainGetVcpus) + * @cpumaps: pointer to a bit map of real CPUs for all vcpus of this + * domain (in 8-bit bytes) (OUT) + * It's assumed there is cpumap in cpumaps array. + * The memory allocated to cpumaps must be (ncpumaps * maplen) bytes + * (ie: calloc(ncpumaps, maplen)). + * One cpumap inside cpumaps has the format described in + * virDomainPinVcpu() API. + * Must not be NULL. + * @maplen: the number of bytes in one cpumap, from 1 up to size of CPU map. + * Must be positive. + * @flags: an OR'ed set of virDomainModificationImpact + * Must not be VIR_DOMAIN_AFFECT_LIVE and + * VIR_DOMAIN_AFFECT_CONFIG concurrently. + * + * Query the CPU affinity setting of all virtual CPUs of domain, store it + * in cpumaps. + * + * Returns the number of virtual CPUs in case of success, + * -1 in case of failure. + */ +int +virDomainGetVcpupinInfo (virDomainPtr domain, int ncpumaps, + unsigned char *cpumaps, int maplen, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "ncpumaps=%d, cpumaps=%p, maplen=%d, flags=%u", + ncpumaps, cpumaps, maplen, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (ncpumaps < 1 || !cpumaps || maplen <= 0 || + INT_MULTIPLY_OVERFLOW(ncpumaps, maplen)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + conn = domain->conn; + + if (conn->driver->domainGetVcpupinInfo) { + int ret; + ret = conn->driver->domainGetVcpupinInfo (domain, ncpumaps, + cpumaps, maplen, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + /** * virDomainGetVcpus: * @domain: pointer to domain object, or NULL for Domain0 @@ -7127,7 +7194,11 @@ error: * Must be zero when cpumaps is NULL and positive when it is non-NULL. * * Extract information about virtual CPUs of domain, store it in info array - * and also in cpumaps if this pointer isn't NULL. + * and also in cpumaps if this pointer isn't NULL. This call may fail + * on an inactive domain. + * + * See also virDomainGetVcpupinInfo for querying just cpumaps, including on + * an inactive domain. * * Returns the number of info filled in case of success, -1 in case of failure. */ diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 7687223309..c7dc3c533b 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -453,6 +453,7 @@ LIBVIRT_0.9.2 { LIBVIRT_0.9.3 { global: virDomainGetControlInfo; + virDomainGetVcpupinInfo; virDomainPinVcpuFlags; virDomainSendKey; virEventAddHandle; -- 2.47.2