Reporting how much memory is exposed to the guest happens under
<currentMemory/> which is taken from def->mem.cur_balloon. The
reported amount should account for both balloon size and the sum
of @actualsize of all virtio-mems. For instance, if domain has
4GiB via balloon and additional 2GiB via virtio-mem, then the
domain XML should report 6GiB. The same applies for domain
statistics.
The way to achieve this is to account for either balloon or
virtio-mem when the size of the other is changed, e.g. on balloon
change we have to add all @actualsize (for non virtio-mem these
will be zero, so the check for memory model is needless, but
makes it more obvious what's happening), and vice versa.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 4 ++++
src/qemu/qemu_process.c | 17 +++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6bcbc75fbc..d5891e32c3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4323,6 +4323,7 @@ processMemoryDeviceSizeChange(virQEMUDriverPtr driver,
{
virDomainMemoryDefPtr mem = NULL;
virObjectEventPtr event = NULL;
+ unsigned long long balloon;
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
return;
@@ -4338,7 +4339,10 @@ processMemoryDeviceSizeChange(virQEMUDriverPtr driver,
goto endjob;
}
+ balloon = vm->def->mem.cur_balloon - mem->actualsize;
mem->actualsize = VIR_DIV_UP(info->size, 1024);
+ balloon += mem->actualsize;
+ vm->def->mem.cur_balloon = balloon;
event = virDomainEventMemoryDeviceSizeChangeNewFromObj(vm,
info->devAlias,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dc301371ef..f6da5afb48 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1253,10 +1253,19 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon G_GNUC_UNUSED,
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
+ size_t i;
virObjectLock(vm);
event = virDomainEventBalloonChangeNewFromObj(vm, actual);
+ /* We want the balloon size stored in domain definition to account for the
+ * actual size of virtio-mem too. */
+ VIR_DEBUG("balloon size before fix is %lld", actual);
+ for (i = 0; i < vm->def->nmems; i++) {
+ if (vm->def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM)
+ actual += vm->def->mems[i]->actualsize;
+ }
+
VIR_DEBUG("Updating balloon from %lld to %lld kb",
vm->def->mem.cur_balloon, actual);
vm->def->mem.cur_balloon = actual;
@@ -2451,6 +2460,7 @@ qemuProcessRefreshBalloonState(virQEMUDriverPtr driver,
int asyncJob)
{
unsigned long long balloon;
+ size_t i;
int rc;
/* if no ballooning is available, the current size equals to the current
@@ -2467,6 +2477,13 @@ qemuProcessRefreshBalloonState(virQEMUDriverPtr driver,
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
return -1;
+ /* We want the balloon size stored in domain definition to account for the
+ * actual size of virtio-mem too. */
+ VIR_DEBUG("balloon size before fix is %lld", balloon);
+ for (i = 0; i < vm->def->nmems; i++) {
+ if (vm->def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM)
+ balloon += vm->def->mems[i]->actualsize;
+ }
vm->def->mem.cur_balloon = balloon;
return 0;
--
2.26.2