This patch implements the code to support virDomainSetMaxMemory API,
and to support VIR_DOMAIN_MEM_MAXIMUM flag in qemudDomainSetMemoryFlags function.
As a result, we can change the maximum memory size of inactive QEMU guests.
Signed-off-by: Taku Izumi <izumi.taku(a)jp.fujitsu.com>
---
src/qemu/qemu_driver.c | 85 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 61 insertions(+), 24 deletions(-)
Index: libvirt/src/qemu/qemu_driver.c
===================================================================
--- libvirt.orig/src/qemu/qemu_driver.c
+++ libvirt/src/qemu/qemu_driver.c
@@ -1578,7 +1578,9 @@ static int qemudDomainSetMemoryFlags(vir
int ret = -1, r, isActive;
virCheckFlags(VIR_DOMAIN_MEM_LIVE |
- VIR_DOMAIN_MEM_CONFIG, -1);
+ VIR_DOMAIN_MEM_CONFIG |
+ VIR_DOMAIN_MEM_MAXIMUM, -1);
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1591,12 +1593,6 @@ static int qemudDomainSetMemoryFlags(vir
goto cleanup;
}
- if (newmem > vm->def->mem.max_balloon) {
- qemuReportError(VIR_ERR_INVALID_ARG,
- "%s", _("cannot set memory higher than max
memory"));
- goto cleanup;
- }
-
if (qemuDomainObjBeginJob(vm) < 0)
goto cleanup;
@@ -1608,6 +1604,15 @@ static int qemudDomainSetMemoryFlags(vir
else
flags = VIR_DOMAIN_MEM_CONFIG;
}
+ if (flags == VIR_DOMAIN_MEM_MAXIMUM) {
+ if (isActive) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ _("cannot resize the maximum memory on an active
domain"));
+ goto endjob;
+ } else {
+ flags = VIR_DOMAIN_MEM_CONFIG | VIR_DOMAIN_MEM_MAXIMUM;
+ }
+ }
if (!isActive && (flags & VIR_DOMAIN_MEM_LIVE)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
@@ -1625,27 +1630,54 @@ static int qemudDomainSetMemoryFlags(vir
goto endjob;
}
- if (flags & VIR_DOMAIN_MEM_LIVE) {
- priv = vm->privateData;
- qemuDomainObjEnterMonitor(vm);
- r = qemuMonitorSetBalloon(priv->mon, newmem);
- qemuDomainObjExitMonitor(vm);
- qemuAuditMemory(vm, vm->def->mem.cur_balloon, newmem, "update", r
== 1);
- if (r < 0)
- goto endjob;
+ if (flags & VIR_DOMAIN_MEM_MAXIMUM) {
+ /* resize the maximum memory */
- /* Lack of balloon support is a fatal error */
- if (r == 0) {
+ if (flags & VIR_DOMAIN_MEM_LIVE) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cannot set memory of an active
domain"));
+ _("cannot resize the maximum memory on an active
domain"));
goto endjob;
}
- }
- if (flags& VIR_DOMAIN_MEM_CONFIG) {
- persistentDef->mem.cur_balloon = newmem;
- ret = virDomainSaveConfig(driver->configDir, persistentDef);
- goto endjob;
+ if (flags & VIR_DOMAIN_MEM_CONFIG) {
+ persistentDef->mem.max_balloon = newmem;
+ if (persistentDef->mem.cur_balloon > newmem)
+ persistentDef->mem.cur_balloon = newmem;
+ ret = virDomainSaveConfig(driver->configDir, persistentDef);
+ goto endjob;
+ }
+
+ } else {
+ /* resize the current memory */
+
+ if (newmem > vm->def->mem.max_balloon) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ "%s", _("cannot set memory higher than max
memory"));
+ goto endjob;
+ }
+
+ if (flags & VIR_DOMAIN_MEM_LIVE) {
+ priv = vm->privateData;
+ qemuDomainObjEnterMonitor(vm);
+ r = qemuMonitorSetBalloon(priv->mon, newmem);
+ qemuDomainObjExitMonitor(vm);
+ qemuAuditMemory(vm, vm->def->mem.cur_balloon, newmem,
"update", r == 1);
+ if (r < 0)
+ goto endjob;
+
+ /* Lack of balloon support is a fatal error */
+ if (r == 0) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("cannot set memory of an active
domain"));
+ goto endjob;
+ }
+ }
+
+ if (flags & VIR_DOMAIN_MEM_CONFIG) {
+ persistentDef->mem.cur_balloon = newmem;
+ ret = virDomainSaveConfig(driver->configDir, persistentDef);
+ goto endjob;
+ }
}
ret = 0;
@@ -1663,6 +1695,11 @@ static int qemudDomainSetMemory(virDomai
return qemudDomainSetMemoryFlags(dom, newmem, VIR_DOMAIN_MEM_LIVE);
}
+static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long memory) {
+ return qemudDomainSetMemoryFlags(dom, memory,
+ VIR_DOMAIN_MEM_MAXIMUM | VIR_DOMAIN_MEM_LIVE);
+}
+
static int qemudDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr info) {
struct qemud_driver *driver = dom->conn->privateData;
@@ -6843,7 +6880,7 @@ static virDriver qemuDriver = {
qemudDomainDestroy, /* domainDestroy */
qemudDomainGetOSType, /* domainGetOSType */
qemudDomainGetMaxMemory, /* domainGetMaxMemory */
- NULL, /* domainSetMaxMemory */
+ qemudDomainSetMaxMemory, /* domainSetMaxMemory */
qemudDomainSetMemory, /* domainSetMemory */
qemudDomainSetMemoryFlags, /* domainSetMemoryFlags */
qemuDomainSetMemoryParameters, /* domainSetMemoryParameters */