[RHEL7,v21,14/14] ve/cgroup: At cgroup_mark(unmark)_ve_roots skip non-virtualized roots

Submitted by Valeriy Vdovin on July 28, 2020, 5:53 p.m.

Details

Message ID 1595958806-338946-15-git-send-email-valeriy.vdovin@virtuozzo.com
State New
Series "Make release_agent per-cgroup property. Run release_agent in proper ve."
Headers show

Commit Message

Valeriy Vdovin July 28, 2020, 5:53 p.m.
During container start there might be a situation when not all cgroup
hierarchies get virtualized by container manager (like vzctl). By
virtualizing a cgroup hierarchy I mean creation of sub-directory within
a particular mounted cgroup. When container starts it looks in css set
of it's init process to list all affilated cgroups and perform actions
on each. But non-virtualized cgroups will also be present in init's css_set
and they should not be touched from inside of any non root ve.

Signed-off-by: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
---
 kernel/cgroup.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Patch hide | download patch | download mbox

diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 402973a..5fc60228 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4464,6 +4464,17 @@  int cgroup_mark_ve_roots(struct ve_struct *ve)
 	mutex_lock(&cgroup_mutex);
 	for_each_active_root(root) {
 		cgrp = css_cgroup_from_root(ve->root_css_set, root);
+
+		/*
+		 * In some situations not all cgroup roots are
+		 * virtualized by container manager (vzctl). In that
+		 * case cgrp will point at the actual top cgroup of
+		 * the hierarchy which is private property of host,
+		 * we should not modify it and just skip.
+		 */
+		if (cgrp == &root->top_cgroup)
+			continue;
+
 		rcu_assign_pointer(cgrp->ve_owner, ve);
 		set_bit(CGRP_VE_ROOT, &cgrp->flags);
 
@@ -4513,6 +4524,14 @@  void cgroup_unmark_ve_roots(struct ve_struct *ve)
 	mutex_lock(&cgroup_mutex);
 	for_each_active_root(root) {
 		cgrp = css_cgroup_from_root(ve->root_css_set, root);
+
+		/*
+		 * For this line see comments in
+		 * cgroup_mark_ve_roots
+		 */
+		if (cgrp == &root->top_cgroup)
+			continue;
+
 		dget(cgrp->dentry);
 		list_add_tail(&cgrp->cft_q_node, &pending);
 	}

Comments

Kirill Tkhai July 31, 2020, 8:28 a.m.
On 28.07.2020 20:53, Valeriy Vdovin wrote:
> During container start there might be a situation when not all cgroup
> hierarchies get virtualized by container manager (like vzctl). By
> virtualizing a cgroup hierarchy I mean creation of sub-directory within
> a particular mounted cgroup. When container starts it looks in css set
> of it's init process to list all affilated cgroups and perform actions
> on each. But non-virtualized cgroups will also be present in init's css_set
> and they should not be touched from inside of any non root ve.
> 
> Signed-off-by: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
> ---
>  kernel/cgroup.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index 402973a..5fc60228 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -4464,6 +4464,17 @@ int cgroup_mark_ve_roots(struct ve_struct *ve)
>  	mutex_lock(&cgroup_mutex);
>  	for_each_active_root(root) {
>  		cgrp = css_cgroup_from_root(ve->root_css_set, root);
> +
> +		/*
> +		 * In some situations not all cgroup roots are
> +		 * virtualized by container manager (vzctl). In that
> +		 * case cgrp will point at the actual top cgroup of
> +		 * the hierarchy which is private property of host,
> +		 * we should not modify it and just skip.
> +		 */
> +		if (cgrp == &root->top_cgroup)
> +			continue;

This is a good idea, but what will be if this cgroup is private cgroup of host, which is not its top_cgroup?

> +
>  		rcu_assign_pointer(cgrp->ve_owner, ve);
>  		set_bit(CGRP_VE_ROOT, &cgrp->flags);
>  
> @@ -4513,6 +4524,14 @@ void cgroup_unmark_ve_roots(struct ve_struct *ve)
>  	mutex_lock(&cgroup_mutex);
>  	for_each_active_root(root) {
>  		cgrp = css_cgroup_from_root(ve->root_css_set, root);
> +
> +		/*
> +		 * For this line see comments in
> +		 * cgroup_mark_ve_roots
> +		 */
> +		if (cgrp == &root->top_cgroup)
> +			continue;
> +
>  		dget(cgrp->dentry);
>  		list_add_tail(&cgrp->cft_q_node, &pending);
>  	}
>