vcpu: improve support for getting xen vcpu counts

* src/xen/xen_driver.c (xenUnifiedDomainGetVcpusFlags): Support
more flags.
* src/xen/xend_internal.h (xenDaemonDomainGetVcpusFlags): New
prototype.
* src/xen/xm_internal.h (xenXMDomainGetVcpusFlags): Likewise.
* src/xen/xend_internal.c (virDomainGetVcpusFlags): New function.
* src/xen/xm_internal.c (xenXMDomainGetVcpusFlags): Likewise.
This commit is contained in:
Eric Blake 2010-10-06 17:54:41 -06:00
parent 0fab10e5ed
commit 290ea33111
5 changed files with 124 additions and 9 deletions

View File

@ -1142,20 +1142,33 @@ static int
xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
{
GET_PRIVATE(dom->conn);
int i, ret;
int ret;
if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
flags);
virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
VIR_DOMAIN_VCPU_CONFIG |
VIR_DOMAIN_VCPU_MAXIMUM, -1);
/* Exactly one of LIVE or CONFIG must be set. */
if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
xenUnifiedError(VIR_ERR_INVALID_ARG,
_("invalid flag combination: (0x%x)"), flags);
return -1;
}
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
ret = drivers[i]->domainGetMaxVcpus (dom);
if (ret != 0) return ret;
}
if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
ret = xenDaemonDomainGetVcpusFlags(dom, flags);
if (ret != -2)
return ret;
}
if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
ret = xenXMDomainGetVcpusFlags(dom, flags);
if (ret != -2)
return ret;
}
if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM))
return xenHypervisorGetVcpuMax(dom);
xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
return -1;
}

View File

@ -3619,6 +3619,58 @@ xenDaemonDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
"cpumap", mapstr, NULL));
}
/**
* xenDaemonDomainGetVcpusFlags:
* @domain: pointer to domain object
* @flags: bitwise-ORd from virDomainVcpuFlags
*
* Extract information about virtual CPUs of domain according to flags.
*
* Returns the number of vcpus on success, -1 if an error message was
* issued, and -2 if the unified driver should keep trying.
*/
int
xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
struct sexpr *root;
int ret;
xenUnifiedPrivatePtr priv;
if (domain == NULL || domain->conn == NULL || domain->name == NULL) {
virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
/* If xendConfigVersion is 2, then we can only report _LIVE (and
* xm_internal reports _CONFIG). If it is 3, then _LIVE and
* _CONFIG are always in sync for a running system. */
if (domain->id < 0 && priv->xendConfigVersion < 3)
return -2;
if (domain->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) {
virXendError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain not active"));
return -1;
}
root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
if (root == NULL)
return -1;
ret = sexpr_int(root, "domain/vcpus");
if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM)) {
int vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
if (vcpus)
ret = MIN(vcpus, ret);
}
if (!ret)
ret = -2;
sexpr_free(root);
return ret;
}
/**
* virDomainGetVcpus:
* @domain: pointer to domain object, or NULL for Domain0

View File

@ -155,6 +155,8 @@ int xenDaemonDomainPinVcpu (virDomainPtr domain,
unsigned int vcpu,
unsigned char *cpumap,
int maplen);
int xenDaemonDomainGetVcpusFlags (virDomainPtr domain,
unsigned int flags);
int xenDaemonDomainGetVcpus (virDomainPtr domain,
virVcpuInfoPtr info,
int maxinfo,

View File

@ -1670,6 +1670,53 @@ cleanup:
return ret;
}
/**
* xenXMDomainGetVcpusFlags:
* @domain: pointer to domain object
* @flags: bitwise-ORd from virDomainVcpuFlags
*
* Extract information about virtual CPUs of domain according to flags.
*
* Returns the number of vcpus on success, -1 if an error message was
* issued, and -2 if the unified driver should keep trying.
*/
int
xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
xenUnifiedPrivatePtr priv;
const char *filename;
xenXMConfCachePtr entry;
int ret = -2;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->id != -1)
return -2;
if (flags & VIR_DOMAIN_VCPU_LIVE) {
xenXMError(VIR_ERR_OPERATION_FAILED, "%s", _("domain not active"));
return -1;
}
priv = domain->conn->privateData;
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
ret = ((flags & VIR_DOMAIN_VCPU_MAXIMUM) ? entry->def->maxvcpus
: entry->def->vcpus);
cleanup:
xenUnifiedUnlock(priv);
return ret;
}
/**
* xenXMDomainPinVcpu:
* @domain: pointer to domain object

View File

@ -45,6 +45,7 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
unsigned char *cpumap, int maplen);
virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname);