[libvirt] [PATCH 16/35] qemu: Add helper to update domain balloon size and refactor usage places

Peter Krempa pkrempa at redhat.com
Fri May 29 13:33:37 UTC 2015


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 | 64 ++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h |  3 ++
 src/qemu/qemu_driver.c | 84 +++++---------------------------------------------
 3 files changed, 75 insertions(+), 76 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index db8554b..661181f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3182,3 +3182,67 @@ 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;
+    }
+
+    return 0;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index a6df199..053607f 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -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__ */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f32b87e..1ff4237 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2618,8 +2618,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;
@@ -2642,43 +2640,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;
     }
@@ -7173,57 +7138,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;
-- 
2.4.1




More information about the libvir-list mailing list