This patch implements the code to support virDomainSetMaxMemory API,
and to support VIR_DOMAIN_MEM_MAXIMUM flag in qemudDomainSetMemoryFlags 
function.
As a result, we can change the maximum memory size of inactive QEMU guests.

Signed-off-by: Taku Izumi <izumi.t...@jp.fujitsu.com>
---
 src/qemu/qemu_driver.c |   85 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 61 insertions(+), 24 deletions(-)

Index: libvirt/src/qemu/qemu_driver.c
===================================================================
--- libvirt.orig/src/qemu/qemu_driver.c
+++ libvirt/src/qemu/qemu_driver.c
@@ -1578,7 +1578,9 @@ static int qemudDomainSetMemoryFlags(vir
     int ret = -1, r, isActive;

     virCheckFlags(VIR_DOMAIN_MEM_LIVE |
-                  VIR_DOMAIN_MEM_CONFIG, -1);
+                  VIR_DOMAIN_MEM_CONFIG |
+                  VIR_DOMAIN_MEM_MAXIMUM, -1);
+

     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1591,12 +1593,6 @@ static int qemudDomainSetMemoryFlags(vir
         goto cleanup;
     }

-    if (newmem > vm->def->mem.max_balloon) {
-        qemuReportError(VIR_ERR_INVALID_ARG,
-                        "%s", _("cannot set memory higher than max memory"));
-        goto cleanup;
-    }
-
     if (qemuDomainObjBeginJob(vm) < 0)
         goto cleanup;

@@ -1608,6 +1604,15 @@ static int qemudDomainSetMemoryFlags(vir
         else
             flags = VIR_DOMAIN_MEM_CONFIG;
     }
+    if (flags == VIR_DOMAIN_MEM_MAXIMUM) {
+        if (isActive) {
+            qemuReportError(VIR_ERR_OPERATION_INVALID,
+                            _("cannot resize the maximum memory on an active 
domain"));
+            goto endjob;
+        } else {
+            flags = VIR_DOMAIN_MEM_CONFIG | VIR_DOMAIN_MEM_MAXIMUM;
+        }
+    }

     if (!isActive && (flags & VIR_DOMAIN_MEM_LIVE)) {
         qemuReportError(VIR_ERR_OPERATION_INVALID,
@@ -1625,27 +1630,54 @@ static int qemudDomainSetMemoryFlags(vir
             goto endjob;
     }

-    if (flags & VIR_DOMAIN_MEM_LIVE) {
-        priv = vm->privateData;
-        qemuDomainObjEnterMonitor(vm);
-        r = qemuMonitorSetBalloon(priv->mon, newmem);
-        qemuDomainObjExitMonitor(vm);
-        qemuAuditMemory(vm, vm->def->mem.cur_balloon, newmem, "update", r == 
1);
-        if (r < 0)
-            goto endjob;
+    if (flags & VIR_DOMAIN_MEM_MAXIMUM) {
+        /* resize the maximum memory */

-        /* Lack of balloon support is a fatal error */
-        if (r == 0) {
+        if (flags & VIR_DOMAIN_MEM_LIVE) {
             qemuReportError(VIR_ERR_OPERATION_INVALID,
-                            "%s", _("cannot set memory of an active domain"));
+                            _("cannot resize the maximum memory on an active 
domain"));
             goto endjob;
         }
-    }

-    if (flags& VIR_DOMAIN_MEM_CONFIG) {
-        persistentDef->mem.cur_balloon = newmem;
-        ret = virDomainSaveConfig(driver->configDir, persistentDef);
-        goto endjob;
+        if (flags & VIR_DOMAIN_MEM_CONFIG) {
+            persistentDef->mem.max_balloon = newmem;
+            if (persistentDef->mem.cur_balloon > newmem)
+                persistentDef->mem.cur_balloon = newmem;
+            ret = virDomainSaveConfig(driver->configDir, persistentDef);
+            goto endjob;
+        }
+
+    } else {
+        /* resize the current memory */
+
+        if (newmem > vm->def->mem.max_balloon) {
+            qemuReportError(VIR_ERR_INVALID_ARG,
+                            "%s", _("cannot set memory higher than max 
memory"));
+            goto endjob;
+        }
+
+        if (flags & VIR_DOMAIN_MEM_LIVE) {
+            priv = vm->privateData;
+            qemuDomainObjEnterMonitor(vm);
+            r = qemuMonitorSetBalloon(priv->mon, newmem);
+            qemuDomainObjExitMonitor(vm);
+            qemuAuditMemory(vm, vm->def->mem.cur_balloon, newmem, "update", r 
== 1);
+            if (r < 0)
+                goto endjob;
+
+            /* Lack of balloon support is a fatal error */
+            if (r == 0) {
+                qemuReportError(VIR_ERR_OPERATION_INVALID,
+                                "%s", _("cannot set memory of an active 
domain"));
+                goto endjob;
+            }
+        }
+
+        if (flags & VIR_DOMAIN_MEM_CONFIG) {
+            persistentDef->mem.cur_balloon = newmem;
+            ret = virDomainSaveConfig(driver->configDir, persistentDef);
+            goto endjob;
+        }
     }

     ret = 0;
@@ -1663,6 +1695,11 @@ static int qemudDomainSetMemory(virDomai
     return qemudDomainSetMemoryFlags(dom, newmem, VIR_DOMAIN_MEM_LIVE);
 }

+static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long memory) {
+    return qemudDomainSetMemoryFlags(dom, memory,
+                                     VIR_DOMAIN_MEM_MAXIMUM | 
VIR_DOMAIN_MEM_LIVE);
+}
+
 static int qemudDomainGetInfo(virDomainPtr dom,
                               virDomainInfoPtr info) {
     struct qemud_driver *driver = dom->conn->privateData;
@@ -6843,7 +6880,7 @@ static virDriver qemuDriver = {
     qemudDomainDestroy, /* domainDestroy */
     qemudDomainGetOSType, /* domainGetOSType */
     qemudDomainGetMaxMemory, /* domainGetMaxMemory */
-    NULL, /* domainSetMaxMemory */
+    qemudDomainSetMaxMemory, /* domainSetMaxMemory */
     qemudDomainSetMemory, /* domainSetMemory */
     qemudDomainSetMemoryFlags, /* domainSetMemoryFlags */
     qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to