This patch introduces a new libvirt API (virDomainPinVcpuFlags) Signed-off-by: Taku Izumi <izumi.taku@xxxxxxxxxxxxxx> --- include/libvirt/libvirt.h.in | 6 +++ src/driver.h | 7 +++ src/libvirt.c | 83 +++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 4 ++ src/lxc/lxc_driver.c | 1 src/openvz/openvz_driver.c | 1 src/phyp/phyp_driver.c | 1 src/qemu/qemu_driver.c | 1 src/remote/remote_driver.c | 1 src/test/test_driver.c | 1 src/uml/uml_driver.c | 1 src/vbox/vbox_tmpl.c | 1 src/vmware/vmware_driver.c | 1 src/xen/xen_driver.c | 1 src/xenapi/xenapi_driver.c | 1 15 files changed, 111 insertions(+) Index: libvirt/include/libvirt/libvirt.h.in =================================================================== --- libvirt.orig/include/libvirt/libvirt.h.in +++ libvirt/include/libvirt/libvirt.h.in @@ -1017,6 +1017,7 @@ typedef virVcpuInfo *virVcpuInfoPtr; /* Flags for controlling virtual CPU hot-plugging. */ typedef enum { + VIR_DOMAIN_VCPU_CURRENT = 0, /* Affect current domain state */ /* Must choose at least one of these two bits; SetVcpus can choose both */ VIR_DOMAIN_VCPU_LIVE = (1 << 0), /* Affect active domain */ VIR_DOMAIN_VCPU_CONFIG = (1 << 1), /* Affect next boot */ @@ -1037,6 +1038,11 @@ int virDomainPinVcpu unsigned int vcpu, unsigned char *cpumap, int maplen); +int virDomainPinVcpuFlags (virDomainPtr domain, + unsigned int vcpu, + unsigned char *cpumap, + int maplen, + unsigned int flags); /** * VIR_USE_CPU: Index: libvirt/src/driver.h =================================================================== --- libvirt.orig/src/driver.h +++ libvirt/src/driver.h @@ -220,6 +220,12 @@ typedef int unsigned char *cpumap, int maplen); typedef int + (*virDrvDomainPinVcpuFlags) (virDomainPtr domain, + unsigned int vcpu, + unsigned char *cpumap, + int maplen, + unsigned int flags); +typedef int (*virDrvDomainGetVcpus) (virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, @@ -570,6 +576,7 @@ struct _virDriver { virDrvDomainSetVcpusFlags domainSetVcpusFlags; virDrvDomainGetVcpusFlags domainGetVcpusFlags; virDrvDomainPinVcpu domainPinVcpu; + virDrvDomainPinVcpuFlags domainPinVcpuFlags; virDrvDomainGetVcpus domainGetVcpus; virDrvDomainGetMaxVcpus domainGetMaxVcpus; virDrvDomainGetSecurityLabel domainGetSecurityLabel; Index: libvirt/src/libvirt.c =================================================================== --- libvirt.orig/src/libvirt.c +++ libvirt/src/libvirt.c @@ -5461,6 +5461,89 @@ error: } /** + * virDomainPinVcpuFlags: + * @domain: pointer to domain object, or NULL for Domain0 + * @vcpu: virtual CPU number + * @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: an OR'ed subset of virDomainVcpuFlags + * + * Dynamically change the real CPUs which can be allocated to a virtual CPU. + * This function requires privileged access to the hypervisor. + * + * @flags may include VIR_DOMAIN_VCPU_LIVE or VIR_DOMAIN_VCPU_CONFIG. + * Both flags may be set, but VIR_DOMAIN_VCPU_MAXIMUM cannot be set. + * If VIR_DOMAIN_VCPU_LIVE is set, the change affects a running domain + * and may fail if domain is not alive. + * If VIR_DOMAIN_VCPU_CONFIG is set, the change affects persistent state, + * and will fail for transient domains. + * If neither flag is specified (tha is, @flags is VIR_DOMAIN_VCPU_CURRENT), + * then an inactive domain modifies persistent setup, while an active domain + * is hypervisor-dependent on whether just live or both live and persistent + * state is changed. + * Not all hypervisors can support all flag combinations. + * + * Returns 0 in case of success, -1 in case of failure. + * + */ +int +virDomainPinVcpuFlags(virDomainPtr domain, unsigned int vcpu, + unsigned char *cpumap, int maplen, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "vcpu=%u, cpumap=%p, maplen=%d flags=%u", + vcpu, cpumap, maplen, flags); + + virResetLastError(); + + if (flags & ~(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if ((vcpu > 32000) || (cpumap == NULL) || (maplen < 1)) { + virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + conn = domain->conn; + + if (conn->driver->domainPinVcpuFlags) { + int ret; + ret = conn->driver->domainPinVcpuFlags (domain, vcpu, cpumap, 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) Index: libvirt/src/libvirt_public.syms =================================================================== --- libvirt.orig/src/libvirt_public.syms +++ libvirt/src/libvirt_public.syms @@ -436,4 +436,8 @@ LIBVIRT_0.9.0 { virStorageVolUpload; } LIBVIRT_0.8.8; +LIBVIRT_0.9.1 { + virDomainPinVcpuFlags; +} LIBVIRT_0.9.0; + # .... define new API here using predicted next version number .... Index: libvirt/src/lxc/lxc_driver.c =================================================================== --- libvirt.orig/src/lxc/lxc_driver.c +++ libvirt/src/lxc/lxc_driver.c @@ -2837,6 +2837,7 @@ static virDriver lxcDriver = { NULL, /* domainSetVcpusFlags */ NULL, /* domainGetVcpusFlags */ NULL, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ NULL, /* domainGetVcpus */ NULL, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/openvz/openvz_driver.c =================================================================== --- libvirt.orig/src/openvz/openvz_driver.c +++ libvirt/src/openvz/openvz_driver.c @@ -1598,6 +1598,7 @@ static virDriver openvzDriver = { openvzDomainSetVcpusFlags, /* domainSetVcpusFlags */ openvzDomainGetVcpusFlags, /* domainGetVcpusFlags */ NULL, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ NULL, /* domainGetVcpus */ openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/phyp/phyp_driver.c =================================================================== --- libvirt.orig/src/phyp/phyp_driver.c +++ libvirt/src/phyp/phyp_driver.c @@ -4003,6 +4003,7 @@ static virDriver phypDriver = { phypDomainSetVcpusFlags, /* domainSetVcpusFlags */ phypDomainGetVcpusFlags, /* domainGetVcpusFlags */ NULL, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ NULL, /* domainGetVcpus */ phypGetLparCPUMAX, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/qemu/qemu_driver.c =================================================================== --- libvirt.orig/src/qemu/qemu_driver.c +++ libvirt/src/qemu/qemu_driver.c @@ -6864,6 +6864,7 @@ static virDriver qemuDriver = { qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */ qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */ qemudDomainPinVcpu, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ qemudDomainGetVcpus, /* domainGetVcpus */ qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */ qemudDomainGetSecurityLabel, /* domainGetSecurityLabel */ Index: libvirt/src/remote/remote_driver.c =================================================================== --- libvirt.orig/src/remote/remote_driver.c +++ libvirt/src/remote/remote_driver.c @@ -11231,6 +11231,7 @@ static virDriver remote_driver = { remoteDomainSetVcpusFlags, /* domainSetVcpusFlags */ remoteDomainGetVcpusFlags, /* domainGetVcpusFlags */ remoteDomainPinVcpu, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ remoteDomainGetVcpus, /* domainGetVcpus */ remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */ remoteDomainGetSecurityLabel, /* domainGetSecurityLabel */ Index: libvirt/src/test/test_driver.c =================================================================== --- libvirt.orig/src/test/test_driver.c +++ libvirt/src/test/test_driver.c @@ -5378,6 +5378,7 @@ static virDriver testDriver = { testDomainSetVcpusFlags, /* domainSetVcpusFlags */ testDomainGetVcpusFlags, /* domainGetVcpusFlags */ testDomainPinVcpu, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ testDomainGetVcpus, /* domainGetVcpus */ testDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/uml/uml_driver.c =================================================================== --- libvirt.orig/src/uml/uml_driver.c +++ libvirt/src/uml/uml_driver.c @@ -2184,6 +2184,7 @@ static virDriver umlDriver = { NULL, /* domainSetVcpusFlags */ NULL, /* domainGetVcpusFlags */ NULL, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ NULL, /* domainGetVcpus */ NULL, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/vbox/vbox_tmpl.c =================================================================== --- libvirt.orig/src/vbox/vbox_tmpl.c +++ libvirt/src/vbox/vbox_tmpl.c @@ -8568,6 +8568,7 @@ virDriver NAME(Driver) = { vboxDomainSetVcpusFlags, /* domainSetVcpusFlags */ vboxDomainGetVcpusFlags, /* domainGetVcpusFlags */ NULL, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ NULL, /* domainGetVcpus */ vboxDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/vmware/vmware_driver.c =================================================================== --- libvirt.orig/src/vmware/vmware_driver.c +++ libvirt/src/vmware/vmware_driver.c @@ -938,6 +938,7 @@ static virDriver vmwareDriver = { NULL, /* domainSetVcpusFlags */ NULL, /* domainGetVcpusFlags */ NULL, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ NULL, /* domainGetVcpus */ NULL, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/xen/xen_driver.c =================================================================== --- libvirt.orig/src/xen/xen_driver.c +++ libvirt/src/xen/xen_driver.c @@ -2072,6 +2072,7 @@ static virDriver xenUnifiedDriver = { xenUnifiedDomainSetVcpusFlags, /* domainSetVcpusFlags */ xenUnifiedDomainGetVcpusFlags, /* domainGetVcpusFlags */ xenUnifiedDomainPinVcpu, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ xenUnifiedDomainGetVcpus, /* domainGetVcpus */ xenUnifiedDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ Index: libvirt/src/xenapi/xenapi_driver.c =================================================================== --- libvirt.orig/src/xenapi/xenapi_driver.c +++ libvirt/src/xenapi/xenapi_driver.c @@ -1820,6 +1820,7 @@ static virDriver xenapiDriver = { xenapiDomainSetVcpusFlags, /* domainSetVcpusFlags */ xenapiDomainGetVcpusFlags, /* domainGetVcpusFlags */ xenapiDomainPinVcpu, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ xenapiDomainGetVcpus, /* domainGetVcpus */ xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list