[libvirt] [PATCH v3] qemu: Set swap_hard_limit before hard_limit

Osier Yang jyang at redhat.com
Fri Aug 17 07:34:52 UTC 2012


Setting hard_limit larger than previous swap_hard_limit must fail,
it's not that good if one wants to change the swap_hard_limit
and hard_limit together. E.g.

% virsh memtune rhel6
hard_limit     : 1000000
soft_limit     : 1000000
swap_hard_limit: 1000000

% virsh memtune rhel6 --hard-limit 1000020 --soft-limit 1000020 \
--swap-hard-limit 1000020 --live

This patch reorder the limits setting to set the swap_hard_limit
first, hard_limit then, and soft_limit last if it's greater than
current swap_hard_limit. And soft_limit first, hard_limit then,
swap_hard_limit last, if not.
---
 src/qemu/qemu_driver.c |   67 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 80cfa84..bd97008 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6651,11 +6651,18 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
     virDomainDefPtr persistentDef = NULL;
     virCgroupPtr group = NULL;
     virDomainObjPtr vm = NULL;
+    virTypedParameterPtr hard_limit = NULL;
+    virTypedParameterPtr swap_hard_limit = NULL;
+    int hard_limit_index = 0;
+    int swap_hard_limit_index = 0;
+    unsigned long long val = 0;
+
     int ret = -1;
     int rc;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
+
     if (virTypedParameterArrayValidate(params, nparams,
                                        VIR_DOMAIN_MEMORY_HARD_LIMIT,
                                        VIR_TYPED_PARAM_ULLONG,
@@ -6694,13 +6701,61 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
         }
     }
 
+    for (i = 0; i < nparams; i++) {
+        if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
+            hard_limit = &params[i];
+            hard_limit_index = i;
+        } else if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
+            swap_hard_limit = &params[i];
+            swap_hard_limit_index = i;
+        }
+    }
+
+    /* It will fail if hard limit greater than swap hard limit anyway */
+    if (swap_hard_limit &&
+        hard_limit &&
+        (hard_limit->value.ul > swap_hard_limit->value.ul)) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("hard limit must be lower than swap hard limit"));
+        goto cleanup;
+    }
+
+    /* Get current swap hard limit */
+    rc = virCgroupGetMemSwapHardLimit(group, &val);
+    if (rc != 0) {
+        virReportSystemError(-rc, "%s",
+                             _("unable to get swap hard limit"));
+        goto cleanup;
+    }
+
+    /* Swap hard_limit and swap_hard_limit to ensure the setting
+     * could succeed if both of them are provided.
+     */
+    if (swap_hard_limit && hard_limit) {
+        virTypedParameter param;
+
+        if (swap_hard_limit->value.ul > val) {
+             if (hard_limit_index < swap_hard_limit_index) {
+                 param = params[hard_limit_index];
+                 params[hard_limit_index] = params[swap_hard_limit_index];
+                 params[swap_hard_limit_index] = param;
+             }
+        } else {
+             if (hard_limit_index > swap_hard_limit_index) {
+                 param = params[hard_limit_index];
+                 params[hard_limit_index] = params[swap_hard_limit_index];
+                 params[swap_hard_limit_index] = param;
+             }
+        }
+    }
+
     ret = 0;
     for (i = 0; i < nparams; i++) {
         virTypedParameterPtr param = &params[i];
 
         if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemoryHardLimit(group, params[i].value.ul);
+                rc = virCgroupSetMemoryHardLimit(group, param->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set memory hard_limit tunable"));
@@ -6709,11 +6764,11 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
             }
 
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                persistentDef->mem.hard_limit = params[i].value.ul;
+                persistentDef->mem.hard_limit = param->value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemorySoftLimit(group, params[i].value.ul);
+                rc = virCgroupSetMemorySoftLimit(group, param->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set memory soft_limit tunable"));
@@ -6722,11 +6777,11 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
             }
 
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                persistentDef->mem.soft_limit = params[i].value.ul;
+                persistentDef->mem.soft_limit = param->value.ul;
             }
         } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT)) {
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
-                rc = virCgroupSetMemSwapHardLimit(group, params[i].value.ul);
+                rc = virCgroupSetMemSwapHardLimit(group, param->value.ul);
                 if (rc != 0) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set swap_hard_limit tunable"));
@@ -6734,7 +6789,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
                 }
             }
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                persistentDef->mem.swap_hard_limit = params[i].value.ul;
+                persistentDef->mem.swap_hard_limit = param->value.ul;
             }
         }
     }
-- 
1.7.7.3




More information about the libvir-list mailing list