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.
This commit is contained in:
Eric Blake 2010-09-27 09:37:22 -06:00
parent dd255d6405
commit 9d2c607992

View File

@ -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.
*/
@ -5236,14 +5238,140 @@ error:
return -1;
}
/**
* 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;
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;
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.
*/