[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/3] maxmem: implement virDomainSetMaxMemory API of the qemu driver



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 taku jp fujitsu com>
---
 src/qemu/qemu_driver.c |   81 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 57 insertions(+), 24 deletions(-)

Index: libvirt/src/qemu/qemu_driver.c
===================================================================
--- libvirt.orig/src/qemu/qemu_driver.c
+++ libvirt/src/qemu/qemu_driver.c
@@ -1580,7 +1580,8 @@ static int qemudDomainSetMemoryFlags(vir
     bool 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);
@@ -1593,12 +1594,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;
 
@@ -1610,6 +1605,12 @@ static int qemudDomainSetMemoryFlags(vir
         else
             flags = VIR_DOMAIN_MEM_CONFIG;
     }
+    if (flags == VIR_DOMAIN_MEM_MAXIMUM) {
+        if (isActive)
+            flags = VIR_DOMAIN_MEM_LIVE | VIR_DOMAIN_MEM_MAXIMUM;
+        else
+            flags = VIR_DOMAIN_MEM_CONFIG | VIR_DOMAIN_MEM_MAXIMUM;
+    }
 
     if (!isActive && (flags & VIR_DOMAIN_MEM_LIVE)) {
         qemuReportError(VIR_ERR_OPERATION_INVALID,
@@ -1627,27 +1628,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;
@@ -1665,6 +1693,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;
@@ -6849,7 +6882,7 @@ static virDriver qemuDriver = {
     qemudDomainDestroy, /* domainDestroy */
     qemudDomainGetOSType, /* domainGetOSType */
     qemudDomainGetMaxMemory, /* domainGetMaxMemory */
-    NULL, /* domainSetMaxMemory */
+    qemudDomainSetMaxMemory, /* domainSetMaxMemory */
     qemudDomainSetMemory, /* domainSetMemory */
     qemudDomainSetMemoryFlags, /* domainSetMemoryFlags */
     qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]