]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: Add helper to update domain balloon size and refactor usage places
authorPeter Krempa <pkrempa@redhat.com>
Wed, 27 May 2015 13:51:52 +0000 (15:51 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 4 Jun 2015 08:52:30 +0000 (10:52 +0200)
When qemu does not support the balloon event the current memory size
needs to be queried. Since there are two places that implement the same
logic, split it out into a function and reuse.

src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_driver.c

index 12a1d97889397b306eca629b05433a7efc2e0597..3826b2fce3b8d6e3702c3a6eb0790af290462bca 100644 (file)
@@ -3196,3 +3196,69 @@ qemuDomainMachineIsI440FX(const virDomainDef *def)
             STRPREFIX(def->os.machine, "pc-i440") ||
             STRPREFIX(def->os.machine, "rhel"));
 }
+
+
+/**
+ * qemuDomainUpdateCurrentMemorySize:
+ *
+ * Updates the current balloon size from the monitor if necessary. In case when
+ * the balloon is not present for the domain, the function recalculates the
+ * maximum size to reflect possible changes.
+ *
+ * Returns 0 on success and updates vm->def->mem.cur_balloon if necessary, -1 on
+ * error and reports libvirt error.
+ */
+int
+qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
+                                  virDomainObjPtr vm)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    unsigned long long balloon;
+    int ret = -1;
+
+    /* inactive domain doesn't need size update */
+    if (!virDomainObjIsActive(vm))
+        return 0;
+
+    /* if no balloning is available, the current size equals to the current
+     * full memory size */
+    if (!vm->def->memballoon ||
+        vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE) {
+        vm->def->mem.cur_balloon = virDomainDefGetMemoryActual(vm->def);
+        return 0;
+    }
+
+    /* current size is always automagically updated via the event */
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BALLOON_EVENT))
+        return 0;
+
+    /* here we need to ask the monitor */
+
+    /* Don't delay if someone's using the monitor, just use existing most
+     * recent data instead */
+    if (qemuDomainJobAllowed(priv, QEMU_JOB_QUERY)) {
+        if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
+            return -1;
+
+        if (!virDomainObjIsActive(vm)) {
+            virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                           _("domain is not running"));
+            goto endjob;
+        }
+
+        qemuDomainObjEnterMonitor(driver, vm);
+        ret = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
+        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            ret = -1;
+
+ endjob:
+        qemuDomainObjEndJob(driver, vm);
+
+        if (ret < 0)
+            return -1;
+    }
+
+    vm->def->mem.cur_balloon = balloon;
+
+    return 0;
+}
index a6df199bee3a768167396da7867f59dbc8d68ef7..053607fe00d9bda4977753524edd64d50cb7c9f6 100644 (file)
@@ -466,4 +466,7 @@ virDomainChrSourceDefPtr qemuFindAgentConfig(virDomainDefPtr def);
 bool qemuDomainMachineIsQ35(const virDomainDef *def);
 bool qemuDomainMachineIsI440FX(const virDomainDef *def);
 
+int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
+                                      virDomainObjPtr vm);
+
 #endif /* __QEMU_DOMAIN_H__ */
index 84e05683ffbedff24b73dd2b4782752a9601e2e0..9671f3a45e12a71d38538ab45afc66909c2443f9 100644 (file)
@@ -2617,8 +2617,6 @@ static int qemuDomainGetInfo(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
-    int err;
-    unsigned long long balloon;
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
@@ -2641,43 +2639,10 @@ static int qemuDomainGetInfo(virDomainPtr dom,
     info->maxMem = virDomainDefGetMemoryActual(vm->def);
 
     if (virDomainObjIsActive(vm)) {
-        qemuDomainObjPrivatePtr priv = vm->privateData;
-
-        if ((vm->def->memballoon != NULL) &&
-            (vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_NONE)) {
-            info->memory = virDomainDefGetMemoryActual(vm->def);
-        } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BALLOON_EVENT)) {
-            info->memory = vm->def->mem.cur_balloon;
-        } else if (qemuDomainJobAllowed(priv, QEMU_JOB_QUERY)) {
-            if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
-                goto cleanup;
-            if (!virDomainObjIsActive(vm)) {
-                err = 0;
-            } else {
-                qemuDomainObjEnterMonitor(driver, vm);
-                err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
-                if (qemuDomainObjExitMonitor(driver, vm) < 0) {
-                    qemuDomainObjEndJob(driver, vm);
-                    goto cleanup;
-                }
-            }
-            qemuDomainObjEndJob(driver, vm);
+        if (qemuDomainUpdateCurrentMemorySize(driver, vm) < 0)
+            goto cleanup;
 
-            if (err < 0) {
-                /* We couldn't get current memory allocation but that's not
-                 * a show stopper; we wouldn't get it if there was a job
-                 * active either
-                 */
-                info->memory = vm->def->mem.cur_balloon;
-            } else if (err == 0) {
-                /* Balloon not supported, so maxmem is always the allocation */
-                info->memory = virDomainDefGetMemoryActual(vm->def);
-            } else {
-                info->memory = balloon;
-            }
-        } else {
-            info->memory = vm->def->mem.cur_balloon;
-        }
+        info->memory = vm->def->mem.cur_balloon;
     } else {
         info->memory = 0;
     }
@@ -7172,57 +7137,24 @@ qemuDomainObjRestore(virConnectPtr conn,
 }
 
 
-static char *qemuDomainGetXMLDesc(virDomainPtr dom,
-                                  unsigned int flags)
+static char
+*qemuDomainGetXMLDesc(virDomainPtr dom,
+                      unsigned int flags)
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     char *ret = NULL;
-    unsigned long long balloon;
-    int err = 0;
-    qemuDomainObjPrivatePtr priv;
 
     /* Flags checked by virDomainDefFormat */
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         goto cleanup;
 
-    priv = vm->privateData;
-
     if (virDomainGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0)
         goto cleanup;
 
-    /* Refresh current memory based on balloon info if supported */
-    if ((vm->def->memballoon != NULL) &&
-        (vm->def->memballoon->model != VIR_DOMAIN_MEMBALLOON_MODEL_NONE) &&
-        !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BALLOON_EVENT) &&
-        (virDomainObjIsActive(vm))) {
-        /* Don't delay if someone's using the monitor, just use
-         * existing most recent data instead */
-        if (qemuDomainJobAllowed(priv, QEMU_JOB_QUERY)) {
-            if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
-                goto cleanup;
-
-            if (!virDomainObjIsActive(vm)) {
-                virReportError(VIR_ERR_OPERATION_INVALID,
-                               "%s", _("domain is not running"));
-                goto endjob;
-            }
-
-            qemuDomainObjEnterMonitor(driver, vm);
-            err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
-                err = -1;
-
- endjob:
-            qemuDomainObjEndJob(driver, vm);
-            if (err < 0)
-                goto cleanup;
-            if (err > 0)
-                vm->def->mem.cur_balloon = balloon;
-            /* err == 0 indicates no balloon support, so ignore it */
-        }
-    }
+    if (qemuDomainUpdateCurrentMemorySize(driver, vm) < 0)
+        goto cleanup;
 
     if ((flags & VIR_DOMAIN_XML_MIGRATABLE))
         flags |= QEMU_DOMAIN_FORMAT_LIVE_FLAGS;