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