提交 eaf43208 编写于 作者: P Peter Krempa

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.
上级 641a145d
...@@ -3196,3 +3196,69 @@ qemuDomainMachineIsI440FX(const virDomainDef *def) ...@@ -3196,3 +3196,69 @@ qemuDomainMachineIsI440FX(const virDomainDef *def)
STRPREFIX(def->os.machine, "pc-i440") || STRPREFIX(def->os.machine, "pc-i440") ||
STRPREFIX(def->os.machine, "rhel")); 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); ...@@ -466,4 +466,7 @@ virDomainChrSourceDefPtr qemuFindAgentConfig(virDomainDefPtr def);
bool qemuDomainMachineIsQ35(const virDomainDef *def); bool qemuDomainMachineIsQ35(const virDomainDef *def);
bool qemuDomainMachineIsI440FX(const virDomainDef *def); bool qemuDomainMachineIsI440FX(const virDomainDef *def);
int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
virDomainObjPtr vm);
#endif /* __QEMU_DOMAIN_H__ */ #endif /* __QEMU_DOMAIN_H__ */
...@@ -2617,8 +2617,6 @@ static int qemuDomainGetInfo(virDomainPtr dom, ...@@ -2617,8 +2617,6 @@ static int qemuDomainGetInfo(virDomainPtr dom,
virQEMUDriverPtr driver = dom->conn->privateData; virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
int ret = -1; int ret = -1;
int err;
unsigned long long balloon;
if (!(vm = qemuDomObjFromDomain(dom))) if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup; goto cleanup;
...@@ -2641,43 +2639,10 @@ static int qemuDomainGetInfo(virDomainPtr dom, ...@@ -2641,43 +2639,10 @@ static int qemuDomainGetInfo(virDomainPtr dom,
info->maxMem = virDomainDefGetMemoryActual(vm->def); info->maxMem = virDomainDefGetMemoryActual(vm->def);
if (virDomainObjIsActive(vm)) { if (virDomainObjIsActive(vm)) {
qemuDomainObjPrivatePtr priv = vm->privateData; if (qemuDomainUpdateCurrentMemorySize(driver, vm) < 0)
goto cleanup;
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 (err < 0) { info->memory = vm->def->mem.cur_balloon;
/* 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 { } else {
info->memory = 0; info->memory = 0;
} }
...@@ -7172,57 +7137,24 @@ qemuDomainObjRestore(virConnectPtr conn, ...@@ -7172,57 +7137,24 @@ qemuDomainObjRestore(virConnectPtr conn,
} }
static char *qemuDomainGetXMLDesc(virDomainPtr dom, static char
unsigned int flags) *qemuDomainGetXMLDesc(virDomainPtr dom,
unsigned int flags)
{ {
virQEMUDriverPtr driver = dom->conn->privateData; virQEMUDriverPtr driver = dom->conn->privateData;
virDomainObjPtr vm; virDomainObjPtr vm;
char *ret = NULL; char *ret = NULL;
unsigned long long balloon;
int err = 0;
qemuDomainObjPrivatePtr priv;
/* Flags checked by virDomainDefFormat */ /* Flags checked by virDomainDefFormat */
if (!(vm = qemuDomObjFromDomain(dom))) if (!(vm = qemuDomObjFromDomain(dom)))
goto cleanup; goto cleanup;
priv = vm->privateData;
if (virDomainGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0) if (virDomainGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0)
goto cleanup; goto cleanup;
/* Refresh current memory based on balloon info if supported */ if (qemuDomainUpdateCurrentMemorySize(driver, vm) < 0)
if ((vm->def->memballoon != NULL) && goto cleanup;
(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 ((flags & VIR_DOMAIN_XML_MIGRATABLE)) if ((flags & VIR_DOMAIN_XML_MIGRATABLE))
flags |= QEMU_DOMAIN_FORMAT_LIVE_FLAGS; flags |= QEMU_DOMAIN_FORMAT_LIVE_FLAGS;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册