---
src/qemu/qemu_driver.c | 100 ++++++++++++++++++++++++++++++++++++++++-------
tools/virsh.c | 2 +-
2 files changed, 86 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index fdb3b30..1e133ae 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4918,23 +4918,22 @@ cleanup:
static int qemuDomainGetMemoryParameters(virDomainPtr dom,
virMemoryParameterPtr params,
int *nparams,
- unsigned int flags ATTRIBUTE_UNUSED)
+ unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
int i;
virCgroupPtr group = NULL;
virDomainObjPtr vm = NULL;
+ virDomainDefPtr persistentDef = NULL;
unsigned long long val;
int ret = -1;
int rc;
+ bool isActive;
- qemuDriverLock(driver);
+ virCheckFlags(VIR_DOMAIN_MEMORY_PARAM_LIVE |
+ VIR_DOMAIN_MEMORY_PARAM_CONFIG, -1);
- if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
- qemuReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("cgroup memory controller is not
mounted"));
- goto cleanup;
- }
+ qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -4944,10 +4943,43 @@ static int qemuDomainGetMemoryParameters(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 (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;
}
if ((*nparams) == 0) {
@@ -4963,10 +4995,47 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
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) {
+ for (i = 0; i < *nparams; i++) {
+ virMemoryParameterPtr param = ¶ms[i];
+ val = 0;
+ param->value.ul = 0;
+ param->type = VIR_DOMAIN_MEMORY_PARAM_ULLONG;
+
+ switch (i) {
+ case 0: /* fill memory hard limit here */
+ if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT) ==
NULL) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Field memory hard limit too
long for destination"));
+ goto cleanup;
+ }
+ param->value.ul = persistentDef->mem.hard_limit;
+ break;
+
+ case 1: /* fill memory soft limit here */
+ if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT) ==
NULL) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Field memory soft limit too
long for destination"));
+ goto cleanup;
+ }
+ param->value.ul = persistentDef->mem.soft_limit;
+ break;
+
+ case 2: /* fill swap hard limit here */
+ if (virStrcpyStatic(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)
== NULL) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Field swap hard limit too
long for destination"));
+ goto cleanup;
+ }
+ param->value.ul = persistentDef->mem.swap_hard_limit;
+ break;
+
+ default:
+ break;
+ /* should not hit here */
+ }
+ }
+ goto out;
}
for (i = 0; i < *nparams; i++) {
@@ -5027,6 +5096,7 @@ static int qemuDomainGetMemoryParameters(virDomainPtr dom,
}
}
+out:
ret = 0;
cleanup:
diff --git a/tools/virsh.c b/tools/virsh.c
index b2a5a8d..5594389 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -3357,7 +3357,7 @@ cmdMemtune(vshControl * ctl, const vshCmd * cmd)
if (nparams == 0) {
/* get the number of memory parameters */
- if (virDomainGetMemoryParameters(dom, NULL, &nparams, 0) != 0) {
+ if (virDomainGetMemoryParameters(dom, NULL, &nparams, flags) != 0) {
vshError(ctl, "%s",
_("Unable to get number of memory parameters"));
goto cleanup;
--
1.7.3.1