@@ -858,6 +858,7 @@ struct cgroup_namespace {
struct user_namespace *user_ns;
struct ucounts *ucounts;
struct css_set *root_cset;
+ struct rcu_head rcu;
};
extern struct cgroup_namespace init_cgroup_ns;
@@ -39,11 +39,12 @@ static struct cgroup_namespace *alloc_cgroup_ns(void)
void free_cgroup_ns(struct cgroup_namespace *ns)
{
+ ns_idr_unregister(&ns->ns);
put_css_set(ns->root_cset);
dec_cgroup_namespaces(ns->ucounts);
put_user_ns(ns->user_ns);
ns_free_inum(&ns->ns);
- kfree(ns);
+ kfree_rcu(ns, rcu);
}
EXPORT_SYMBOL(free_cgroup_ns);
@@ -54,6 +55,7 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
struct cgroup_namespace *new_ns;
struct ucounts *ucounts;
struct css_set *cset;
+ int err;
BUG_ON(!old_ns);
@@ -78,16 +80,28 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
new_ns = alloc_cgroup_ns();
if (IS_ERR(new_ns)) {
- put_css_set(cset);
- dec_cgroup_namespaces(ucounts);
- return new_ns;
+ err = PTR_ERR(new_ns);
+ goto err_put_css_set;
}
new_ns->user_ns = get_user_ns(user_ns);
new_ns->ucounts = ucounts;
new_ns->root_cset = cset;
+ err = ns_idr_register(&new_ns->ns);
+ if (err < 0)
+ goto err_put_user_ns;
+
return new_ns;
+
+err_put_user_ns:
+ put_user_ns(new_ns->user_ns);
+ ns_free_inum(&new_ns->ns);
+ kfree(new_ns);
+err_put_css_set:
+ put_css_set(cset);
+ dec_cgroup_namespaces(ucounts);
+ return ERR_PTR(err);
}
static inline struct cgroup_namespace *to_cg_ns(struct ns_common *ns)
@@ -152,6 +166,7 @@ const struct proc_ns_operations cgroupns_operations = {
static __init int cgroup_namespaces_init(void)
{
+ WARN_ON(ns_idr_register(&init_cgroup_ns.ns) < 0);
return 0;
}
subsys_initcall(cgroup_namespaces_init);
Now they are exposed in /proc/namespace/ directory. Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com> --- include/linux/cgroup.h | 1 + kernel/cgroup/namespace.c | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-)