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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list