]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: adjust maxmem/maxvcpu computation
authorEric Blake <eblake@redhat.com>
Fri, 24 Jan 2014 17:52:23 +0000 (10:52 -0700)
committerEric Blake <eblake@redhat.com>
Thu, 20 Feb 2014 18:27:16 +0000 (11:27 -0700)
https://bugzilla.redhat.com/show_bug.cgi?id=1038363

If a domain has a different maximum for persistent and live maxmem
or max vcpus, then it is possible to hit cases where libvirt
refuses to adjust the current values or gets halfway through
the adjustment before failing.  Better is to determine up front
if the change is possible for all requested flags.

Based on an idea by Geoff Franks.

* src/qemu/qemu_driver.c (qemuDomainSetMemoryFlags): Compute
correct maximum if both live and config are being set.
(qemuDomainSetVcpusFlags): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/qemu/qemu_driver.c

index a291c205d1aa8a50a98f005a3080e2ec7fb34cb8..c9a865ebcf7bd06107c7cde9048a965305d86ce9 100644 (file)
@@ -2245,8 +2245,16 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
 
     } else {
         /* resize the current memory */
+        unsigned long oldmax = 0;
 
-        if (newmem > vm->def->mem.max_balloon) {
+        if (flags & VIR_DOMAIN_AFFECT_LIVE)
+            oldmax = vm->def->mem.max_balloon;
+        if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+            if (!oldmax || oldmax > persistentDef->mem.max_balloon)
+                oldmax = persistentDef->mem.max_balloon;
+        }
+
+        if (newmem > oldmax) {
             virReportError(VIR_ERR_INVALID_ARG, "%s",
                            _("cannot set memory higher than max memory"));
             goto endjob;
@@ -4124,6 +4132,7 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
     virDomainDefPtr persistentDef;
     int ret = -1;
     bool maximum;
+    unsigned int maxvcpus = 0;
     virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
     qemuAgentCPUInfoPtr cpuinfo = NULL;
@@ -4171,11 +4180,17 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
         goto endjob;
     }
 
-    if (!maximum && nvcpus > vm->def->maxvcpus) {
+    if (flags & VIR_DOMAIN_AFFECT_LIVE)
+        maxvcpus = vm->def->maxvcpus;
+    if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
+        if (!maxvcpus || maxvcpus > persistentDef->maxvcpus)
+            maxvcpus = persistentDef->maxvcpus;
+    }
+    if (!maximum && nvcpus > maxvcpus) {
         virReportError(VIR_ERR_INVALID_ARG,
                        _("requested vcpus is greater than max allowable"
                          " vcpus for the domain: %d > %d"),
-                       nvcpus, vm->def->maxvcpus);
+                       nvcpus, maxvcpus);
         goto endjob;
     }