1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-01-12 13:17:58 +03:00

qemu: Add helper to update domain balloon size and refactor usage places

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.
This commit is contained in:
Peter Krempa 2015-05-27 15:51:52 +02:00
parent 641a145d73
commit eaf4320869
3 changed files with 77 additions and 76 deletions

View 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;
}

View 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__ */

View 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)
if (qemuDomainUpdateCurrentMemorySize(driver, vm) < 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 (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;
}
} else {
info->memory = 0;
}
@ -7172,58 +7137,25 @@ qemuDomainObjRestore(virConnectPtr conn,
}
static char *qemuDomainGetXMLDesc(virDomainPtr dom,
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)
if (qemuDomainUpdateCurrentMemorySize(driver, vm) < 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 ((flags & VIR_DOMAIN_XML_MIGRATABLE))
flags |= QEMU_DOMAIN_FORMAT_LIVE_FLAGS;