e10da2
From 6c9e6b956453d0f0c4ff542ef8a184d663a39266 Mon Sep 17 00:00:00 2001
e10da2
From: Eric Blake <eblake@redhat.com>
e10da2
Date: Mon, 4 Oct 2010 17:01:12 -0600
e10da2
Subject: [PATCH 09/15] vcpu: support all flags in test driver
e10da2
e10da2
* src/test/test_driver.c (testDomainGetVcpusFlags)
e10da2
(testDomainSetVcpusFlags): Support all flags.
e10da2
(testDomainUpdateVCPUs): Update cpu count here.
e10da2
---
e10da2
 src/test/test_driver.c |  128 ++++++++++++++++++++++++++++++++++++++++-------
e10da2
 1 files changed, 109 insertions(+), 19 deletions(-)
e10da2
e10da2
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
e10da2
index b70c80d..a9d3d89 100644
e10da2
--- a/src/test/test_driver.c
e10da2
+++ b/src/test/test_driver.c
e10da2
@@ -450,6 +450,7 @@ testDomainUpdateVCPUs(virConnectPtr conn,
e10da2
                 goto cleanup;
e10da2
     }
e10da2
e10da2
+    dom->def->vcpus = nvcpus;
e10da2
     ret = 0;
e10da2
 cleanup:
e10da2
     return ret;
e10da2
@@ -2032,12 +2033,51 @@ cleanup:
e10da2
 static int
e10da2
 testDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
e10da2
 {
e10da2
-    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
e10da2
-        testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
e10da2
+    testConnPtr privconn = domain->conn->privateData;
e10da2
+    virDomainObjPtr vm;
e10da2
+    virDomainDefPtr def;
e10da2
+    int ret = -1;
e10da2
+
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
+        testError(VIR_ERR_INVALID_ARG,
e10da2
+                  _("invalid flag combination: (0x%x)"), flags);
e10da2
         return -1;
e10da2
     }
e10da2
e10da2
-    return testGetMaxVCPUs(domain->conn, "test");
e10da2
+    testDriverLock(privconn);
e10da2
+    vm = virDomainFindByUUID(&privconn->domains, domain->uuid);
e10da2
+    testDriverUnlock(privconn);
e10da2
+
e10da2
+    if (!vm) {
e10da2
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
e10da2
+        virUUIDFormat(domain->uuid, uuidstr);
e10da2
+        testError(VIR_ERR_NO_DOMAIN,
e10da2
+                  _("no domain with matching uuid '%s'"), uuidstr);
e10da2
+        goto cleanup;
e10da2
+    }
e10da2
+
e10da2
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
e10da2
+        if (!virDomainObjIsActive(vm)) {
e10da2
+            testError(VIR_ERR_OPERATION_INVALID, "%s",
e10da2
+                      _("domain not active"));
e10da2
+            goto cleanup;
e10da2
+        }
e10da2
+        def = vm->def;
e10da2
+    } else {
e10da2
+        def = vm->newDef ? vm->newDef : vm->def;
e10da2
+    }
e10da2
+
e10da2
+    ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
e10da2
+
e10da2
+cleanup:
e10da2
+    if (vm)
e10da2
+        virDomainObjUnlock(vm);
e10da2
+    return ret;
e10da2
 }
e10da2
e10da2
 static int
e10da2
@@ -2053,21 +2093,30 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
e10da2
 {
e10da2
     testConnPtr privconn = domain->conn->privateData;
e10da2
     virDomainObjPtr privdom = NULL;
e10da2
+    virDomainDefPtr def;
e10da2
     int ret = -1, maxvcpus;
e10da2
e10da2
-    if (flags != VIR_DOMAIN_VCPU_LIVE) {
e10da2
-        testError(VIR_ERR_INVALID_ARG, _("unsupported flags: (0x%x)"), flags);
e10da2
+    virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
e10da2
+                  VIR_DOMAIN_VCPU_CONFIG |
e10da2
+                  VIR_DOMAIN_VCPU_MAXIMUM, -1);
e10da2
+
e10da2
+    /* At least one of LIVE or CONFIG must be set.  MAXIMUM cannot be
e10da2
+     * mixed with LIVE.  */
e10da2
+    if ((flags & (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG)) == 0 ||
e10da2
+        (flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
e10da2
+         (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) {
e10da2
+        testError(VIR_ERR_INVALID_ARG,
e10da2
+                  _("invalid flag combination: (0x%x)"), flags);
e10da2
+        return -1;
e10da2
+    }
e10da2
+    if (!nrCpus || (maxvcpus = testGetMaxVCPUs(domain->conn, NULL)) < nrCpus) {
e10da2
+        testError(VIR_ERR_INVALID_ARG,
e10da2
+                  _("argument out of range: %d"), nrCpus);
e10da2
         return -1;
e10da2
     }
e10da2
-
e10da2
-    /* Do this first before locking */
e10da2
-    maxvcpus = testDomainGetMaxVcpus(domain);
e10da2
-    if (maxvcpus < 0)
e10da2
-        goto cleanup;
e10da2
e10da2
     testDriverLock(privconn);
e10da2
-    privdom = virDomainFindByName(&privconn->domains,
e10da2
-                                  domain->name);
e10da2
+    privdom = virDomainFindByUUID(&privconn->domains, domain->uuid);
e10da2
     testDriverUnlock(privconn);
e10da2
e10da2
     if (privdom == NULL) {
e10da2
@@ -2075,13 +2124,17 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
e10da2
         goto cleanup;
e10da2
     }
e10da2
e10da2
-    if (!virDomainObjIsActive(privdom)) {
e10da2
+    if (!virDomainObjIsActive(privdom) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
e10da2
         testError(VIR_ERR_OPERATION_INVALID,
e10da2
                   "%s", _("cannot hotplug vcpus for an inactive domain"));
e10da2
         goto cleanup;
e10da2
     }
e10da2
e10da2
-    /* We allow more cpus in guest than host */
e10da2
+    /* We allow more cpus in guest than host, but not more than the
e10da2
+     * domain's starting limit.  */
e10da2
+    if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
e10da2
+        VIR_DOMAIN_VCPU_LIVE && privdom->def->maxvcpus < maxvcpus)
e10da2
+        maxvcpus = privdom->def->maxvcpus;
e10da2
     if (nrCpus > maxvcpus) {
e10da2
         testError(VIR_ERR_INVALID_ARG,
e10da2
                   "requested cpu amount exceeds maximum (%d > %d)",
e10da2
@@ -2089,12 +2142,49 @@ testDomainSetVcpusFlags(virDomainPtr domain, unsigned int nrCpus,
e10da2
         goto cleanup;
e10da2
     }
e10da2
e10da2
-    /* Update VCPU state for the running domain */
e10da2
-    if (testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0) < 0)
e10da2
-        goto cleanup;
e10da2
+    switch (flags) {
e10da2
+    case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
e10da2
+        def = privdom->def;
e10da2
+        if (virDomainObjIsActive(privdom)) {
e10da2
+            if (privdom->newDef)
e10da2
+                def = privdom->newDef;
e10da2
+            else {
e10da2
+                testError(VIR_ERR_OPERATION_INVALID, "%s",
e10da2
+                          _("no persistent state"));
e10da2
+                goto cleanup;
e10da2
+            }
e10da2
+        }
e10da2
+        def->maxvcpus = nrCpus;
e10da2
+        if (nrCpus < def->vcpus)
e10da2
+            def->vcpus = nrCpus;
e10da2
+        ret = 0;
e10da2
+        break;
e10da2
e10da2
-    privdom->def->vcpus = nrCpus;
e10da2
-    ret = 0;
e10da2
+    case VIR_DOMAIN_VCPU_CONFIG:
e10da2
+        def = privdom->def;
e10da2
+        if (virDomainObjIsActive(privdom)) {
e10da2
+            if (privdom->newDef)
e10da2
+                def = privdom->newDef;
e10da2
+            else {
e10da2
+                testError(VIR_ERR_OPERATION_INVALID, "%s",
e10da2
+                          _("no persistent state"));
e10da2
+                goto cleanup;
e10da2
+            }
e10da2
+        }
e10da2
+        def->vcpus = nrCpus;
e10da2
+        ret = 0;
e10da2
+        break;
e10da2
+
e10da2
+    case VIR_DOMAIN_VCPU_LIVE:
e10da2
+        ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
e10da2
+        break;
e10da2
+
e10da2
+    case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
e10da2
+        ret = testDomainUpdateVCPUs(domain->conn, privdom, nrCpus, 0);
e10da2
+        if (ret == 0 && privdom->newDef)
e10da2
+            privdom->newDef->vcpus = nrCpus;
e10da2
+        break;
e10da2
+    }
e10da2
e10da2
 cleanup:
e10da2
     if (privdom)
e10da2
-- 
e10da2
1.7.2.3
e10da2