From 290ea33111be7bdf1f1381b90de33eb0e67c1a15 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 6 Oct 2010 17:54:41 -0600 Subject: [PATCH 13/15] 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. --- src/xen/xen_driver.c | 31 +++++++++++++++++++-------- src/xen/xend_internal.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ src/xen/xend_internal.h | 2 + src/xen/xm_internal.c | 47 ++++++++++++++++++++++++++++++++++++++++++ src/xen/xm_internal.h | 1 + 5 files changed, 124 insertions(+), 9 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index d6c9c57..fe2ff86 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -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; } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index dfc6415..3642296 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -3620,6 +3620,58 @@ xenDaemonDomainPinVcpu(virDomainPtr domain, unsigned int vcpu, } /** + * 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 < XEND_CONFIG_VERSION_3_0_4) + 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 * @info: pointer to an array of virVcpuInfo structures (OUT) diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h index c757716..923cebd 100644 --- a/src/xen/xend_internal.h +++ b/src/xen/xend_internal.h @@ -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, diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index f7121ab..4ea4245 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1671,6 +1671,53 @@ cleanup: } /** + * 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 * @vcpu: virtual CPU number (reserved) diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h index 3ad3456..3295fbd 100644 --- a/src/xen/xm_internal.h +++ b/src/xen/xm_internal.h @@ -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); -- 1.7.2.3