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