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:
parent
641a145d73
commit
eaf4320869
@ -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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user