From 9d2c60799271d605f82dfd4bfa6ed7d14ad87e26 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 27 Sep 2010 09:37:22 -0600 Subject: [PATCH 04/15] vcpu: implement the public APIs Factors common checks (such as nonzero vcpu count) up front, but drivers will still need to do additional flag checks. * src/libvirt.c (virDomainSetVcpusFlags, virDomainGetVcpusFlags): New functions. (virDomainSetVcpus, virDomainGetMaxVcpus): Refer to new API. --- src/libvirt.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 134 insertions(+), 6 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 629d97b..1b39210 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -5192,7 +5192,9 @@ error: * This function requires privileged access to the hypervisor. * * This command only changes the runtime configuration of the domain, - * so can only be called on an active domain. + * so can only be called on an active domain. It is hypervisor-dependent + * whether it also affects persistent configuration; for more control, + * use virDomainSetVcpusFlags(). * * Returns 0 in case of success, -1 in case of failure. */ @@ -5237,13 +5239,139 @@ error: } /** + * virDomainSetVcpusFlags: + * @domain: pointer to domain object, or NULL for Domain0 + * @nvcpus: the new number of virtual CPUs for this domain, must be at least 1 + * @flags: an OR'ed set of virDomainVcpuFlags + * + * Dynamically change the number of virtual CPUs used by the domain. + * Note that this call may fail if the underlying virtualization hypervisor + * does not support it or if growing the number is arbitrary limited. + * 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_VCPU_CONFIG to affect the next boot via the XML + * description of the domain. Both flags may be set. + * + * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then + * VIR_DOMAIN_VCPU_LIVE must be clear, and only the maximum virtual + * CPU limit is altered; generally, this value must be less than or + * equal to virConnectGetMaxVcpus(). Otherwise, this call affects the + * current virtual CPU limit, which must be less than or equal to the + * maximum limit. + * + * Returns 0 in case of success, -1 in case of failure. + */ + +int +virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus, + unsigned int flags) +{ + virConnectPtr conn; + VIR_DEBUG("domain=%p, nvcpus=%u, flags=%u", domain, nvcpus, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return (-1); + } + if (domain->conn->flags & VIR_CONNECT_RO) { + virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + /* Perform some argument validation common to all implementations. */ + if (nvcpus < 1 || (unsigned short) nvcpus != nvcpus || + (flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0) { + virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainSetVcpusFlags) { + int ret; + ret = conn->driver->domainSetVcpusFlags (domain, nvcpus, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** + * virDomainGetVcpusFlags: + * @domain: pointer to domain object, or NULL for Domain0 + * @flags: an OR'ed set of virDomainVcpuFlags + * + * Query the number of virtual CPUs used by the domain. Note that + * this call may fail if the underlying virtualization hypervisor does + * not support it. This function requires privileged access to the + * hypervisor. + * + * @flags must include either VIR_DOMAIN_VCPU_ACTIVE to query a + * running domain (which will fail if domain is not active), or + * VIR_DOMAIN_VCPU_PERSISTENT to query the XML description of the + * domain. It is an error to set both flags. + * + * If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum + * virtual CPU limit is queried. Otherwise, this call queries the + * current virtual CPU limit. + * + * Returns 0 in case of success, -1 in case of failure. + */ + +int +virDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags) +{ + virConnectPtr conn; + VIR_DEBUG("domain=%p, flags=%u", domain, flags); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return (-1); + } + + /* Exactly one of these two flags should be set. */ + if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) { + virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + conn = domain->conn; + + if (conn->driver->domainGetVcpusFlags) { + int ret; + ret = conn->driver->domainGetVcpusFlags (domain, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} + +/** * virDomainPinVcpu: * @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. + * 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. @@ -5371,9 +5499,9 @@ error: * * Provides the maximum number of virtual CPUs supported for * the guest VM. If the guest is inactive, this is basically - * the same as virConnectGetMaxVcpus. If the guest is running + * the same as virConnectGetMaxVcpus(). If the guest is running * this will reflect the maximum number of virtual CPUs the - * guest was booted with. + * guest was booted with. For more details, see virDomainGetVcpusFlags(). * * Returns the maximum of virtual CPU or -1 in case of error. */ -- 1.7.2.3