]> xenbits.xensource.com Git - libvirt.git/commitdiff
maxmem: implement virDomainSetMaxMemory API of the qemu driver
authorTaku Izumi <izumi.taku@jp.fujitsu.com>
Fri, 8 Apr 2011 05:08:13 +0000 (14:08 +0900)
committerEric Blake <eblake@redhat.com>
Fri, 8 Apr 2011 23:40:29 +0000 (17:40 -0600)
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/libvirt.c
src/qemu/qemu_driver.c

index 4a396955bac6f1e5905989bbed8504e0d6701893..0da98859fc6037bdc6bfa9b97188721a176aeb38 100644 (file)
@@ -2714,8 +2714,9 @@ error:
  * to Domain0 i.e. the domain where the application runs.
  * This function requires privileged access to the hypervisor.
  *
- * This command only changes the runtime configuration of the domain,
- * so can only be called on an active domain.
+ * This command is hypervisor-specific for whether active, persistent,
+ * or both configurations are changed; for more control, use
+ * virDomainSetMemoryFlags().
  *
  * Returns 0 in case of success and -1 in case of failure.
  */
index a4b56a72659efd28803d68735fbff9e1529dc29f..04a5f6557e0bb6032edc7daedd8e3acaddfb0326 100644 (file)
@@ -1580,7 +1580,8 @@ static int qemudDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     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(virDomainPtr dom, unsigned long newmem,
         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(virDomainPtr dom, unsigned long newmem,
         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,56 @@ static int qemudDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
             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)
+    if (flags & VIR_DOMAIN_MEM_MAXIMUM) {
+        /* resize the maximum memory */
+
+        if (flags & VIR_DOMAIN_MEM_LIVE) {
+            qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                            _("cannot resize the maximum memory on an "
+                              "active domain"));
             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"));
+        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;
         }
-    }
 
-    if (flags& VIR_DOMAIN_MEM_CONFIG) {
-        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;
@@ -1661,12 +1691,19 @@ cleanup:
     return ret;
 }
 
-static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem) {
+static int qemudDomainSetMemory(virDomainPtr dom, unsigned long newmem)
+{
     return qemudDomainSetMemoryFlags(dom, newmem, VIR_DOMAIN_MEM_LIVE);
 }
 
+static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long memory)
+{
+    return qemudDomainSetMemoryFlags(dom, memory, VIR_DOMAIN_MEM_MAXIMUM);
+}
+
 static int qemudDomainGetInfo(virDomainPtr dom,
-                              virDomainInfoPtr info) {
+                              virDomainInfoPtr info)
+{
     struct qemud_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
@@ -6849,7 +6886,7 @@ static virDriver qemuDriver = {
     qemudDomainDestroy, /* domainDestroy */
     qemudDomainGetOSType, /* domainGetOSType */
     qemudDomainGetMaxMemory, /* domainGetMaxMemory */
-    NULL, /* domainSetMaxMemory */
+    qemudDomainSetMaxMemory, /* domainSetMaxMemory */
     qemudDomainSetMemory, /* domainSetMemory */
     qemudDomainSetMemoryFlags, /* domainSetMemoryFlags */
     qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */