We don't wan't two ve namespaces linking to the same ve cgroup at the same time, we wan't each container having its own ve cgroup and namespace pair.
https://virtuozzo.atlassian.net/browse/VSTOR-119801 Signed-off-by: Pavel Tikhomirov <[email protected]> Feature: ve: ve generic structures --- v2: new patch --- include/linux/ve.h | 2 ++ kernel/ve/ve.c | 1 + kernel/ve/ve_namespace.c | 44 +++++++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/linux/ve.h b/include/linux/ve.h index 4a42f16c259a..224acf012821 100644 --- a/include/linux/ve.h +++ b/include/linux/ve.h @@ -25,6 +25,7 @@ struct nsproxy; struct user_namespace; +struct ve_namespace; struct cn_private; struct vfsmount; @@ -52,6 +53,7 @@ struct ve_struct { /* per VE CPU stats*/ u64 start_jiffies; /* Deprecated */ + struct ve_namespace *ve_ns; struct nsproxy __rcu *ve_nsproxy; struct cred *init_cred; diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c index ef2d802a3949..897423a52c08 100644 --- a/kernel/ve/ve.c +++ b/kernel/ve/ve.c @@ -63,6 +63,7 @@ struct ve_struct ve0 = { .ve_name = "0", .start_jiffies = INITIAL_JIFFIES, + .ve_ns = &init_ve_ns, RCU_POINTER_INITIALIZER(ve_nsproxy, &init_nsproxy), .state = VE_STATE_RUNNING, diff --git a/kernel/ve/ve_namespace.c b/kernel/ve/ve_namespace.c index 44cb7f0c66b0..3dbe0dde2645 100644 --- a/kernel/ve/ve_namespace.c +++ b/kernel/ve/ve_namespace.c @@ -24,11 +24,41 @@ static void dec_ve_namespaces(struct ucounts *ucounts) dec_ucount(ucounts, UCOUNT_VE_NAMESPACES); } +/* + * VE namespace links to current ve cgroup exclusively (1:1 link) + */ +static int ve_namespace_link_ve(struct ve_namespace *ns, struct ve_struct *ve) +{ + guard(rwsem_write)(&ve->op_sem); + if (ve->ve_ns) + return -EBUSY; + + ns->ve = get_ve(ve); + ve->ve_ns = ns; + + return 0; +} + +static void ve_namespace_unlink_ve(struct ve_namespace *ns) +{ + struct ve_struct *ve = ns->ve; + + /* Clean up the exclusive link from ve_struct */ + if (ve) { + scoped_guard(rwsem_write, &ve->op_sem) { + ns->ve = NULL; + ve->ve_ns = NULL; + } + put_ve(ve); + } +} + static struct ve_namespace *clone_ve_ns(struct user_namespace *user_ns, struct ve_namespace *old_ns) { struct ve_namespace *ns; struct ucounts *ucounts; + struct ve_struct __free(put_ve) *ve = NULL; int err; ucounts = inc_ve_namespaces(user_ns); @@ -50,17 +80,17 @@ static struct ve_namespace *clone_ve_ns(struct user_namespace *user_ns, ns->ns.ops = &ve_ns_operations; ns->user_ns = get_user_ns(user_ns); - /* - * VE namespace links to current ve cgroup - * FIXME it should be a 1:1 link - */ scoped_guard(rcu) - ns->ve = get_ve(css_to_ve(task_css(current, ve_cgrp_id))); - if (!ns->ve) { + ve = get_ve(css_to_ve(task_css(current, ve_cgrp_id))); + if (!ve) { err = -EINVAL; goto err_free_inum; } + err = ve_namespace_link_ve(ns, ve); + if (err) + goto err_free_inum; + return ns; err_free_inum: put_user_ns(ns->user_ns); @@ -121,7 +151,7 @@ void free_ve_ns(struct ve_namespace *ns) { struct ucounts *ucounts = ns->ucounts; - put_ve(ns->ve); + ve_namespace_unlink_ve(ns); put_user_ns(ns->user_ns); ns_free_inum(&ns->ns); kfree(ns); -- 2.52.0 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
