diff options
author | Grzegorz Nosek <root@localdomain.pl> | 2009-04-02 19:57:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-02 22:04:53 -0400 |
commit | 313e924c0852943e67335fad9d2608701f0dfe8e (patch) | |
tree | fa4c3f65a7ed6edea52ae78b012138ebab1420c3 /kernel/cgroup.c | |
parent | d20a390a0ee2bf2f692c539c6ce1c829e1080bb5 (diff) |
cgroups: relax ns_can_attach checks to allow attaching to grandchild cgroups
The ns_proxy cgroup allows moving processes to child cgroups only one
level deep at a time. This commit relaxes this restriction and makes it
possible to attach tasks directly to grandchild cgroups, e.g.:
($pid is in the root cgroup)
echo $pid > /cgroup/CG1/CG2/tasks
Previously this operation would fail with -EPERM and would have to be
performed as two steps:
echo $pid > /cgroup/CG1/tasks
echo $pid > /cgroup/CG1/CG2/tasks
Also, the target cgroup no longer needs to be empty to move a task there.
Signed-off-by: Grzegorz Nosek <root@localdomain.pl>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Reviewed-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Paul Menage <menage@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index c500ca7239b2..27792bcb0758 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -3084,18 +3084,19 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys, | |||
3084 | } | 3084 | } |
3085 | 3085 | ||
3086 | /** | 3086 | /** |
3087 | * cgroup_is_descendant - see if @cgrp is a descendant of current task's cgrp | 3087 | * cgroup_is_descendant - see if @cgrp is a descendant of @task's cgrp |
3088 | * @cgrp: the cgroup in question | 3088 | * @cgrp: the cgroup in question |
3089 | * @task: the task in question | ||
3089 | * | 3090 | * |
3090 | * See if @cgrp is a descendant of the current task's cgroup in | 3091 | * See if @cgrp is a descendant of @task's cgroup in the appropriate |
3091 | * the appropriate hierarchy. | 3092 | * hierarchy. |
3092 | * | 3093 | * |
3093 | * If we are sending in dummytop, then presumably we are creating | 3094 | * If we are sending in dummytop, then presumably we are creating |
3094 | * the top cgroup in the subsystem. | 3095 | * the top cgroup in the subsystem. |
3095 | * | 3096 | * |
3096 | * Called only by the ns (nsproxy) cgroup. | 3097 | * Called only by the ns (nsproxy) cgroup. |
3097 | */ | 3098 | */ |
3098 | int cgroup_is_descendant(const struct cgroup *cgrp) | 3099 | int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task) |
3099 | { | 3100 | { |
3100 | int ret; | 3101 | int ret; |
3101 | struct cgroup *target; | 3102 | struct cgroup *target; |
@@ -3105,7 +3106,7 @@ int cgroup_is_descendant(const struct cgroup *cgrp) | |||
3105 | return 1; | 3106 | return 1; |
3106 | 3107 | ||
3107 | get_first_subsys(cgrp, NULL, &subsys_id); | 3108 | get_first_subsys(cgrp, NULL, &subsys_id); |
3108 | target = task_cgroup(current, subsys_id); | 3109 | target = task_cgroup(task, subsys_id); |
3109 | while (cgrp != target && cgrp!= cgrp->top_cgroup) | 3110 | while (cgrp != target && cgrp!= cgrp->top_cgroup) |
3110 | cgrp = cgrp->parent; | 3111 | cgrp = cgrp->parent; |
3111 | ret = (cgrp == target); | 3112 | ret = (cgrp == target); |