On Fri, Apr 23, 2021 at 15:24:33 +0200, Michal Privoznik wrote:
The qemuDomainSetMemoryFlags() allows for memballoon
(<currentMemory/>) changes for both active and inactive guests.
And just before doing any change, we have to make sure that the
new size is not greater than the total memory (<memory/>).
However, the total memory includes not only the regular guest
memory, but also sum of maximum sizes of all virtio-mems (in fact
all memory devices for that matter). But virtio-mem devices are
modified differently (via virDomainUpdateDevice()) and thus the
upper limit for new balloon size has to be lowered.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e376a64bee..6a9da62ded 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2433,12 +2433,28 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned
long newmem,
} else {
/* resize the current memory */
unsigned long oldmax = 0;
+ size_t i;
- if (def)
+ if (def) {
oldmax = virDomainDefGetMemoryTotal(def);
+
+ /* While virtio-mem is regular mem from guest POV, it can't be
+ * modified through this API. */
+ for (i = 0; i < def->nmems; i++) {
+ if (def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM)
+ oldmax -= def->mems[i]->size;
+ }
+ }
+
if (persistentDef) {
- if (!oldmax || oldmax > virDomainDefGetMemoryTotal(persistentDef))
+ if (!oldmax || oldmax > virDomainDefGetMemoryTotal(persistentDef)) {
IMO this code will not be correct any more when you do the subtraction
of virtio-mem devices above as you compare it with the total memory of
the persistent def.