e10da2
From 290ea33111be7bdf1f1381b90de33eb0e67c1a15 Mon Sep 17 00:00:00 2001
e10da2
From: Eric Blake <eblake@redhat.com>
e10da2
Date: Wed, 6 Oct 2010 17:54:41 -0600
e10da2
Subject: [PATCH 13/15] vcpu: improve support for getting xen vcpu counts
e10da2
e10da2
* src/xen/xen_driver.c (xenUnifiedDomainGetVcpusFlags): Support
e10da2
more flags.
e10da2
* src/xen/xend_internal.h (xenDaemonDomainGetVcpusFlags): New
e10da2
prototype.
e10da2
* src/xen/xm_internal.h (xenXMDomainGetVcpusFlags): Likewise.
e10da2
* src/xen/xend_internal.c (virDomainGetVcpusFlags): New function.
e10da2
* src/xen/xm_internal.c (xenXMDomainGetVcpusFlags): Likewise.
e10da2
---
e10da2
 src/xen/xen_driver.c    |   31 +++++++++++++++++++--------
e10da2
 src/xen/xend_internal.c |   52 +++++++++++++++++++++++++++++++++++++++++++++++
e10da2
 src/xen/xend_internal.h |    2 +
e10da2
 src/xen/xm_internal.c   |   47 ++++++++++++++++++++++++++++++++++++++++++
e10da2
 src/xen/xm_internal.h   |    1 +
e10da2
 5 files changed, 124 insertions(+), 9 deletions(-)
e10da2
e10da2
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
e10da2
index d6c9c57..fe2ff86 100644
e10da2
--- a/src/xen/xen_driver.c
e10da2
+++ b/src/xen/xen_driver.c
e10da2
@@ -1142,20 +1142,33 @@ static int
e10da2
 xenUnifiedDomainGetVcpusFlags (virDomainPtr dom, unsigned int flags)
e10da2
 {
e10da2
     GET_PRIVATE(dom->conn);
e10da2
-    int i, ret;
e10da2
+    int ret;
e10da2
e10da2
-    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
e10da2
-        xenUnifiedError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"),
e10da2
-                        flags);
e10da2
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
e10da2
+                  VIR_DOMAIN_VCPU_CONFIG |
e10da2
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
e10da2
+
e10da2
+    /* Exactly one of LIVE or CONFIG must be set.  */
e10da2
+    if (!(flags & VIR_DOMAIN_VCPU_LIVE) == !(flags & VIR_DOMAIN_VCPU_CONFIG)) {
e10da2
+        xenUnifiedError(VIR_ERR_INVALID_ARG,
e10da2
+                        _("invalid flag combination: (0x%x)"), flags);
e10da2
         return -1;
e10da2
     }
e10da2
e10da2
-    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
e10da2
-        if (priv->opened[i] && drivers[i]->domainGetMaxVcpus) {
e10da2
-            ret = drivers[i]->domainGetMaxVcpus (dom);
e10da2
-            if (ret != 0) return ret;
e10da2
-        }
e10da2
+    if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
e10da2
+        ret = xenDaemonDomainGetVcpusFlags(dom, flags);
e10da2
+        if (ret != -2)
e10da2
+            return ret;
e10da2
+    }
e10da2
+    if (priv->opened[XEN_UNIFIED_XM_OFFSET]) {
e10da2
+        ret = xenXMDomainGetVcpusFlags(dom, flags);
e10da2
+        if (ret != -2)
e10da2
+            return ret;
e10da2
+    }
e10da2
+    if (flags == (VIR_DOMAIN_VCPU_CONFIG | VIR_DOMAIN_VCPU_MAXIMUM))
e10da2
+        return xenHypervisorGetVcpuMax(dom);
e10da2
e10da2
+    xenUnifiedError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
e10da2
     return -1;
e10da2
 }
e10da2
e10da2
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
e10da2
index dfc6415..3642296 100644
e10da2
--- a/src/xen/xend_internal.c
e10da2
+++ b/src/xen/xend_internal.c
e10da2
@@ -3620,6 +3620,58 @@ xenDaemonDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
e10da2
 }
e10da2
e10da2
 /**
e10da2
+ * xenDaemonDomainGetVcpusFlags:
e10da2
+ * @domain: pointer to domain object
e10da2
+ * @flags: bitwise-ORd from virDomainVcpuFlags
e10da2
+ *
e10da2
+ * Extract information about virtual CPUs of domain according to flags.
e10da2
+ *
e10da2
+ * Returns the number of vcpus on success, -1 if an error message was
e10da2
+ * issued, and -2 if the unified driver should keep trying.
e10da2
+
e10da2
+ */
e10da2
+int
e10da2
+xenDaemonDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
e10da2
+{
e10da2
+    struct sexpr *root;
e10da2
+    int ret;
e10da2
+    xenUnifiedPrivatePtr priv;
e10da2
+
e10da2
+    if (domain == NULL || domain->conn == NULL || domain->name == NULL) {
e10da2
+        virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
e10da2
+        return -1;
e10da2
+    }
e10da2
+
e10da2
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
e10da2
+
e10da2
+    /* If xendConfigVersion is 2, then we can only report _LIVE (and
e10da2
+     * xm_internal reports _CONFIG).  If it is 3, then _LIVE and
e10da2
+     * _CONFIG are always in sync for a running system.  */
e10da2
+    if (domain->id < 0 && priv->xendConfigVersion < XEND_CONFIG_VERSION_3_0_4)
e10da2
+        return -2;
e10da2
+    if (domain->id < 0 && (flags & VIR_DOMAIN_VCPU_LIVE)) {
e10da2
+        virXendError(VIR_ERR_OPERATION_INVALID, "%s",
e10da2
+                     _("domain not active"));
e10da2
+        return -1;
e10da2
+    }
e10da2
+
e10da2
+    root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
e10da2
+    if (root == NULL)
e10da2
+        return -1;
e10da2
+
e10da2
+    ret = sexpr_int(root, "domain/vcpus");
e10da2
+    if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM)) {
e10da2
+        int vcpus = count_one_bits(sexpr_int(root, "domain/vcpu_avail"));
e10da2
+        if (vcpus)
e10da2
+            ret = MIN(vcpus, ret);
e10da2
+    }
e10da2
+    if (!ret)
e10da2
+        ret = -2;
e10da2
+    sexpr_free(root);
e10da2
+    return ret;
e10da2
+}
e10da2
+
e10da2
+/**
e10da2
  * virDomainGetVcpus:
e10da2
  * @domain: pointer to domain object, or NULL for Domain0
e10da2
  * @info: pointer to an array of virVcpuInfo structures (OUT)
e10da2
diff --git a/src/xen/xend_internal.h b/src/xen/xend_internal.h
e10da2
index c757716..923cebd 100644
e10da2
--- a/src/xen/xend_internal.h
e10da2
+++ b/src/xen/xend_internal.h
e10da2
@@ -155,6 +155,8 @@ int	xenDaemonDomainPinVcpu		(virDomainPtr domain,
e10da2
                                          unsigned int vcpu,
e10da2
                                          unsigned char *cpumap,
e10da2
                                          int maplen);
e10da2
+int     xenDaemonDomainGetVcpusFlags    (virDomainPtr domain,
e10da2
+                                         unsigned int flags);
e10da2
 int	xenDaemonDomainGetVcpus		(virDomainPtr domain,
e10da2
                                          virVcpuInfoPtr info,
e10da2
                                          int maxinfo,
e10da2
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
e10da2
index f7121ab..4ea4245 100644
e10da2
--- a/src/xen/xm_internal.c
e10da2
+++ b/src/xen/xm_internal.c
e10da2
@@ -1671,6 +1671,53 @@ cleanup:
e10da2
 }
e10da2
e10da2
 /**
e10da2
+ * xenXMDomainGetVcpusFlags:
e10da2
+ * @domain: pointer to domain object
e10da2
+ * @flags: bitwise-ORd from virDomainVcpuFlags
e10da2
+ *
e10da2
+ * Extract information about virtual CPUs of domain according to flags.
e10da2
+ *
e10da2
+ * Returns the number of vcpus on success, -1 if an error message was
e10da2
+ * issued, and -2 if the unified driver should keep trying.
e10da2
+ */
e10da2
+int
e10da2
+xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
e10da2
+{
e10da2
+    xenUnifiedPrivatePtr priv;
e10da2
+    const char *filename;
e10da2
+    xenXMConfCachePtr entry;
e10da2
+    int ret = -2;
e10da2
+
e10da2
+    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
e10da2
+        xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
e10da2
+        return -1;
e10da2
+    }
e10da2
+
e10da2
+    if (domain->id != -1)
e10da2
+        return -2;
e10da2
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
e10da2
+        xenXMError(VIR_ERR_OPERATION_FAILED, "%s", _("domain not active"));
e10da2
+        return -1;
e10da2
+    }
e10da2
+
e10da2
+    priv = domain->conn->privateData;
e10da2
+    xenUnifiedLock(priv);
e10da2
+
e10da2
+    if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
e10da2
+        goto cleanup;
e10da2
+
e10da2
+    if (!(entry = virHashLookup(priv->configCache, filename)))
e10da2
+        goto cleanup;
e10da2
+
e10da2
+    ret = ((flags & VIR_DOMAIN_VCPU_MAXIMUM) ? entry->def->maxvcpus
e10da2
+           : entry->def->vcpus);
e10da2
+
e10da2
+cleanup:
e10da2
+    xenUnifiedUnlock(priv);
e10da2
+    return ret;
e10da2
+}
e10da2
+
e10da2
+/**
e10da2
  * xenXMDomainPinVcpu:
e10da2
  * @domain: pointer to domain object
e10da2
  * @vcpu: virtual CPU number (reserved)
e10da2
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
e10da2
index 3ad3456..3295fbd 100644
e10da2
--- a/src/xen/xm_internal.h
e10da2
+++ b/src/xen/xm_internal.h
e10da2
@@ -45,6 +45,7 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory);
e10da2
 int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
e10da2
 unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain);
e10da2
 int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus);
e10da2
+int xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags);
e10da2
 int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
e10da2
                        unsigned char *cpumap, int maplen);
e10da2
 virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname);
e10da2
-- 
e10da2
1.7.2.3
e10da2