On nie, gru 14, 2008 at 03:06:04 +0100, Grzegorz Nosek wrote: > On sob, gru 13, 2008 at 03:03:52 +0800, Li Zefan wrote: > > > /** > > > - * cgroup_is_descendant - see if @cgrp is a descendant of current task's cgrp > > > + * cgroup_is_descendant - see if @cgrp is a descendant of @task's cgrp > > > * @cgrp: the cgroup in question > > > + * @task: the task in question > > > + * @subsys_id: cgroup subsystem id used to determine hierarchy; if negative, > > > + * use get_first_subsys() > > > > The last argument is redundant. > > > > [...] > > > > It makes no difference with: > > if (!cgroup_is_descendant(new_cgroup, task, -1)) > > > > That's why we don't need argument 'subsys_id'. > > Thanks, I thought so (the "first" subsys_id looked arbitrary to me) but not knowing > the cgroup internals I wanted to preserve the original code as much as possible. > Will update the patch. As promised, here's the updated patch. >From 2abb608222f3dfd1c5da3022a75c824f2b00b3f5 Mon Sep 17 00:00:00 2001 From: Grzegorz Nosek <root@xxxxxxxxxxxxxx> Date: Fri, 12 Dec 2008 21:48:09 +0100 Subject: [PATCH] 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 Signed-off-by: Grzegorz Nosek <root@xxxxxxxxxxxxxx> --- include/linux/cgroup.h | 4 ++-- kernel/cgroup.c | 12 +++++++----- kernel/ns_cgroup.c | 9 +++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 1ba3ded..53188f5 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -301,8 +301,8 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen); int cgroup_task_count(const struct cgroup *cgrp); -/* Return true if the cgroup is a descendant of the current cgroup */ -int cgroup_is_descendant(const struct cgroup *cgrp); +/* Return true if cgrp is a descendant of the task's cgroup */ +int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task); /* Control Group subsystem type. See Documentation/cgroups.txt for details */ diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 2ae040d..5512d78 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -3101,18 +3101,19 @@ int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys, } /** - * cgroup_is_descendant - see if @cgrp is a descendant of current task's cgrp + * cgroup_is_descendant - see if @cgrp is a descendant of @task's cgrp * @cgrp: the cgroup in question + * @task: the task in question * - * See if @cgrp is a descendant of the current task's cgroup in - * the appropriate hierarchy. + * See if @cgrp is a descendant of @task's cgroup in the appropriate + * hierarchy. * * If we are sending in dummytop, then presumably we are creating * the top cgroup in the subsystem. * * Called only by the ns (nsproxy) cgroup. */ -int cgroup_is_descendant(const struct cgroup *cgrp) +int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task) { int ret; struct cgroup *target; @@ -3122,7 +3123,8 @@ int cgroup_is_descendant(const struct cgroup *cgrp) return 1; get_first_subsys(cgrp, NULL, &subsys_id); - target = task_cgroup(current, subsys_id); + target = task_cgroup(task, subsys_id); + while (cgrp != target && cgrp!= cgrp->top_cgroup) cgrp = cgrp->parent; ret = (cgrp == target); diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c index 43c2111..d99b4cc 100644 --- a/kernel/ns_cgroup.c +++ b/kernel/ns_cgroup.c @@ -46,21 +46,18 @@ int ns_cgroup_clone(struct task_struct *task, struct pid *pid) static int ns_can_attach(struct cgroup_subsys *ss, struct cgroup *new_cgroup, struct task_struct *task) { - struct cgroup *orig; - if (current != task) { if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!cgroup_is_descendant(new_cgroup)) + if (!cgroup_is_descendant(new_cgroup, current)) return -EPERM; } if (atomic_read(&new_cgroup->count) != 0) return -EPERM; - orig = task_cgroup(task, ns_subsys_id); - if (orig && orig != new_cgroup->parent) + if (!cgroup_is_descendant(new_cgroup, task)) return -EPERM; return 0; @@ -78,7 +75,7 @@ static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss, if (!capable(CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); - if (!cgroup_is_descendant(cgroup)) + if (!cgroup_is_descendant(cgroup, current)) return ERR_PTR(-EPERM); ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL); -- 1.5.4.4 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers