e10da2
From 28a3605906385cba43df77051dc26e865f237b09 Mon Sep 17 00:00:00 2001
e10da2
From: Eric Blake <eblake@redhat.com>
e10da2
Date: Wed, 29 Sep 2010 17:40:45 -0600
e10da2
Subject: [PATCH 11/15] vcpu: complete vcpu support in qemu driver
e10da2
e10da2
* src/qemu/qemu_driver.c (qemudDomainSetVcpusFlags)
e10da2
(qemudDomainGetVcpusFlags): Support all feasible flag
e10da2
combinations.
e10da2
---
e10da2
 src/qemu/qemu_driver.c |  100 ++++++++++++++++++++++++++++++++++++++++-------
e10da2
 1 files changed, 85 insertions(+), 15 deletions(-)
e10da2
e10da2
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
e10da2
index c66dc04..a9e057f 100644
e10da2
--- a/src/qemu/qemu_driver.c
e10da2
+++ b/src/qemu/qemu_driver.c
e10da2
@@ -5941,13 +5941,27 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
e10da2
 {
e10da2
     struct qemud_driver *driver = dom->conn->privateData;
e10da2
     virDomainObjPtr vm;
e10da2
+    virDomainDefPtr def;
e10da2
     const char * type;
e10da2
     int max;
e10da2
     int ret = -1;
e10da2
e10da2
-    if (flags != VIR_DOMAIN_VCPU_LIVE) {
e10da2
-        qemuReportError(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
+    /* 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
+        qemuReportError(VIR_ERR_INVALID_ARG,
e10da2
+                        _("invalid flag combination: (0x%x)"), flags);
e10da2
+        return -1;
e10da2
+    }
e10da2
+    if (!nvcpus || (unsigned short) nvcpus != nvcpus) {
e10da2
+        qemuReportError(VIR_ERR_INVALID_ARG,
e10da2
+                        _("argument out of range: %d"), nvcpus);
e10da2
         return -1;
e10da2
     }
e10da2
e10da2
@@ -5966,7 +5980,7 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
e10da2
     if (qemuDomainObjBeginJob(vm) < 0)
e10da2
         goto cleanup;
e10da2
e10da2
-    if (!virDomainObjIsActive(vm)) {
e10da2
+    if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
e10da2
         qemuReportError(VIR_ERR_OPERATION_INVALID,
e10da2
                          "%s", _("domain is not running"));
e10da2
         goto endjob;
e10da2
@@ -5985,6 +5999,11 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
e10da2
         goto endjob;
e10da2
     }
e10da2
e10da2
+    if ((flags & (VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_LIVE)) ==
e10da2
+        VIR_DOMAIN_VCPU_LIVE && vm->def->maxvcpus < max) {
e10da2
+        max = vm->def->maxvcpus;
e10da2
+    }
e10da2
+
e10da2
     if (nvcpus > max) {
e10da2
         qemuReportError(VIR_ERR_INVALID_ARG,
e10da2
                         _("requested vcpus is greater than max allowable"
e10da2
@@ -5992,7 +6011,49 @@ qemudDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
e10da2
         goto endjob;
e10da2
     }
e10da2
e10da2
-    ret = qemudDomainHotplugVcpus(vm, nvcpus);
e10da2
+    switch (flags) {
e10da2
+    case VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_CONFIG:
e10da2
+        def = vm->def;
e10da2
+        if (virDomainObjIsActive(vm)) {
e10da2
+            if (vm->newDef)
e10da2
+                def = vm->newDef;
e10da2
+            else{
e10da2
+                qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
e10da2
+                                _("no persistent state"));
e10da2
+                goto endjob;
e10da2
+            }
e10da2
+        }
e10da2
+        def->maxvcpus = nvcpus;
e10da2
+        if (nvcpus < vm->newDef->vcpus)
e10da2
+            def->vcpus = nvcpus;
e10da2
+        ret = 0;
e10da2
+        break;
e10da2
+
e10da2
+    case VIR_DOMAIN_VCPU_CONFIG:
e10da2
+        def = vm->def;
e10da2
+        if (virDomainObjIsActive(vm)) {
e10da2
+            if (vm->newDef)
e10da2
+                def = vm->newDef;
e10da2
+            else {
e10da2
+                qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
e10da2
+                                _("no persistent state"));
e10da2
+                goto endjob;
e10da2
+            }
e10da2
+        }
e10da2
+        def->vcpus = nvcpus;
e10da2
+        ret = 0;
e10da2
+        break;
e10da2
+
e10da2
+    case VIR_DOMAIN_VCPU_LIVE:
e10da2
+        ret = qemudDomainHotplugVcpus(vm, nvcpus);
e10da2
+        break;
e10da2
+
e10da2
+    case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG:
e10da2
+        ret = qemudDomainHotplugVcpus(vm, nvcpus);
e10da2
+        if (ret == 0 && vm->newDef)
e10da2
+            vm->newDef->vcpus = nvcpus;
e10da2
+        break;
e10da2
+    }
e10da2
e10da2
 endjob:
e10da2
     if (qemuDomainObjEndJob(vm) == 0)
e10da2
@@ -6171,12 +6232,17 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
e10da2
 {
e10da2
     struct qemud_driver *driver = dom->conn->privateData;
e10da2
     virDomainObjPtr vm;
e10da2
-    const char *type;
e10da2
+    virDomainDefPtr def;
e10da2
     int ret = -1;
e10da2
e10da2
-    if (flags != (VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_MAXIMUM)) {
e10da2
-        qemuReportError(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
+        qemuReportError(VIR_ERR_INVALID_ARG,
e10da2
+                        _("invalid flag combination: (0x%x)"), flags);
e10da2
         return -1;
e10da2
     }
e10da2
e10da2
@@ -6192,14 +6258,18 @@ qemudDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
e10da2
         goto cleanup;
e10da2
     }
e10da2
e10da2
-    if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
e10da2
-        qemuReportError(VIR_ERR_INTERNAL_ERROR,
e10da2
-                        _("unknown virt type in domain definition '%d'"),
e10da2
-                        vm->def->virtType);
e10da2
-        goto cleanup;
e10da2
+    if (flags & VIR_DOMAIN_VCPU_LIVE) {
e10da2
+        if (!virDomainObjIsActive(vm)) {
e10da2
+            qemuReportError(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 = qemudGetMaxVCPUs(NULL, type);
e10da2
+    ret = (flags & VIR_DOMAIN_VCPU_MAXIMUM) ? def->maxvcpus : def->vcpus;
e10da2
e10da2
 cleanup:
e10da2
     if (vm)
e10da2
-- 
e10da2
1.7.2.3
e10da2