https://bugzilla.redhat.com/show_bug.cgi?id=1135491
Add the libvirt API infrastructure to support setting IOThread data.
For now this is the pinned CPU information, but eventually will also
support hot plug add/del
The API will support the LIVE, CONFIG, or CURRENT flags. If the
VIR_DOMAIN_IOTHREADS_PIN flag is not provided, it's left up to the
hypervisor to handle, but when not provided the cpumap/maplen arguments
are not checked.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
include/libvirt/libvirt-domain.h | 16 ++++++++++
src/driver-hypervisor.h | 8 +++++
src/libvirt-domain.c | 69 ++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
4 files changed, 94 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 9dcc424..e07db16 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1582,11 +1582,27 @@ struct _virDomainIOThreadsInfo {
char **resources; /* array of resources using IOThread */
};
+/* Flags for controlling virtual IOThread pinning. */
+typedef enum {
+ /* See virDomainModificationImpact for these flags. */
+ VIR_DOMAIN_IOTHREADS_CURRENT = VIR_DOMAIN_AFFECT_CURRENT,
+ VIR_DOMAIN_IOTHREADS_LIVE = VIR_DOMAIN_AFFECT_LIVE,
+ VIR_DOMAIN_IOTHREADS_CONFIG = VIR_DOMAIN_AFFECT_CONFIG,
+
+ /* Additionally, these flags may be bitwise-OR'd in. */
+ VIR_DOMAIN_IOTHREADS_PIN = (1 << 2), /* thread_id to pin using cpumap */
+} virDomainIOThreadsFlags;
+
void virDomainIOThreadsInfoFree(virDomainIOThreadsInfoPtr info);
int virDomainGetIOThreadsInfo(virDomainPtr domain,
virDomainIOThreadsInfoPtr **info,
unsigned int flags);
+int virDomainSetIOThreads(virDomainPtr domain,
+ unsigned int iothread_val,
+ unsigned char *cpumap,
+ int maplen,
+ unsigned int flags);
/**
* VIR_USE_CPU:
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 2ce1a51..120d761 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -386,6 +386,13 @@ typedef int
unsigned int flags);
typedef int
+(*virDrvDomainSetIOThreads)(virDomainPtr domain,
+ unsigned int iothread_val,
+ unsigned char *cpumap,
+ int maplen,
+ unsigned int flags);
+
+typedef int
(*virDrvDomainGetSecurityLabel)(virDomainPtr domain,
virSecurityLabelPtr seclabel);
@@ -1260,6 +1267,7 @@ struct _virHypervisorDriver {
virDrvDomainGetVcpus domainGetVcpus;
virDrvDomainGetMaxVcpus domainGetMaxVcpus;
virDrvDomainGetIOThreadsInfo domainGetIOThreadsInfo;
+ virDrvDomainSetIOThreads domainSetIOThreads;
virDrvDomainGetSecurityLabel domainGetSecurityLabel;
virDrvDomainGetSecurityLabelList domainGetSecurityLabelList;
virDrvNodeGetSecurityModel nodeGetSecurityModel;
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index f893b35..bf73773 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -7969,6 +7969,75 @@ virDomainIOThreadsInfoFree(virDomainIOThreadsInfoPtr info)
/**
+ * virDomainSetIOThreads:
+ * @domain: a domain object
+ * @iothread_val: either the thread_id to modify or a count of IOThreads
+ * to be added or removed from the domain depending on the @flags setting
+ * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN)
+ * Each bit set to 1 means that corresponding CPU is usable.
+ * Bytes are stored in little-endian order: CPU0-7, 8-15...
+ * In each byte, lowest CPU number is least significant bit.
+ * @maplen: number of bytes in cpumap, from 1 up to size of CPU map in
+ * underlying virtualization system (Xen...).
+ * If maplen < size, missing bytes are set to zero.
+ * If maplen > size, failure code is returned.
+ * @flags: bitwise-OR of supported virDomainIOThreadsFlags
+ *
+ * If the VIR_DOMAIN_IOTHREADS_PIN flag is set, the @iothread_val will be
+ * an existing IOThread to be pinned
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virDomainSetIOThreads(virDomainPtr domain,
+ unsigned int iothread_val,
+ unsigned char *cpumap,
+ int maplen,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "iothread_val=%u, cpumap=%p, maplen=%d",
+ iothread_val, cpumap, maplen);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+ if ((unsigned short) iothread_val != iothread_val) {
+ virReportError(VIR_ERR_OVERFLOW, _("input too large: %u"),
+ iothread_val);
+ goto error;
+ }
+
+ virCheckPositiveArgGoto(iothread_val, error);
+
+ /* If we're pinning threads, then need to ensure cpumap/maplen are valid */
+ if (flags & VIR_DOMAIN_IOTHREADS_PIN) {
+ virCheckNonNullArgGoto(cpumap, error);
+ virCheckPositiveArgGoto(maplen, error);
+ }
+
+ if (conn->driver->domainSetIOThreads) {
+ int ret;
+ ret = conn->driver->domainSetIOThreads(domain, iothread_val,
+ cpumap, maplen, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+
+/**
* virDomainGetSecurityLabel:
* @domain: a domain object
* @seclabel: pointer to a virSecurityLabel structure
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index d3ddd24..b1a9e83 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -699,6 +699,7 @@ LIBVIRT_1.2.13 {
global:
virDomainIOThreadsInfoFree;
virDomainGetIOThreadsInfo;
+ virDomainSetIOThreads;
} LIBVIRT_1.2.12;
# .... define new API here using predicted next version number ....
--
2.1.0