[libvirt] [PATCH 0/4] RFC: vcpupin: configure inactive domains' CPU affinity setting

Hi all, This patchset enables us to configure inactive domains' CPU affinity setting. The basic technique is the same as that of "virsh setmem" command. => http://www.redhat.com/archives/libvir-list/2011-March/msg00013.html *[PATCH 1/4] vcpupin: inroduce a new libvir API (virDomainPinVcpuFlags) *[PATCH 2/4] vcpupin: implement the code to address the new API in the qemu driver *[PATCH 3/4] vcpupin: implement the remote protocol to address the new API *[PATCH 4/4] vcpupin: add the new options to "virsh vcpupin" command Best regards, Taku Izumi

This patch introduces a new libvirt API (virDomainPinVcpuFlags) Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> --- include/libvirt/libvirt.h.in | 5 +++ src/driver.h | 7 ++++ src/libvirt.c | 70 +++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 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, 94 insertions(+) Index: libvirt/include/libvirt/libvirt.h.in =================================================================== --- libvirt.orig/include/libvirt/libvirt.h.in +++ libvirt/include/libvirt/libvirt.h.in @@ -1036,6 +1036,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 @@ -5495,6 +5495,76 @@ 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 correspoinding 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 set of virDomainVcpuFlags + * + * Dynamically change the real CPUs which can be allocated to a virtual CPU. + * This function requires privileged access to the hypervisor. + * + * @flags must include VIR_DOMAIN_VCPU_LIVE to affect a running domain + * (which may fail if domain is not active), or VIR_DOMAIN_MEM_CONFIG to + * affect the next boot via the XML description of the domain. + * Both flags may be set. + * + * 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 (!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 @@ -434,6 +434,7 @@ LIBVIRT_0.9.0 { virEventRunDefaultImpl; virStorageVolDownload; virStorageVolUpload; + virDomainPinVcpuFlags; } LIBVIRT_0.8.8; # .... 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 @@ -1585,6 +1585,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 @@ -3986,6 +3986,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 @@ -6854,6 +6854,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 @@ -11227,6 +11227,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 @@ -2180,6 +2180,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 @@ -1816,6 +1816,7 @@ static virDriver xenapiDriver = { xenapiDomainSetVcpusFlags, /* domainSetVcpusFlags */ xenapiDomainGetVcpusFlags, /* domainGetVcpusFlags */ xenapiDomainPinVcpu, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ xenapiDomainGetVcpus, /* domainGetVcpus */ xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */

于 2011年03月31日 13:38, Taku Izumi 写道:
This patch introduces a new libvirt API (virDomainPinVcpuFlags)
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> --- include/libvirt/libvirt.h.in | 5 +++ src/driver.h | 7 ++++ src/libvirt.c | 70 +++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 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, 94 insertions(+)
Index: libvirt/include/libvirt/libvirt.h.in =================================================================== --- libvirt.orig/include/libvirt/libvirt.h.in +++ libvirt/include/libvirt/libvirt.h.in @@ -1036,6 +1036,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 @@ -5495,6 +5495,76 @@ 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 correspoinding 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 set of virDomainVcpuFlags + * + * Dynamically change the real CPUs which can be allocated to a virtual CPU. + * This function requires privileged access to the hypervisor. + * + * @flags must include VIR_DOMAIN_VCPU_LIVE to affect a running domain + * (which may fail if domain is not active), or VIR_DOMAIN_MEM_CONFIG to + * affect the next boot via the XML description of the domain. + * Both flags may be set. + * + * 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 (!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 @@ -434,6 +434,7 @@ LIBVIRT_0.9.0 { virEventRunDefaultImpl; virStorageVolDownload; virStorageVolUpload; + virDomainPinVcpuFlags; } LIBVIRT_0.8.8;
# .... 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 @@ -1585,6 +1585,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 @@ -3986,6 +3986,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 @@ -6854,6 +6854,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 @@ -11227,6 +11227,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 @@ -2180,6 +2180,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 @@ -1816,6 +1816,7 @@ static virDriver xenapiDriver = { xenapiDomainSetVcpusFlags, /* domainSetVcpusFlags */ xenapiDomainGetVcpusFlags, /* domainGetVcpusFlags */ xenapiDomainPinVcpu, /* domainPinVcpu */ + NULL, /* domainPinVcpuFlags */ xenapiDomainGetVcpus, /* domainGetVcpus */ xenapiDomainGetMaxVcpus, /* domainGetMaxVcpus */ NULL, /* domainGetSecurityLabel */
Looks good to me. Regards Osier

On 03/30/2011 11:38 PM, Taku Izumi wrote:
This patch introduces a new libvirt API (virDomainPinVcpuFlags)
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
/** + * 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 correspoinding CPU is usable.
s/correspoinding/corresponding/
+ * 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.
s/</>/
+ * @flags: an OR'ed set of virDomainVcpuFlags
Is VIR_DOMAIN_VCPU_MAXIMUM really applicable here? The docs should probably mention that it is a 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 must include VIR_DOMAIN_VCPU_LIVE to affect a running domain + * (which may fail if domain is not active), or VIR_DOMAIN_MEM_CONFIG to
s/VIR_DOMAIN_MEM_CONFIG/VIR_DOMAIN_VCPU_CONFIG/
+ * affect the next boot via the XML description of the domain. + * Both flags may be set. + * + * 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) +{ Index: libvirt/src/libvirt_public.syms =================================================================== --- libvirt.orig/src/libvirt_public.syms +++ libvirt/src/libvirt_public.syms @@ -434,6 +434,7 @@ LIBVIRT_0.9.0 { virEventRunDefaultImpl; virStorageVolDownload; virStorageVolUpload; + virDomainPinVcpuFlags; } LIBVIRT_0.8.8;
We've missed the 0.9.0 feature freeze, can you adjust this patch series to be for 0.9.1? -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

(2011/04/02 1:47), Eric Blake wrote:
On 03/30/2011 11:38 PM, Taku Izumi wrote:
This patch introduces a new libvirt API (virDomainPinVcpuFlags)
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com>
/** + * 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 correspoinding CPU is usable.
s/correspoinding/corresponding/
+ * 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.
s/</>/
+ * @flags: an OR'ed set of virDomainVcpuFlags
Is VIR_DOMAIN_VCPU_MAXIMUM really applicable here? The docs should probably mention that it is a 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 must include VIR_DOMAIN_VCPU_LIVE to affect a running domain + * (which may fail if domain is not active), or VIR_DOMAIN_MEM_CONFIG to
s/VIR_DOMAIN_MEM_CONFIG/VIR_DOMAIN_VCPU_CONFIG/
+ * affect the next boot via the XML description of the domain. + * Both flags may be set. + * + * 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) +{ Index: libvirt/src/libvirt_public.syms =================================================================== --- libvirt.orig/src/libvirt_public.syms +++ libvirt/src/libvirt_public.syms @@ -434,6 +434,7 @@ LIBVIRT_0.9.0 { virEventRunDefaultImpl; virStorageVolDownload; virStorageVolUpload; + virDomainPinVcpuFlags; } LIBVIRT_0.8.8;
We've missed the 0.9.0 feature freeze, can you adjust this patch series to be for 0.9.1?
Thank you for reviewing. I'll rebase this patch set after releasing libvirt 0.9.0. Best regards, Taku Izumi

This patch implements the code to address the new API (virDomainPinVcpuFlags) in the qemu driver. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> --- src/qemu/qemu_driver.c | 89 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 22 deletions(-) Index: libvirt/src/qemu/qemu_driver.c =================================================================== --- libvirt.orig/src/qemu/qemu_driver.c +++ libvirt/src/qemu/qemu_driver.c @@ -2624,17 +2624,29 @@ qemudDomainSetVcpus(virDomainPtr dom, un static int -qemudDomainPinVcpu(virDomainPtr dom, - unsigned int vcpu, - unsigned char *cpumap, - int maplen) { +qemudDomainPinVcpuFlags(virDomainPtr dom, + unsigned int vcpu, + unsigned char *cpumap, + int maplen, + unsigned int flags) { + struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; + virDomainDefPtr persistentDef = NULL; int maxcpu, hostcpus; virNodeInfo nodeinfo; int ret = -1; qemuDomainObjPrivatePtr priv; + virCheckFlags(VIR_DOMAIN_VCPU_LIVE | + VIR_DOMAIN_VCPU_CONFIG, -1); + + if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_MEM_CONFIG)) == 0) { + qemuReportError(VIR_ERR_INVALID_ARG, + _("invalid flag combination: (0x%x)"), flags); + return -1; + } + qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); qemuDriverUnlock(driver); @@ -2647,7 +2659,7 @@ qemudDomainPinVcpu(virDomainPtr dom, goto cleanup; } - if (!virDomainObjIsActive(vm)) { + if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_VCPU_LIVE)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",_("cannot pin vcpus on an inactive domain")); goto cleanup; @@ -2662,27 +2674,52 @@ qemudDomainPinVcpu(virDomainPtr dom, goto cleanup; } - if (nodeGetInfo(dom->conn, &nodeinfo) < 0) - goto cleanup; + if (flags & VIR_DOMAIN_VCPU_CONFIG) { + if (!vm->persistent) { + qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot change persistent config of a transient domain")); + goto cleanup; + } + if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm))) + goto cleanup; + } - hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); - maxcpu = maplen * 8; - if (maxcpu > hostcpus) - maxcpu = hostcpus; + if (flags & VIR_DOMAIN_VCPU_LIVE) { - if (priv->vcpupids != NULL) { - if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], - cpumap, maplen, maxcpu) < 0) + if (nodeGetInfo(dom->conn, &nodeinfo) < 0) goto cleanup; - } else { - qemuReportError(VIR_ERR_NO_SUPPORT, - "%s", _("cpu affinity is not supported")); - goto cleanup; + + hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); + maxcpu = maplen * 8; + if (maxcpu > hostcpus) + maxcpu = hostcpus; + + if (priv->vcpupids != NULL) { + if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], + cpumap, maplen, maxcpu) < 0) + goto cleanup; + } else { + qemuReportError(VIR_ERR_NO_SUPPORT, + "%s", _("cpu affinity is not supported")); + goto cleanup; + } + + if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add vcpupin xml of a running domain")); + goto cleanup; + } + } - if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu) < 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("failed to update or add vcpupin xml")); + if (flags & VIR_DOMAIN_VCPU_CONFIG) { + + if (virDomainVcpupinAdd(persistentDef, cpumap, maplen, vcpu) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add vcpupin xml of a persistent domain")); + goto cleanup; + } + ret = virDomainSaveConfig(driver->configDir, persistentDef); goto cleanup; } @@ -2695,6 +2732,14 @@ cleanup: } static int +qemudDomainPinVcpu(virDomainPtr dom, + unsigned int vcpu, + unsigned char *cpumap, + int maplen) { + return qemudDomainPinVcpuFlags(dom, vcpu, cpumap, maplen, VIR_DOMAIN_VCPU_LIVE); +} + +static int qemudDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, @@ -6854,7 +6899,7 @@ static virDriver qemuDriver = { qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */ qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */ qemudDomainPinVcpu, /* domainPinVcpu */ - NULL, /* domainPinVcpuFlags */ + qemudDomainPinVcpuFlags, /* domainPinVcpuFlags */ qemudDomainGetVcpus, /* domainGetVcpus */ qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */ qemudDomainGetSecurityLabel, /* domainGetSecurityLabel */

于 2011年03月31日 13:38, Taku Izumi 写道:
This patch implements the code to address the new API (virDomainPinVcpuFlags) in the qemu driver.
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> --- src/qemu/qemu_driver.c | 89 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 22 deletions(-)
Index: libvirt/src/qemu/qemu_driver.c =================================================================== --- libvirt.orig/src/qemu/qemu_driver.c +++ libvirt/src/qemu/qemu_driver.c @@ -2624,17 +2624,29 @@ qemudDomainSetVcpus(virDomainPtr dom, un
static int -qemudDomainPinVcpu(virDomainPtr dom, - unsigned int vcpu, - unsigned char *cpumap, - int maplen) { +qemudDomainPinVcpuFlags(virDomainPtr dom, + unsigned int vcpu, + unsigned char *cpumap, + int maplen, + unsigned int flags) { + struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; + virDomainDefPtr persistentDef = NULL; int maxcpu, hostcpus; virNodeInfo nodeinfo; int ret = -1; qemuDomainObjPrivatePtr priv;
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE | + VIR_DOMAIN_VCPU_CONFIG, -1); + + if ((flags& (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_MEM_CONFIG)) == 0) {
s/VIR_DOMAIN_MEM_CONFIG/VIR_DOMAIN_VCPU_CONFIG/ This allows both "LIVE" and "CONFIG" are set, and you use two "if" clauses later for both of them, ( if (flags& VIR_DOMAIN_VCPU_CONFIG), and if (flags& VIR_DOMAIN_VCPU_LIVE) ) so there should be problem. IMHO it should be: Exactly one of "LIVE" or "CONFIG" is set.
+ qemuReportError(VIR_ERR_INVALID_ARG, + _("invalid flag combination: (0x%x)"), flags); + return -1; + } + qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); qemuDriverUnlock(driver); @@ -2647,7 +2659,7 @@ qemudDomainPinVcpu(virDomainPtr dom, goto cleanup; }
- if (!virDomainObjIsActive(vm)) { + if (!virDomainObjIsActive(vm)&& (flags& VIR_DOMAIN_VCPU_LIVE)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",_("cannot pin vcpus on an inactive domain")); goto cleanup; @@ -2662,27 +2674,52 @@ qemudDomainPinVcpu(virDomainPtr dom, goto cleanup; }
- if (nodeGetInfo(dom->conn,&nodeinfo)< 0) - goto cleanup; + if (flags& VIR_DOMAIN_VCPU_CONFIG) { + if (!vm->persistent) { + qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot change persistent config of a transient domain")); + goto cleanup; + } + if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm))) + goto cleanup; + }
- hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); - maxcpu = maplen * 8; - if (maxcpu> hostcpus) - maxcpu = hostcpus; + if (flags& VIR_DOMAIN_VCPU_LIVE) {
- if (priv->vcpupids != NULL) { - if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], - cpumap, maplen, maxcpu)< 0) + if (nodeGetInfo(dom->conn,&nodeinfo)< 0) goto cleanup; - } else { - qemuReportError(VIR_ERR_NO_SUPPORT, - "%s", _("cpu affinity is not supported")); - goto cleanup; + + hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); + maxcpu = maplen * 8; + if (maxcpu> hostcpus) + maxcpu = hostcpus; + + if (priv->vcpupids != NULL) { + if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], + cpumap, maplen, maxcpu)< 0) + goto cleanup; + } else { + qemuReportError(VIR_ERR_NO_SUPPORT, + "%s", _("cpu affinity is not supported")); + goto cleanup; + } + + if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu)< 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add vcpupin xml of a running domain"));
Indention, :-)
+ goto cleanup; + } + }
- if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu)< 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("failed to update or add vcpupin xml")); + if (flags& VIR_DOMAIN_VCPU_CONFIG) { + + if (virDomainVcpupinAdd(persistentDef, cpumap, maplen, vcpu)< 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add vcpupin xml of a persistent domain"));
likewise
+ goto cleanup; + } + ret = virDomainSaveConfig(driver->configDir, persistentDef); goto cleanup; }
@@ -2695,6 +2732,14 @@ cleanup: }
static int +qemudDomainPinVcpu(virDomainPtr dom, + unsigned int vcpu, + unsigned char *cpumap, + int maplen) { + return qemudDomainPinVcpuFlags(dom, vcpu, cpumap, maplen, VIR_DOMAIN_VCPU_LIVE); +} + +static int qemudDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, @@ -6854,7 +6899,7 @@ static virDriver qemuDriver = { qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */ qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */ qemudDomainPinVcpu, /* domainPinVcpu */ - NULL, /* domainPinVcpuFlags */ + qemudDomainPinVcpuFlags, /* domainPinVcpuFlags */ qemudDomainGetVcpus, /* domainGetVcpus */ qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */ qemudDomainGetSecurityLabel, /* domainGetSecurityLabel */
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

于 2011年03月31日 15:33, Osier Yang 写道:
于 2011年03月31日 13:38, Taku Izumi 写道:
This patch implements the code to address the new API (virDomainPinVcpuFlags) in the qemu driver.
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> --- src/qemu/qemu_driver.c | 89 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 22 deletions(-)
Index: libvirt/src/qemu/qemu_driver.c =================================================================== --- libvirt.orig/src/qemu/qemu_driver.c +++ libvirt/src/qemu/qemu_driver.c @@ -2624,17 +2624,29 @@ qemudDomainSetVcpus(virDomainPtr dom, un
static int -qemudDomainPinVcpu(virDomainPtr dom, - unsigned int vcpu, - unsigned char *cpumap, - int maplen) { +qemudDomainPinVcpuFlags(virDomainPtr dom, + unsigned int vcpu, + unsigned char *cpumap, + int maplen, + unsigned int flags) { + struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; + virDomainDefPtr persistentDef = NULL; int maxcpu, hostcpus; virNodeInfo nodeinfo; int ret = -1; qemuDomainObjPrivatePtr priv;
+ virCheckFlags(VIR_DOMAIN_VCPU_LIVE | + VIR_DOMAIN_VCPU_CONFIG, -1); + + if ((flags& (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_MEM_CONFIG)) == 0) {
s/VIR_DOMAIN_MEM_CONFIG/VIR_DOMAIN_VCPU_CONFIG/
This allows both "LIVE" and "CONFIG" are set, and you use two "if" clauses later for both of them, ( if (flags& VIR_DOMAIN_VCPU_CONFIG), and if (flags& VIR_DOMAIN_VCPU_LIVE) ) so there should be problem.
IMHO it should be: Exactly one of "LIVE" or "CONFIG" is set.
Or is it designed like so, allow both "LIVE" and "CONFIG" is set?
+ qemuReportError(VIR_ERR_INVALID_ARG, + _("invalid flag combination: (0x%x)"), flags); + return -1; + } + qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); qemuDriverUnlock(driver); @@ -2647,7 +2659,7 @@ qemudDomainPinVcpu(virDomainPtr dom, goto cleanup; }
- if (!virDomainObjIsActive(vm)) { + if (!virDomainObjIsActive(vm)&& (flags& VIR_DOMAIN_VCPU_LIVE)) { qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",_("cannot pin vcpus on an inactive domain")); goto cleanup; @@ -2662,27 +2674,52 @@ qemudDomainPinVcpu(virDomainPtr dom, goto cleanup; }
- if (nodeGetInfo(dom->conn,&nodeinfo)< 0) - goto cleanup; + if (flags& VIR_DOMAIN_VCPU_CONFIG) { + if (!vm->persistent) { + qemuReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot change persistent config of a transient domain")); + goto cleanup; + } + if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm))) + goto cleanup; + }
- hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); - maxcpu = maplen * 8; - if (maxcpu> hostcpus) - maxcpu = hostcpus; + if (flags& VIR_DOMAIN_VCPU_LIVE) {
- if (priv->vcpupids != NULL) { - if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], - cpumap, maplen, maxcpu)< 0) + if (nodeGetInfo(dom->conn,&nodeinfo)< 0) goto cleanup; - } else { - qemuReportError(VIR_ERR_NO_SUPPORT, - "%s", _("cpu affinity is not supported")); - goto cleanup; + + hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); + maxcpu = maplen * 8; + if (maxcpu> hostcpus) + maxcpu = hostcpus; + + if (priv->vcpupids != NULL) { + if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], + cpumap, maplen, maxcpu)< 0) + goto cleanup; + } else { + qemuReportError(VIR_ERR_NO_SUPPORT, + "%s", _("cpu affinity is not supported")); + goto cleanup; + } + + if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu)< 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add vcpupin xml of a running domain"));
Indention, :-)
+ goto cleanup; + } + }
- if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu)< 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("failed to update or add vcpupin xml")); + if (flags& VIR_DOMAIN_VCPU_CONFIG) { + + if (virDomainVcpupinAdd(persistentDef, cpumap, maplen, vcpu)< 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add vcpupin xml of a persistent domain"));
likewise
+ goto cleanup; + } + ret = virDomainSaveConfig(driver->configDir, persistentDef); goto cleanup; }
@@ -2695,6 +2732,14 @@ cleanup: }
static int +qemudDomainPinVcpu(virDomainPtr dom, + unsigned int vcpu, + unsigned char *cpumap, + int maplen) { + return qemudDomainPinVcpuFlags(dom, vcpu, cpumap, maplen, VIR_DOMAIN_VCPU_LIVE); +} + +static int qemudDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, @@ -6854,7 +6899,7 @@ static virDriver qemuDriver = { qemudDomainSetVcpusFlags, /* domainSetVcpusFlags */ qemudDomainGetVcpusFlags, /* domainGetVcpusFlags */ qemudDomainPinVcpu, /* domainPinVcpu */ - NULL, /* domainPinVcpuFlags */ + qemudDomainPinVcpuFlags, /* domainPinVcpuFlags */ qemudDomainGetVcpus, /* domainGetVcpus */ qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */ qemudDomainGetSecurityLabel, /* domainGetSecurityLabel */
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

Thank you for reviewing!
+ if ((flags& (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_MEM_CONFIG)) == 0) {
s/VIR_DOMAIN_MEM_CONFIG/VIR_DOMAIN_VCPU_CONFIG/
Oops!. orz
This allows both "LIVE" and "CONFIG" are set, and you use two "if" clauses later for both of them, ( if (flags& VIR_DOMAIN_VCPU_CONFIG), and if (flags& VIR_DOMAIN_VCPU_LIVE) ) so there should be problem.
IMHO it should be: Exactly one of "LIVE" or "CONFIG" is set.
I think "LIVE" and "CONIFG" can coexist, so it is allowed to set at the same time. Best regards, Taku Izumi

On 03/31/2011 01:33 AM, Osier Yang wrote:
This allows both "LIVE" and "CONFIG" are set, and you use two "if" clauses later for both of them, ( if (flags& VIR_DOMAIN_VCPU_CONFIG), and if (flags& VIR_DOMAIN_VCPU_LIVE) ) so there should be problem.
IMHO it should be: Exactly one of "LIVE" or "CONFIG" is set.
No, it should be perfectly acceptable to accept both at once (and some hypervisors may reject LIVE in isolation, as they can only affect LIVE and CONFIG simultaneously). We may _also_ want to document that if neither LIVE nor CONFIG is set, then we instead default to the current state of the domain (LIVE if it is active, CONFIG if it is just defined), as that has proved to be a handy shortcut. We're not very consistent on those semantics on existing APIs (so someone will have to read the docs for each API to learn which setting is which, due to backwards compatibility), but for future APIs it is best to shoot for: flags = 0 - default to LIVE or CONFIG as appropriate flags = LIVE - temporary change - affect running guest but not persistent (error if not running) flags = CONFIG - config change - affect next boot but not running guest (error if guest is transient and running, since there is no persistent state for transient guests) flags = LIVE|CONFIG - affect running guest and affect next boot (error if guest is not running, or if guest is transient) -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

This patch implements the remote protocol to address the new API (virDomainPinVcpuFlags). Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> --- daemon/remote.c | 37 +++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 1 daemon/remote_dispatch_prototypes.h | 8 +++++++ daemon/remote_dispatch_table.h | 5 ++++ src/remote/remote_driver.c | 40 +++++++++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 16 ++++++++++++++ src/remote/remote_protocol.h | 14 ++++++++++++ src/remote/remote_protocol.x | 10 ++++++++- src/remote_protocol-structs | 9 ++++++++ 9 files changed, 138 insertions(+), 2 deletions(-) Index: libvirt/daemon/remote.c =================================================================== --- libvirt.orig/daemon/remote.c +++ libvirt/daemon/remote.c @@ -2188,6 +2188,43 @@ remoteDispatchDomainPinVcpu (struct qemu } static int +remoteDispatchDomainPinVcpuFlags (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_domain_pin_vcpu_flags_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + int rv; + + dom = get_nonnull_domain (conn, args->dom); + if (dom == NULL) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + if (args->cpumap.cpumap_len > REMOTE_CPUMAP_MAX) { + virDomainFree(dom); + remoteDispatchFormatError (rerr, "%s", _("cpumap_len > REMOTE_CPUMAP_MAX")); + return -1; + } + + rv = virDomainPinVcpuFlags (dom, args->vcpu, + (unsigned char *) args->cpumap.cpumap_val, + args->cpumap.cpumap_len, + args->flags); + if (rv == -1) { + remoteDispatchConnError(rerr, conn); + virDomainFree(dom); + return -1; + } + virDomainFree(dom); + return 0; +} + +static int remoteDispatchDomainReboot (struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, virConnectPtr conn, Index: libvirt/daemon/remote_dispatch_args.h =================================================================== --- libvirt.orig/daemon/remote_dispatch_args.h +++ libvirt/daemon/remote_dispatch_args.h @@ -178,3 +178,4 @@ remote_domain_migrate_set_max_speed_args val_remote_domain_migrate_set_max_speed_args; remote_storage_vol_upload_args val_remote_storage_vol_upload_args; remote_storage_vol_download_args val_remote_storage_vol_download_args; + remote_domain_pin_vcpu_flags_args val_remote_domain_pin_vcpu_flags_args; Index: libvirt/daemon/remote_dispatch_prototypes.h =================================================================== --- libvirt.orig/daemon/remote_dispatch_prototypes.h +++ libvirt/daemon/remote_dispatch_prototypes.h @@ -506,6 +506,14 @@ static int remoteDispatchDomainPinVcpu( remote_error *err, remote_domain_pin_vcpu_args *args, void *ret); +static int remoteDispatchDomainPinVcpuFlags( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_pin_vcpu_flags_args *args, + void *ret); static int remoteDispatchDomainReboot( struct qemud_server *server, struct qemud_client *client, Index: libvirt/daemon/remote_dispatch_table.h =================================================================== --- libvirt.orig/daemon/remote_dispatch_table.h +++ libvirt/daemon/remote_dispatch_table.h @@ -1052,3 +1052,8 @@ .args_filter = (xdrproc_t) xdr_remote_storage_vol_download_args, .ret_filter = (xdrproc_t) xdr_void, }, +{ /* DomainPinVcpuFlags => 210 */ + .fn = (dispatch_fn) remoteDispatchDomainPinVcpuFlags, + .args_filter = (xdrproc_t) xdr_remote_domain_pin_vcpu_flags_args, + .ret_filter = (xdrproc_t) xdr_void, +}, Index: libvirt/src/remote/remote_driver.c =================================================================== --- libvirt.orig/src/remote/remote_driver.c +++ libvirt/src/remote/remote_driver.c @@ -3042,6 +3042,44 @@ done: } static int +remoteDomainPinVcpuFlags (virDomainPtr domain, + unsigned int vcpu, + unsigned char *cpumap, + int maplen, + unsigned int flags) +{ + int rv = -1; + remote_domain_pin_vcpu_flags_args args; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + if (maplen > REMOTE_CPUMAP_MAX) { + remoteError(VIR_ERR_RPC, + _("map length greater than maximum: %d > %d"), + maplen, REMOTE_CPUMAP_MAX); + goto done; + } + + make_nonnull_domain (&args.dom, domain); + args.vcpu = vcpu; + args.cpumap.cpumap_len = maplen; + args.cpumap.cpumap_val = (char *) cpumap; + args.flags = flags; + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_PIN_VCPU_FLAGS, + (xdrproc_t) xdr_remote_domain_pin_vcpu_flags_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteDomainGetVcpus (virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, @@ -11227,7 +11265,7 @@ static virDriver remote_driver = { remoteDomainSetVcpusFlags, /* domainSetVcpusFlags */ remoteDomainGetVcpusFlags, /* domainGetVcpusFlags */ remoteDomainPinVcpu, /* domainPinVcpu */ - NULL, /* domainPinVcpuFlags */ + remoteDomainPinVcpuFlags, /* domainPinVcpuFlags */ remoteDomainGetVcpus, /* domainGetVcpus */ remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */ remoteDomainGetSecurityLabel, /* domainGetSecurityLabel */ Index: libvirt/src/remote/remote_protocol.c =================================================================== --- libvirt.orig/src/remote/remote_protocol.c +++ libvirt/src/remote/remote_protocol.c @@ -1521,6 +1521,22 @@ xdr_remote_domain_pin_vcpu_args (XDR *xd } bool_t +xdr_remote_domain_pin_vcpu_flags_args (XDR *xdrs, remote_domain_pin_vcpu_flags_args *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->cpumap.cpumap_val; + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_int (xdrs, &objp->vcpu)) + return FALSE; + if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cpumap.cpumap_len, REMOTE_CPUMAP_MAX)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_domain_get_vcpus_args (XDR *xdrs, remote_domain_get_vcpus_args *objp) { Index: libvirt/src/remote/remote_protocol.h =================================================================== --- libvirt.orig/src/remote/remote_protocol.h +++ libvirt/src/remote/remote_protocol.h @@ -841,6 +841,17 @@ struct remote_domain_pin_vcpu_args { }; typedef struct remote_domain_pin_vcpu_args remote_domain_pin_vcpu_args; +struct remote_domain_pin_vcpu_flags_args { + remote_nonnull_domain dom; + int vcpu; + struct { + u_int cpumap_len; + char *cpumap_val; + } cpumap; + u_int flags; +}; +typedef struct remote_domain_pin_vcpu_flags_args remote_domain_pin_vcpu_flags_args; + struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo; @@ -2413,6 +2424,7 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_DOMAIN_PIN_VCPU_FLAGS = 210, }; typedef enum remote_procedure remote_procedure; @@ -2566,6 +2578,7 @@ extern bool_t xdr_remote_domain_set_vcp extern bool_t xdr_remote_domain_get_vcpus_flags_args (XDR *, remote_domain_get_vcpus_flags_args*); extern bool_t xdr_remote_domain_get_vcpus_flags_ret (XDR *, remote_domain_get_vcpus_flags_ret*); extern bool_t xdr_remote_domain_pin_vcpu_args (XDR *, remote_domain_pin_vcpu_args*); +extern bool_t xdr_remote_domain_pin_vcpu_flags_args (XDR *, remote_domain_pin_vcpu_flags_args*); extern bool_t xdr_remote_domain_get_vcpus_args (XDR *, remote_domain_get_vcpus_args*); extern bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*); extern bool_t xdr_remote_domain_get_max_vcpus_args (XDR *, remote_domain_get_max_vcpus_args*); @@ -2923,6 +2936,7 @@ extern bool_t xdr_remote_domain_set_vcpu extern bool_t xdr_remote_domain_get_vcpus_flags_args (); extern bool_t xdr_remote_domain_get_vcpus_flags_ret (); extern bool_t xdr_remote_domain_pin_vcpu_args (); +extern bool_t xdr_remote_domain_pin_vcpu_flags_args (); extern bool_t xdr_remote_domain_get_vcpus_args (); extern bool_t xdr_remote_domain_get_vcpus_ret (); extern bool_t xdr_remote_domain_get_max_vcpus_args (); Index: libvirt/src/remote/remote_protocol.x =================================================================== --- libvirt.orig/src/remote/remote_protocol.x +++ libvirt/src/remote/remote_protocol.x @@ -843,6 +843,13 @@ struct remote_domain_pin_vcpu_args { opaque cpumap<REMOTE_CPUMAP_MAX>; }; +struct remote_domain_pin_vcpu_flags_args { + remote_nonnull_domain dom; + int vcpu; + opaque cpumap<REMOTE_CPUMAP_MAX>; + unsigned int flags; +}; + struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo; @@ -2176,7 +2183,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 206, REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, - REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209 + REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_DOMAIN_PIN_VCPU_FLAGS = 210 /* * Notice how the entries are grouped in sets of 10 ? Index: libvirt/src/remote_protocol-structs =================================================================== --- libvirt.orig/src/remote_protocol-structs +++ libvirt/src/remote_protocol-structs @@ -528,6 +528,15 @@ struct remote_domain_pin_vcpu_args { char * cpumap_val; } cpumap; }; +struct remote_domain_pin_vcpu_flags_args { + remote_nonnull_domain dom; + int vcpu; + struct { + u_int cpumap_len; + char * cpumap_val; + } cpumap; + u_int flags; +}; struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo;

On Thu, Mar 31, 2011 at 02:39:52PM +0900, Taku Izumi wrote:
This patch implements the remote protocol to address the new API (virDomainPinVcpuFlags).
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> --- daemon/remote.c | 37 +++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 1 daemon/remote_dispatch_prototypes.h | 8 +++++++ daemon/remote_dispatch_table.h | 5 ++++ src/remote/remote_driver.c | 40 +++++++++++++++++++++++++++++++++++- src/remote/remote_protocol.c | 16 ++++++++++++++ src/remote/remote_protocol.h | 14 ++++++++++++ src/remote/remote_protocol.x | 10 ++++++++- src/remote_protocol-structs | 9 ++++++++ 9 files changed, 138 insertions(+), 2 deletions(-)
Index: libvirt/daemon/remote.c =================================================================== --- libvirt.orig/daemon/remote.c +++ libvirt/daemon/remote.c @@ -2188,6 +2188,43 @@ remoteDispatchDomainPinVcpu (struct qemu }
static int +remoteDispatchDomainPinVcpuFlags (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_domain_pin_vcpu_flags_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + virDomainPtr dom; + int rv; + + dom = get_nonnull_domain (conn, args->dom); + if (dom == NULL) { + remoteDispatchConnError(rerr, conn); + return -1; + } + + if (args->cpumap.cpumap_len > REMOTE_CPUMAP_MAX) { + virDomainFree(dom); + remoteDispatchFormatError (rerr, "%s", _("cpumap_len > REMOTE_CPUMAP_MAX")); + return -1; + } + + rv = virDomainPinVcpuFlags (dom, args->vcpu, + (unsigned char *) args->cpumap.cpumap_val, + args->cpumap.cpumap_len, + args->flags); + if (rv == -1) { + remoteDispatchConnError(rerr, conn); + virDomainFree(dom); + return -1; + } + virDomainFree(dom); + return 0; +} + +static int remoteDispatchDomainReboot (struct qemud_server *server ATTRIBUTE_UNUSED, struct qemud_client *client ATTRIBUTE_UNUSED, virConnectPtr conn, Index: libvirt/daemon/remote_dispatch_args.h =================================================================== --- libvirt.orig/daemon/remote_dispatch_args.h +++ libvirt/daemon/remote_dispatch_args.h @@ -178,3 +178,4 @@ remote_domain_migrate_set_max_speed_args val_remote_domain_migrate_set_max_speed_args;
Long line auto-wrapped by your mail client?
remote_storage_vol_upload_args val_remote_storage_vol_upload_args; remote_storage_vol_download_args val_remote_storage_vol_download_args; + remote_domain_pin_vcpu_flags_args val_remote_domain_pin_vcpu_flags_args; Index: libvirt/daemon/remote_dispatch_prototypes.h =================================================================== --- libvirt.orig/daemon/remote_dispatch_prototypes.h +++ libvirt/daemon/remote_dispatch_prototypes.h @@ -506,6 +506,14 @@ static int remoteDispatchDomainPinVcpu( remote_error *err, remote_domain_pin_vcpu_args *args, void *ret); +static int remoteDispatchDomainPinVcpuFlags( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_domain_pin_vcpu_flags_args *args, + void *ret); static int remoteDispatchDomainReboot( struct qemud_server *server, struct qemud_client *client, Index: libvirt/daemon/remote_dispatch_table.h =================================================================== --- libvirt.orig/daemon/remote_dispatch_table.h +++ libvirt/daemon/remote_dispatch_table.h @@ -1052,3 +1052,8 @@ .args_filter = (xdrproc_t) xdr_remote_storage_vol_download_args, .ret_filter = (xdrproc_t) xdr_void, }, +{ /* DomainPinVcpuFlags => 210 */ + .fn = (dispatch_fn) remoteDispatchDomainPinVcpuFlags, + .args_filter = (xdrproc_t) xdr_remote_domain_pin_vcpu_flags_args, + .ret_filter = (xdrproc_t) xdr_void, +}, Index: libvirt/src/remote/remote_driver.c =================================================================== --- libvirt.orig/src/remote/remote_driver.c +++ libvirt/src/remote/remote_driver.c @@ -3042,6 +3042,44 @@ done: }
static int +remoteDomainPinVcpuFlags (virDomainPtr domain, + unsigned int vcpu, + unsigned char *cpumap, + int maplen, + unsigned int flags) +{ + int rv = -1; + remote_domain_pin_vcpu_flags_args args; + struct private_data *priv = domain->conn->privateData; + + remoteDriverLock(priv); + + if (maplen > REMOTE_CPUMAP_MAX) { + remoteError(VIR_ERR_RPC, + _("map length greater than maximum: %d > %d"), + maplen, REMOTE_CPUMAP_MAX); + goto done; + } + + make_nonnull_domain (&args.dom, domain); + args.vcpu = vcpu; + args.cpumap.cpumap_len = maplen; + args.cpumap.cpumap_val = (char *) cpumap; + args.flags = flags; + + if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_PIN_VCPU_FLAGS, + (xdrproc_t) xdr_remote_domain_pin_vcpu_flags_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteDomainGetVcpus (virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, @@ -11227,7 +11265,7 @@ static virDriver remote_driver = { remoteDomainSetVcpusFlags, /* domainSetVcpusFlags */ remoteDomainGetVcpusFlags, /* domainGetVcpusFlags */ remoteDomainPinVcpu, /* domainPinVcpu */ - NULL, /* domainPinVcpuFlags */ + remoteDomainPinVcpuFlags, /* domainPinVcpuFlags */ remoteDomainGetVcpus, /* domainGetVcpus */ remoteDomainGetMaxVcpus, /* domainGetMaxVcpus */ remoteDomainGetSecurityLabel, /* domainGetSecurityLabel */ Index: libvirt/src/remote/remote_protocol.c =================================================================== --- libvirt.orig/src/remote/remote_protocol.c +++ libvirt/src/remote/remote_protocol.c @@ -1521,6 +1521,22 @@ xdr_remote_domain_pin_vcpu_args (XDR *xd }
bool_t +xdr_remote_domain_pin_vcpu_flags_args (XDR *xdrs, remote_domain_pin_vcpu_flags_args *objp)
Long line auto-wrapped by your mail client?
+{ + char **objp_cpp0 = (char **) (void *) &objp->cpumap.cpumap_val; + + if (!xdr_remote_nonnull_domain (xdrs, &objp->dom)) + return FALSE; + if (!xdr_int (xdrs, &objp->vcpu)) + return FALSE; + if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cpumap.cpumap_len, REMOTE_CPUMAP_MAX))
Long line auto-wrapped by your mail client?
+ return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_domain_get_vcpus_args (XDR *xdrs, remote_domain_get_vcpus_args *objp) {
Index: libvirt/src/remote/remote_protocol.h =================================================================== --- libvirt.orig/src/remote/remote_protocol.h +++ libvirt/src/remote/remote_protocol.h @@ -841,6 +841,17 @@ struct remote_domain_pin_vcpu_args { }; typedef struct remote_domain_pin_vcpu_args remote_domain_pin_vcpu_args;
+struct remote_domain_pin_vcpu_flags_args { + remote_nonnull_domain dom; + int vcpu; + struct { + u_int cpumap_len; + char *cpumap_val; + } cpumap; + u_int flags; +}; +typedef struct remote_domain_pin_vcpu_flags_args remote_domain_pin_vcpu_flags_args; + struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo; @@ -2413,6 +2424,7 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_DOMAIN_PIN_VCPU_FLAGS = 210, }; typedef enum remote_procedure remote_procedure;
@@ -2566,6 +2578,7 @@ extern bool_t xdr_remote_domain_set_vcp extern bool_t xdr_remote_domain_get_vcpus_flags_args (XDR *, remote_domain_get_vcpus_flags_args*);
Long line auto-wrapped by your mail client?
extern bool_t xdr_remote_domain_get_vcpus_flags_ret (XDR *, remote_domain_get_vcpus_flags_ret*);
Long line auto-wrapped by your mail client?
extern bool_t xdr_remote_domain_pin_vcpu_args (XDR *, remote_domain_pin_vcpu_args*); +extern bool_t xdr_remote_domain_pin_vcpu_flags_args (XDR *, remote_domain_pin_vcpu_flags_args*);
Long line auto-wrapped by your mail client?
extern bool_t xdr_remote_domain_get_vcpus_args (XDR *, remote_domain_get_vcpus_args*); extern bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*); extern bool_t xdr_remote_domain_get_max_vcpus_args (XDR *, remote_domain_get_max_vcpus_args*);
Long line auto-wrapped by your mail client?
@@ -2923,6 +2936,7 @@ extern bool_t xdr_remote_domain_set_vcpu extern bool_t xdr_remote_domain_get_vcpus_flags_args (); extern bool_t xdr_remote_domain_get_vcpus_flags_ret (); extern bool_t xdr_remote_domain_pin_vcpu_args (); +extern bool_t xdr_remote_domain_pin_vcpu_flags_args (); extern bool_t xdr_remote_domain_get_vcpus_args (); extern bool_t xdr_remote_domain_get_vcpus_ret (); extern bool_t xdr_remote_domain_get_max_vcpus_args (); Index: libvirt/src/remote/remote_protocol.x =================================================================== --- libvirt.orig/src/remote/remote_protocol.x +++ libvirt/src/remote/remote_protocol.x @@ -843,6 +843,13 @@ struct remote_domain_pin_vcpu_args { opaque cpumap<REMOTE_CPUMAP_MAX>; };
+struct remote_domain_pin_vcpu_flags_args { + remote_nonnull_domain dom; + int vcpu; + opaque cpumap<REMOTE_CPUMAP_MAX>; + unsigned int flags; +}; + struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo; @@ -2176,7 +2183,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 206, REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, - REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209 + REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_DOMAIN_PIN_VCPU_FLAGS = 210
/* * Notice how the entries are grouped in sets of 10 ? Index: libvirt/src/remote_protocol-structs =================================================================== --- libvirt.orig/src/remote_protocol-structs +++ libvirt/src/remote_protocol-structs @@ -528,6 +528,15 @@ struct remote_domain_pin_vcpu_args { char * cpumap_val; } cpumap; }; +struct remote_domain_pin_vcpu_flags_args { + remote_nonnull_domain dom; + int vcpu; + struct { + u_int cpumap_len; + char * cpumap_val; + } cpumap; + u_int flags; +}; struct remote_domain_get_vcpus_args { remote_nonnull_domain dom; int maxinfo;
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

This patch adds the new option (--live and --config) to "virsh vcpupin" command. The behavior of above aption is the same as that of "virsh setmem", "virsh setvcpus", and whatnot. When the --config option is specified, the command affects a persistent domain, while --live option is specified, it affects a running (live) domain. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> --- tools/virsh.c | 22 ++++++++++++++++++++-- tools/virsh.pod | 5 ++++- 2 files changed, 24 insertions(+), 3 deletions(-) Index: libvirt/tools/virsh.c =================================================================== --- libvirt.orig/tools/virsh.c +++ libvirt/tools/virsh.c @@ -2712,6 +2712,8 @@ static const vshCmdOptDef opts_vcpupin[] {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"vcpu", VSH_OT_INT, VSH_OFLAG_REQ, N_("vcpu number")}, {"cpulist", VSH_OT_DATA, VSH_OFLAG_REQ, N_("host cpu number(s) (comma separated)")}, + {"config", VSH_OT_BOOL, 0, N_("affect next boot")}, + {"live", VSH_OT_BOOL, 0, N_("affect running domain")}, {NULL, 0, 0, NULL} }; @@ -2728,6 +2730,16 @@ cmdVcpupin(vshControl *ctl, const vshCmd int cpumaplen; int i; enum { expect_num, expect_num_or_comma } state; + int config = vshCommandOptBool(cmd, "config"); + int live = vshCommandOptBool(cmd, "live"); + int flags = 0; + + if (config) + flags |= VIR_DOMAIN_VCPU_CONFIG; + if (live) + flags |= VIR_DOMAIN_VCPU_LIVE; + if (!live && !config) + flags = -1; if (!vshConnectionUsability(ctl, ctl->conn)) return FALSE; @@ -2824,8 +2836,14 @@ cmdVcpupin(vshControl *ctl, const vshCmd cpulist++; } while (cpulist); - if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) { - ret = FALSE; + if (flags == -1) { + if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) { + ret = FALSE; + } + } else { + if (virDomainPinVcpuFlags(dom, vcpu, cpumap, cpumaplen, flags) != 0) { + ret = FALSE; + } } VIR_FREE(cpumap); Index: libvirt/tools/virsh.pod =================================================================== --- libvirt.orig/tools/virsh.pod +++ libvirt/tools/virsh.pod @@ -711,10 +711,13 @@ values; these two flags cannot both be s Returns basic information about the domain virtual CPUs, like the number of vCPUs, the running time, the affinity to physical processors. -=item B<vcpupin> I<domain-id> I<vcpu> I<cpulist> +=item B<vcpupin> I<domain-id> I<vcpu> I<cpulist> optional I<--live> I<--config> Pin domain VCPUs to host physical CPUs. The I<vcpu> number must be provided and I<cpulist> is a comma separated list of physical CPU numbers. +If I<--live> is specified, affect a running guest. +If I<--config> is specified, affect the next boot of a persistent guest. +Both flags may be given. =item B<vncdisplay> I<domain-id>

于 2011年03月31日 13:41, Taku Izumi 写道:
This patch adds the new option (--live and --config) to "virsh vcpupin" command. The behavior of above aption is the same as that of "virsh setmem", "virsh setvcpus", and whatnot. When the --config option is specified, the command affects a persistent domain, while --live option is specified, it affects a running (live) domain.
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> --- tools/virsh.c | 22 ++++++++++++++++++++-- tools/virsh.pod | 5 ++++- 2 files changed, 24 insertions(+), 3 deletions(-)
Index: libvirt/tools/virsh.c =================================================================== --- libvirt.orig/tools/virsh.c +++ libvirt/tools/virsh.c @@ -2712,6 +2712,8 @@ static const vshCmdOptDef opts_vcpupin[] {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, {"vcpu", VSH_OT_INT, VSH_OFLAG_REQ, N_("vcpu number")}, {"cpulist", VSH_OT_DATA, VSH_OFLAG_REQ, N_("host cpu number(s) (comma separated)")}, + {"config", VSH_OT_BOOL, 0, N_("affect next boot")}, + {"live", VSH_OT_BOOL, 0, N_("affect running domain")}, {NULL, 0, 0, NULL} };
@@ -2728,6 +2730,16 @@ cmdVcpupin(vshControl *ctl, const vshCmd int cpumaplen; int i; enum { expect_num, expect_num_or_comma } state; + int config = vshCommandOptBool(cmd, "config"); + int live = vshCommandOptBool(cmd, "live"); + int flags = 0; + + if (config) + flags |= VIR_DOMAIN_VCPU_CONFIG; + if (live) + flags |= VIR_DOMAIN_VCPU_LIVE; + if (!live&& !config) + flags = -1;
if (!vshConnectionUsability(ctl, ctl->conn)) return FALSE; @@ -2824,8 +2836,14 @@ cmdVcpupin(vshControl *ctl, const vshCmd cpulist++; } while (cpulist);
- if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) { - ret = FALSE; + if (flags == -1) { + if (virDomainPinVcpu(dom, vcpu, cpumap, cpumaplen) != 0) { + ret = FALSE; + } + } else { + if (virDomainPinVcpuFlags(dom, vcpu, cpumap, cpumaplen, flags) != 0) { + ret = FALSE; + } }
VIR_FREE(cpumap); Index: libvirt/tools/virsh.pod =================================================================== --- libvirt.orig/tools/virsh.pod +++ libvirt/tools/virsh.pod @@ -711,10 +711,13 @@ values; these two flags cannot both be s Returns basic information about the domain virtual CPUs, like the number of vCPUs, the running time, the affinity to physical processors.
-=item B<vcpupin> I<domain-id> I<vcpu> I<cpulist> +=item B<vcpupin> I<domain-id> I<vcpu> I<cpulist> optional I<--live> I<--config>
Pin domain VCPUs to host physical CPUs. The I<vcpu> number must be provided and I<cpulist> is a comma separated list of physical CPU numbers. +If I<--live> is specified, affect a running guest. +If I<--config> is specified, affect the next boot of a persistent guest. +Both flags may be given.
Oh, yeah, get your sense here, forget about the previous doubt on 2/4 patch. :-) Looks good to me
=item B<vncdisplay> I<domain-id>
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (4)
-
Eric Blake
-
Hu Tao
-
Osier Yang
-
Taku Izumi