cgroup attach/fork hooks consistency with the ns_cgroup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I noticed two different behaviours, the second one looks weird for me:

 1) when the cgroup is manually created:
	mkdir /cgroup/foo
	echo $$ > /cgroup/foo/tasks

 only the "attach" callback is called as expected.

2) when the cgroup is automatically created via the ns_cgroup with the clone function and the namespace flags,

  the "attach" *and* the "fork" callbacks are called.


IMHO, these two different behaviours look inconsistent. Won't this lead to some problems or a specific code to handle both cases if a cgroup is using the fork and the attach hooks ?

For example, let's imagine we create a control group which shows the number of tasks running. We have a global atomic and we display its value in the cgroupfs.

When a task attaches to the cgroup, we do atomic_inc in the attach callback. For all its child, the fork hook will do atomic_inc and exit hook will do atomic_dec.

If we create the cgroup manually like the case 1) that works. But if we use the control group with the ns_cgroup the task counter will be set to 2 for the first tasks entering the cgroup because the attach callback will increment the counter and the fork callback will increment it again.

In attachment a source code to illustrate the example.

Shouldn't the ns_cgroup_clone be called after the cgroup_fork_callbacks in copy_process function ? So we don't call the fork callback for the first tasks and we keep the consistency ?

Thanks
 -- Daniel


---
 include/linux/cgroup_subsys.h |    1 
 kernel/Makefile               |    2 
 kernel/cgroup_bug.c           |   87 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 1 deletion(-)

Index: linux-2.6/kernel/cgroup_bug.c
===================================================================
--- /dev/null
+++ linux-2.6/kernel/cgroup_bug.c
@@ -0,0 +1,87 @@
+#include <linux/cgroup.h>
+#include <asm/atomic.h>
+
+struct bug_cg {
+	struct cgroup_subsys_state css;
+	atomic_t ntasks;
+};
+
+static inline struct bug_cg *bug_cgroup(struct cgroup *cgroup)
+{
+	return container_of(cgroup_subsys_state(cgroup, bug_subsys_id),
+			    struct bug_cg, css);
+}
+
+static struct cgroup_subsys_state *bug_cgroup_create(struct cgroup_subsys *ss,
+						     struct cgroup *cgroup)
+{
+	struct bug_cg *bug_cg;
+
+	bug_cg = kzalloc(sizeof(*bug_cg), GFP_KERNEL);
+	if (!bug_cg)
+		return ERR_PTR(-ENOMEM);
+
+	atomic_set(&bug_cg->ntasks, 0);
+
+	return &bug_cg->css;
+}
+
+static void bug_cgroup_destroy(struct cgroup_subsys *ss, struct cgroup *cgroup)
+{
+	struct bug_cg *bug_cg = bug_cgroup(cgroup);
+	kfree(bug_cg);
+}
+
+static void bug_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgroup,
+			      struct cgroup *old_cgroup,
+			      struct task_struct *task)
+{
+	struct bug_cg *bug_cg = bug_cgroup(cgroup);
+
+	atomic_inc(&bug_cg->ntasks);
+}
+
+static int bug_cgroup_fork(struct cgroup_subsys *ss, struct task_struct *task,
+			   unsigned long clone_flags)
+{
+	struct cgroup *cgroup = task_cgroup(task, bug_subsys_id);
+
+	atomic_inc(&bug_cgroup(cgroup)->ntasks);
+
+	return 0;
+}
+
+static void bug_cgroup_exit(struct cgroup_subsys *ss, struct task_struct *task)
+{
+	struct cgroup *cgroup = task_cgroup(task, bug_subsys_id);
+
+	atomic_dec(&bug_cgroup(cgroup)->ntasks);
+}
+
+static u64 task_count_read(struct cgroup *cgroup, struct cftype *cft)
+{
+	return atomic_read(&bug_cgroup(cgroup)->ntasks);
+}
+
+static struct cftype files[] = {
+	{
+		.name = "ntask",
+		.read_u64 = task_count_read,
+	},
+};
+
+static int bug_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cgroup)
+{
+	return cgroup_add_files(cgroup, ss, files, ARRAY_SIZE(files));
+}
+
+struct cgroup_subsys bug_subsys = {
+	.name		= "bug",
+	.subsys_id	= bug_subsys_id,
+	.create		= bug_cgroup_create,
+	.destroy	= bug_cgroup_destroy,
+	.populate	= bug_cgroup_populate,
+	.attach         = bug_cgroup_attach,
+	.fork		= bug_cgroup_fork,
+	.exit		= bug_cgroup_exit,
+};
Index: linux-2.6/include/linux/cgroup_subsys.h
===================================================================
--- linux-2.6.orig/include/linux/cgroup_subsys.h
+++ linux-2.6/include/linux/cgroup_subsys.h
@@ -21,6 +21,7 @@ SUBSYS(debug)
 
 #ifdef CONFIG_CGROUP_NS
 SUBSYS(ns)
+SUBSYS(bug)
 #endif
 
 /* */
Index: linux-2.6/kernel/Makefile
===================================================================
--- linux-2.6.orig/kernel/Makefile
+++ linux-2.6/kernel/Makefile
@@ -60,7 +60,7 @@ obj-$(CONFIG_CGROUPS) += cgroup.o
 obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o
 obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
-obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o
+obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o cgroup_bug.o
 obj-$(CONFIG_UTS_NS) += utsname.o
 obj-$(CONFIG_USER_NS) += user_namespace.o
 obj-$(CONFIG_PID_NS) += pid_namespace.o
_______________________________________________
Containers mailing list
Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/containers

[Index of Archives]     [Cgroups]     [Netdev]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux