[libvirt] [PATCH] qemu: Ensure the cpuset is formated as expected before passing to cgroup

Osier Yang jyang at redhat.com
Thu Aug 16 03:35:04 UTC 2012


The parameter value for cpuset could be in special format like
"0-10,^7", which is not recongnized by cgroup. This patch is to
ensure the cpuset is formated as expected before passing it to
cgroup. As a side effect, after the patch, it parses the cpuset
early before cgroup setting, to avoid the rollback if cpuset
parsing fails afterwards.
---
 src/qemu/qemu_driver.c |   77 +++++++++++++++++++++++++----------------------
 1 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 369e8ed..fc412a1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6952,8 +6952,23 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
             }
         } else if (STREQ(param->field, VIR_DOMAIN_NUMA_NODESET)) {
             int rc;
-            bool savedmask;
-            char oldnodemask[VIR_DOMAIN_CPUMASK_LEN];
+            char *nodeset = NULL;
+            char *nodeset_str = NULL;
+
+            if (VIR_ALLOC_N(nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) {
+                virReportOOMError();
+                ret = -1;
+                goto cleanup;
+            };
+
+            if (virDomainCpuSetParse(params[i].value.s,
+                                     0, nodeset,
+                                     VIR_DOMAIN_CPUMASK_LEN) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("Failed to parse nodeset"));
+                ret = -1;
+                continue;
+            }
 
             if (flags & VIR_DOMAIN_AFFECT_LIVE) {
                 if (vm->def->numatune.memory.mode !=
@@ -6961,72 +6976,62 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
                     virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                                    _("change of nodeset for running domain "
                                      "requires strict numa mode"));
+                    VIR_FREE(nodeset);
                     ret = -1;
                     continue;
                 }
-                rc = virCgroupSetCpusetMems(group, params[i].value.s);
-                if (rc != 0) {
+
+                /* Ensure the cpuset string is formated before passing to cgroup */
+                if (!(nodeset_str = virDomainCpuSetFormat(nodeset,
+                                                          VIR_DOMAIN_CPUMASK_LEN))) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("Failed to format nodeset"));
+                    VIR_FREE(nodeset);
+                    ret = -1;
+                    continue;
+                }
+
+                if ((rc = virCgroupSetCpusetMems(group, nodeset_str) != 0)) {
                     virReportSystemError(-rc, "%s",
                                          _("unable to set numa tunable"));
+                    VIR_FREE(nodeset);
+                    VIR_FREE(nodeset_str);
                     ret = -1;
                     continue;
                 }
+                VIR_FREE(nodeset_str);
 
                 /* update vm->def here so that dumpxml can read the new
                  * values from vm->def. */
-                savedmask = false;
                 if (!vm->def->numatune.memory.nodemask) {
                     if (VIR_ALLOC_N(vm->def->numatune.memory.nodemask,
                                     VIR_DOMAIN_CPUMASK_LEN) < 0) {
                         virReportOOMError();
+                        VIR_FREE(nodeset);
                         ret = -1;
                         goto cleanup;
                     }
                 } else {
-                    memcpy(oldnodemask, vm->def->numatune.memory.nodemask,
-                           VIR_DOMAIN_CPUMASK_LEN);
-                    savedmask = true;
-                }
-                if (virDomainCpuSetParse(params[i].value.s,
-                                         0,
-                                         vm->def->numatune.memory.nodemask,
-                                         VIR_DOMAIN_CPUMASK_LEN) < 0) {
-                    if (savedmask)
-                        memcpy(vm->def->numatune.memory.nodemask,
-                               oldnodemask, VIR_DOMAIN_CPUMASK_LEN);
-                    else
-                        VIR_FREE(vm->def->numatune.memory.nodemask);
-                    ret = -1;
-                    continue;
+                    VIR_FREE(vm->def->numatune.memory.nodemask);
                 }
+
+                vm->def->numatune.memory.nodemask = nodeset;
             }
 
             if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
-                savedmask = false;
                 if (!persistentDef->numatune.memory.nodemask) {
                     if (VIR_ALLOC_N(persistentDef->numatune.memory.nodemask,
                                     VIR_DOMAIN_CPUMASK_LEN) < 0) {
                         virReportOOMError();
+                        VIR_FREE(nodeset);
                         ret = -1;
                         goto cleanup;
                     }
                 } else {
-                    memcpy(oldnodemask, persistentDef->numatune.memory.nodemask,
-                           VIR_DOMAIN_CPUMASK_LEN);
-                    savedmask = true;
-                }
-                if (virDomainCpuSetParse(params[i].value.s,
-                                         0,
-                                         persistentDef->numatune.memory.nodemask,
-                                         VIR_DOMAIN_CPUMASK_LEN) < 0) {
-                    if (savedmask)
-                        memcpy(persistentDef->numatune.memory.nodemask,
-                               oldnodemask, VIR_DOMAIN_CPUMASK_LEN);
-                    else
-                        VIR_FREE(persistentDef->numatune.memory.nodemask);
-                    ret = -1;
-                    continue;
+                    VIR_FREE(persistentDef->numatune.memory.nodemask);
                 }
+
+                persistentDef->numatune.memory.nodemask = nodeset;
             }
         }
     }
-- 
1.7.7.3




More information about the libvir-list mailing list