From 8f657259bb9c8310b1f232249174f06f30089755 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 21 Jun 2016 10:44:51 +0200 Subject: [PATCH] lib: Add API for specific vCPU hot(un)plug 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 e303140a23..c0f715d66a 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 51af73200b..b81420aefe 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 5b3e842058..619a9fccb2 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 62885ac415..04ef58021b 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 a3f7d9b0ba..0c8bfeed16 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 cd0a14cc69..abe63af070 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 0360600cfb..e1e53d21b2 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, };