This patch introduces a new libvirt API (virDomainGetVcpupinInfo).
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).
There is the companion API of this, whose name is virDomainGetVcpusFlags.
However its signature is different from what everyone expect, so we can't use
this to retrieve it either.
The virDomainGetVcpupinInfo is the new API to retrieve CPU affinity information
of active and inactive domains.
Signed-off-by: Taku Izumi <izumi.taku(a)jp.fujitsu.com>
---
include/libvirt/libvirt.h.in | 6 +++
src/driver.h | 8 ++++
src/libvirt.c | 69 +++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1
4 files changed, 84 insertions(+)
Index: libvirt/include/libvirt/libvirt.h.in
===================================================================
--- libvirt.orig/include/libvirt/libvirt.h.in
+++ libvirt/include/libvirt/libvirt.h.in
@@ -1265,6 +1265,12 @@ int virDomainPinVcpu
int maplen,
unsigned int flags);
+int virDomainGetVcpupinInfo (virDomainPtr domain,
+ int maxinfo,
+ 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)
Index: libvirt/src/driver.h
===================================================================
--- libvirt.orig/src/driver.h
+++ libvirt/src/driver.h
@@ -240,6 +240,13 @@ typedef int
int maplen,
unsigned int flags);
typedef int
+ (*virDrvDomainGetVcpupinInfo) (virDomainPtr domain,
+ int maxinfo,
+ unsigned char *cpumaps,
+ int maplen,
+ unsigned int flags);
+
+typedef int
(*virDrvDomainGetVcpus) (virDomainPtr domain,
virVcpuInfoPtr info,
int maxinfo,
@@ -724,6 +731,7 @@ struct _virDriver {
virDrvDomainGetVcpusFlags domainGetVcpusFlags;
virDrvDomainPinVcpu domainPinVcpu;
virDrvDomainPinVcpuFlags domainPinVcpuFlags;
+ virDrvDomainGetVcpupinInfo domainGetVcpupinInfo;
virDrvDomainGetVcpus domainGetVcpus;
virDrvDomainGetMaxVcpus domainGetMaxVcpus;
virDrvDomainGetSecurityLabel domainGetSecurityLabel;
Index: libvirt/src/libvirt_public.syms
===================================================================
--- libvirt.orig/src/libvirt_public.syms
+++ libvirt/src/libvirt_public.syms
@@ -467,6 +467,7 @@ LIBVIRT_0.9.3 {
virEventUpdateTimeout;
virNodeGetCPUStats;
virNodeGetMemoryStats;
+ virDomainGetVcpupinInfo;
} LIBVIRT_0.9.2;
# .... define new API here using predicted next version number ....
Index: libvirt/src/libvirt.c
===================================================================
--- libvirt.orig/src/libvirt.c
+++ libvirt/src/libvirt.c
@@ -7087,6 +7087,75 @@ error:
}
/**
+ * virDomainGetVcpupinInfo:
+ * @domain: pointer to domain object, or NULL for Domain0
+ * @maxinfo: the number of cpumap
+ * @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 <maxinfo> cpumap in cpumaps array.
+ * The memory allocated to cpumaps must be (maxinfo * maplen) bytes
+ * (ie: calloc(maxinfo, 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 specified 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 maxinfo,
+ unsigned char *cpumaps, int maplen, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "maxinfo=%d, cpumaps=%p, maplen=%d, flags=%u",
+ maxinfo, cpumaps, maplen, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (maxinfo < 1) {
+ virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if ((cpumaps == NULL) || (cpumaps && maplen <= 0)) {
+ virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetVcpupinInfo) {
+ int ret;
+ ret = conn->driver->domainGetVcpupinInfo (domain, maxinfo,
+ 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
* @info: pointer to an array of virVcpuInfo structures (OUT)