---
src/qemu/qemu_driver.c | 106 +++++++++++++++++++++++++++++++++++-------------
1 files changed, 77 insertions(+), 29 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f04e443..9057a83 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4812,20 +4812,20 @@ cleanup:
static int qemuDomainSetMemoryParameters(virDomainPtr dom,
virMemoryParameterPtr params,
int nparams,
- unsigned int flags ATTRIBUTE_UNUSED)
+ unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
int i;
+ virDomainDefPtr persistentDef = NULL;
virCgroupPtr group = NULL;
virDomainObjPtr vm = NULL;
int ret = -1;
+ bool isActive;
+
+ virCheckFlags(VIR_DOMAIN_MEMORY_PARAM_LIVE |
+ VIR_DOMAIN_MEMORY_PARAM_CONFIG, -1);
qemuDriverLock(driver);
- if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cgroup memory controller is not
mounted"));
- goto cleanup;
- }
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -4835,16 +4835,43 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
goto cleanup;
}
- if (!virDomainObjIsActive(vm)) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("domain is not running"));
- goto cleanup;
+ isActive = virDomainObjIsActive(vm);
+
+ if (flags == VIR_DOMAIN_MEMORY_PARAM_CURRENT) {
+ if (isActive)
+ flags = VIR_DOMAIN_MEMORY_PARAM_LIVE;
+ else
+ flags = VIR_DOMAIN_MEMORY_PARAM_CONFIG;
}
- if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0)
{
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot find cgroup for domain %s"),
vm->def->name);
- goto cleanup;
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_LIVE) {
+ if (!isActive) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("cgroup memory controller is not
mounted"));
+ goto cleanup;
+ }
+
+ if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) !=
0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot find cgroup for domain %s"),
vm->def->name);
+ goto cleanup;
+ }
+ }
+
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_CONFIG) {
+ if (!vm->persistent) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot change persistent config of a transient
domain"));
+ goto cleanup;
+ }
+ if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
+ goto cleanup;
}
ret = 0;
@@ -4860,11 +4887,17 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
continue;
}
- rc = virCgroupSetMemoryHardLimit(group, params[i].value.ul);
- if (rc != 0) {
- virReportSystemError(-rc, "%s",
- _("unable to set memory hard_limit
tunable"));
- ret = -1;
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_LIVE) {
+ rc = virCgroupSetMemoryHardLimit(group, params[i].value.ul);
+ if (rc != 0) {
+ virReportSystemError(-rc, "%s",
+ _("unable to set memory hard_limit
tunable"));
+ ret = -1;
+ }
+ }
+
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_CONFIG) {
+ persistentDef->mem.hard_limit = params[i].value.ul;
}
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
int rc;
@@ -4875,11 +4908,17 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
continue;
}
- rc = virCgroupSetMemorySoftLimit(group, params[i].value.ul);
- if (rc != 0) {
- virReportSystemError(-rc, "%s",
- _("unable to set memory soft_limit
tunable"));
- ret = -1;
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_LIVE) {
+ rc = virCgroupSetMemorySoftLimit(group, params[i].value.ul);
+ if (rc != 0) {
+ virReportSystemError(-rc, "%s",
+ _("unable to set memory soft_limit
tunable"));
+ ret = -1;
+ }
+ }
+
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_CONFIG) {
+ persistentDef->mem.soft_limit = params[i].value.ul;
}
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
int rc;
@@ -4890,11 +4929,16 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
continue;
}
- rc = virCgroupSetMemSwapHardLimit(group, params[i].value.ul);
- if (rc != 0) {
- virReportSystemError(-rc, "%s",
- _("unable to set swap_hard_limit
tunable"));
- ret = -1;
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_LIVE) {
+ rc = virCgroupSetMemSwapHardLimit(group, params[i].value.ul);
+ if (rc != 0) {
+ virReportSystemError(-rc, "%s",
+ _("unable to set swap_hard_limit
tunable"));
+ ret = -1;
+ }
+ }
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_CONFIG) {
+ persistentDef->mem.swap_hard_limit = params[i].value.ul;
}
} else if (STREQ(param->field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) {
qemuReportError(VIR_ERR_INVALID_ARG,
@@ -4907,6 +4951,10 @@ static int qemuDomainSetMemoryParameters(virDomainPtr dom,
}
}
+ if (flags & VIR_DOMAIN_MEMORY_PARAM_CONFIG) {
+ ret = virDomainSaveConfig(driver->configDir, persistentDef);
+ }
+
cleanup:
virCgroupFree(&group);
if (vm)
--
1.7.3.1