--- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list