Similarly to domainSetGuestVcpus this commit adds API which allows to
modify state of individual vcpus rather than just setting the count.
This allows to enable CPUs in specific guest NUMA nodes to achieve any
necessary configuration.
---
include/libvirt/libvirt-domain.h | 5 +++++
src/driver-hypervisor.h | 7 ++++++
src/libvirt-domain.c | 48 ++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 +++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 16 +++++++++++++-
src/remote_protocol-structs | 7 ++++++
7 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index e303140a2..c0f715d66 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4528,4 +4528,9 @@ int virDomainSetGuestVcpus(virDomainPtr domain,
int state,
unsigned int flags);
+int virDomainSetVcpu(virDomainPtr domain,
+ const char *vcpumap,
+ int state,
+ unsigned int flags);
+
#endif /* __VIR_LIBVIRT_DOMAIN_H__ */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 51af73200..b81420aef 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1251,6 +1251,12 @@ typedef int
int state,
unsigned int flags);
+typedef int
+(*virDrvDomainSetVcpu)(virDomainPtr domain,
+ const char *cpumap,
+ int state,
+ unsigned int flags);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
typedef virHypervisorDriver *virHypervisorDriverPtr;
@@ -1489,6 +1495,7 @@ struct _virHypervisorDriver {
virDrvDomainMigrateStartPostCopy domainMigrateStartPostCopy;
virDrvDomainGetGuestVcpus domainGetGuestVcpus;
virDrvDomainSetGuestVcpus domainSetGuestVcpus;
+ virDrvDomainSetVcpu domainSetVcpu;
};
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 5b3e84205..619a9fccb 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11749,3 +11749,51 @@ virDomainSetGuestVcpus(virDomainPtr domain,
virDispatchError(domain->conn);
return -1;
}
+
+
+/**
+ * virDomainSetVcpu:
+ * @domain: pointer to domain object
+ * @vcpumap: text representation of a bitmap of vcpus to set
+ * @state: 0 to disable/1 to enable cpus described by @vcpumap
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Enables/disables individual vcpus described by @vcpumap in the hypervisor.
+ *
+ * Various hypervisor implementations may limit to operate on just 1
+ * hotpluggable entity (which may contain multiple vCPUs on certain platforms).
+ *
+ * Note that OSes and hypervisors may require vCPU 0 to stay online.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+virDomainSetVcpu(virDomainPtr domain,
+ const char *vcpumap,
+ int state,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(domain, "vcpumap='%s' state=%i flags=%x",
+ NULLSTR(vcpumap), state, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckReadOnlyGoto(domain->conn->flags, error);
+
+ virCheckNonNullArgGoto(vcpumap, error);
+
+ if (domain->conn->driver->domainSetVcpu) {
+ int ret;
+ ret = domain->conn->driver->domainSetVcpu(domain, vcpumap, state,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 62885ac41..04ef58021 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -753,4 +753,9 @@ LIBVIRT_3.0.0 {
virConnectSecretEventDeregisterAny;
} LIBVIRT_2.2.0;
+LIBVIRT_3.1.0 {
+ global:
+ virDomainSetVcpu;
+} LIBVIRT_3.0.0;
+
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index a3f7d9b0b..0c8bfeed1 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8402,6 +8402,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainMigrateStartPostCopy = remoteDomainMigrateStartPostCopy, /* 1.3.3 */
.domainGetGuestVcpus = remoteDomainGetGuestVcpus, /* 2.0.0 */
.domainSetGuestVcpus = remoteDomainSetGuestVcpus, /* 2.0.0 */
+ .domainSetVcpu = remoteDomainSetVcpu, /* 3.1.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 68469a5b1..b2a67c801 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3353,6 +3353,13 @@ struct remote_domain_set_guest_vcpus_args {
unsigned int flags;
};
+struct remote_domain_set_vcpu_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string cpumap;
+ int state;
+ unsigned int flags;
+};
+
struct remote_domain_event_callback_metadata_change_msg {
int callbackID;
@@ -6018,6 +6025,13 @@ enum remote_procedure {
* @generate: both
* @acl: none
*/
- REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED = 383
+ REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED = 383,
+ /**
+ * @generate: both
+ * @acl: domain:write
+ * @acl: domain:save:!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE
+ * @acl: domain:save:VIR_DOMAIN_AFFECT_CONFIG
+ */
+ REMOTE_PROC_DOMAIN_SET_VCPU = 384
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 0360600cf..e1e53d21b 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2800,6 +2800,12 @@ struct remote_domain_set_guest_vcpus_args {
int state;
u_int flags;
};
+struct remote_domain_set_vcpu_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string cpumap;
+ int state;
+ u_int flags;
+};
struct remote_domain_event_callback_metadata_change_msg {
int callbackID;
remote_nonnull_domain dom;
@@ -3210,4 +3216,5 @@ enum remote_procedure {
REMOTE_PROC_CONNECT_SECRET_EVENT_DEREGISTER_ANY = 381,
REMOTE_PROC_SECRET_EVENT_LIFECYCLE = 382,
REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED = 383,
+ REMOTE_PROC_DOMAIN_SET_VCPU = 384,
};
--
2.11.0