
On Wed, Apr 25, 2012 at 05:44:52PM +0800, Wen Congyang wrote:
introduce a new API to move all tasks from a cgroup to another cgroup
--- src/util/cgroup.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/cgroup.h | 2 + 2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/src/util/cgroup.c b/src/util/cgroup.c index 901a841..724cc6e 100644 --- a/src/util/cgroup.c +++ b/src/util/cgroup.c @@ -789,6 +789,61 @@ int virCgroupAddTask(virCgroupPtr group, pid_t pid) return rc; }
+static int virCgrouAddTaskStr(virCgroupPtr group, const char *pidstr) +{ + unsigned long long value; + + if (virStrToLong_ull(pidstr, NULL, 10, &value) < 0) + return -EINVAL; + + return virCgroupAddTask(group, value); +} + +/** + * virCgroupMoveTask: + * + * @src_group: The source cgroup where all tasks are removed from + * @dest_group: The destination where all tasks are added to + * + * Returns: 0 on success + */ +int virCgroupMoveTask(virCgroupPtr src_group, virCgroupPtr dest_group) +{ + int rc = 0; + int i; + char *content, *value, *next; + + for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { + /* Skip over controllers not mounted */ + if (!src_group->controllers[i].mountPoint || + !dest_group->controllers[i].mountPoint) + continue; + + rc = virCgroupGetValueStr(src_group, i, "tasks", &content); + if (rc != 0) + break; + + value = content; + while((next = strchr(value, '\n')) != NULL) { + *next = '\0'; + if ((rc = virCgrouAddTaskStr(dest_group, value) < 0)) + goto cleanup; + value = next + 1; + } + if (*value != '\0') { + if ((rc = virCgrouAddTaskStr(dest_group, value) < 0)) + goto cleanup; + } + + VIR_FREE(content); + } + + return 0; + +cleanup: + virCgroupMoveTask(dest_group, src_group);
If we get here, the tasks that are originally in dest_group can be mistakenly moved to src_group. And, note that this is a recursive call, there is the possibility it ends up with a endless call to virCgroupMoveTask if all fail because of the same error. -- Thanks, Hu Tao