[libvirt] [PATCH 0/3] Few more memory hotplug related fixes

Peter Krempa (3): conf: Always truncate balloon size to maximum memory size conf: Fix up balloon size after removing a memory device from def qemu: Fix balloon size handling with memory hot(un)plug src/conf/domain_conf.c | 27 +++++++-------------------- src/qemu/qemu_driver.c | 3 +++ src/qemu/qemu_hotplug.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-) -- 2.3.5

Specifying a balloon size more than the memory size of a guest isn't something that should be rejected when parsing the XML. Truncate the size to the maximum memory size. --- src/conf/domain_conf.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5f74ab1..d397bca 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3364,27 +3364,9 @@ virDomainDefPostParseInternal(virDomainDefPtr def, return -1; } - if (def->mem.cur_balloon > virDomainDefGetMemoryActual(def)) { - /* Older libvirt could get into this situation due to - * rounding; if the discrepancy is less than 4MiB, we silently - * round down, otherwise we flag the issue. */ - if (VIR_DIV_UP(def->mem.cur_balloon, 4096) > - VIR_DIV_UP(virDomainDefGetMemoryActual(def), 4096)) { - virReportError(VIR_ERR_XML_ERROR, - _("current memory '%lluk' exceeds " - "maximum '%lluk'"), - def->mem.cur_balloon, - virDomainDefGetMemoryActual(def)); - return -1; - } else { - VIR_DEBUG("Truncating current %lluk to maximum %lluk", - def->mem.cur_balloon, - virDomainDefGetMemoryActual(def)); - def->mem.cur_balloon = virDomainDefGetMemoryActual(def); - } - } else if (def->mem.cur_balloon == 0) { + if (def->mem.cur_balloon > virDomainDefGetMemoryActual(def) || + def->mem.cur_balloon == 0) def->mem.cur_balloon = virDomainDefGetMemoryActual(def); - } if ((def->mem.max_memory || def->mem.memory_slots) && !(def->mem.max_memory && def->mem.memory_slots)) { -- 2.3.5

To avoid having the ballooned memory size larger than the actual physical memory size, truncate the ballooned size if it overflows. --- src/conf/domain_conf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d397bca..3a1782e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -12986,6 +12986,11 @@ virDomainMemoryRemove(virDomainDefPtr def, { virDomainMemoryDefPtr ret = def->mems[idx]; VIR_DELETE_ELEMENT(def->mems, idx, def->nmems); + + /* fix up balloon size */ + if (def->mem.cur_balloon > virDomainDefGetMemoryActual(def)) + def->mem.cur_balloon = virDomainDefGetMemoryActual(def); + return ret; } -- 2.3.5

Since libvirt doesn't call to update the new balloon size in qemu add code that will handle tweaking of the size of the current balloon statistic until qemu reports the new size using the event. --- src/qemu/qemu_driver.c | 3 +++ src/qemu/qemu_hotplug.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d6e7570..187145a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -8379,6 +8379,9 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps, return -1; } + if (vmdef->mem.cur_balloon == virDomainDefGetMemoryActual(vmdef)) + vmdef->mem.cur_balloon += dev->data.memory->size; + if (virDomainMemoryInsert(vmdef, dev->data.memory) < 0) return -1; dev->data.memory = NULL; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 613b728..c3b3efb 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1727,6 +1727,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, const char *backendType; virJSONValuePtr props = NULL; virObjectEventPtr event; + bool fix_balloon = false; int id; int ret = -1; @@ -1742,6 +1743,9 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, if (virAsprintf(&objalias, "mem%s", mem->info.alias) < 0) goto cleanup; + if (vm->def->mem.cur_balloon == virDomainDefGetMemoryActual(vm->def)) + fix_balloon = true; + if (!(devstr = qemuBuildMemoryDeviceStr(mem, vm->def, priv->qemuCaps))) goto cleanup; @@ -1780,6 +1784,10 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, if (event) qemuDomainEventQueue(driver, event); + /* fix the balloon size if it was set to maximum */ + if (fix_balloon) + vm->def->mem.cur_balloon += mem->size; + /* mem is consumed by vm->def */ mem = NULL; @@ -2897,6 +2905,8 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver, if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) goto error; + vm->def->mem.cur_balloon -= mem->size; + if ((idx = virDomainMemoryFindByDef(vm->def, mem)) >= 0) virDomainMemoryRemove(vm->def, idx); -- 2.3.5

On 30.04.2015 18:20, Peter Krempa wrote:
Peter Krempa (3): conf: Always truncate balloon size to maximum memory size conf: Fix up balloon size after removing a memory device from def qemu: Fix balloon size handling with memory hot(un)plug
src/conf/domain_conf.c | 27 +++++++-------------------- src/qemu/qemu_driver.c | 3 +++ src/qemu/qemu_hotplug.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-)
ACK series Michal

On Tue, May 05, 2015 at 14:23:00 +0200, Michal Privoznik wrote:
On 30.04.2015 18:20, Peter Krempa wrote:
Peter Krempa (3): conf: Always truncate balloon size to maximum memory size conf: Fix up balloon size after removing a memory device from def qemu: Fix balloon size handling with memory hot(un)plug
src/conf/domain_conf.c | 27 +++++++-------------------- src/qemu/qemu_driver.c | 3 +++ src/qemu/qemu_hotplug.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-)
ACK series
Pushed; Thanks. Peter
participants (2)
-
Michal Privoznik
-
Peter Krempa