[Devel] [PATCH v12 09/12] ve/cgroup: Implemented logic that uses 'cgroup->ve_owner' to run release_agent notifications.

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Mon Apr 20 11:54:00 MSK 2020



On 4/20/20 6:42 AM, Valeriy Vdovin wrote:
> release_agent_cgroup work will extract ve_owner information from each
> cgroup in it's list and run user mode helper under it's namespaces.
> Also some code was added to detect ve destruction and manage
> release_agent executions in this case.
> 
> https://jira.sw.ru/browse/PSBM-83887
> Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
> ---
>   kernel/cgroup.c | 29 +++++++++++++++++++++++++----
>   1 file changed, 25 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index 80a4a01..7acdd01 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -5428,13 +5428,15 @@ static void check_for_release(struct cgroup *cgrp)
>    */
>   void cgroup_release_agent(struct work_struct *work)
>   {
> +	struct ve_struct *ve;
> +	ve = container_of(work, struct ve_struct, release_agent_work);
>   	mutex_lock(&cgroup_mutex);
>   	raw_spin_lock(&ve->release_list_lock);
>   	while (!list_empty(&ve->release_list)) {

"ve" is used in previous patch but defined here, something should be 
reordered here.

>   		char *argv[3], *envp[3];
>   		int i, err;
>   		char *pathbuf = NULL, *agentbuf = NULL;
> -		struct cgroup *cgrp;
> +		struct cgroup *cgrp, *root_cgrp;
>   
>   		cgrp = list_entry(ve->release_list.next,
>   				  struct cgroup,
> @@ -5445,8 +5447,24 @@ void cgroup_release_agent(struct work_struct *work)
>   		pathbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
>   		if (!pathbuf)
>   			goto continue_free;
> -		if (cgroup_path(cgrp, pathbuf, PAGE_SIZE) < 0)
> +		if (__cgroup_path(cgrp, pathbuf, PAGE_SIZE, 1) < 0)
>   			goto continue_free;
> +		rcu_read_lock();
> +		root_cgrp = cgroup_get_local_root(cgrp);
> +		/*
> +		 * At VE destruction root cgroup looses VE_ROOT flag.
> +		 * Because of that 'cgroup_get_local_root' will not see
> +		 * VE root and return host's root cgroup instead.
> +		 * We can detect this because we have a pointer to
> +		 * original ve coming from work argument.
> +		 * We do not want to execute VE's notifications on host,
> +		 * so in this case we skip.
> +		 */
> +		if (rcu_dereference(root_cgrp->ve_owner) != ve) {
> +			rcu_read_unlock();
> +			goto continue_free;
> +		}
> +		rcu_read_unlock();
>   		agentbuf = kstrdup(cgrp->root->release_agent_path, GFP_KERNEL);
>   		if (!agentbuf)
>   			goto continue_free;
> @@ -5466,8 +5484,11 @@ void cgroup_release_agent(struct work_struct *work)
>   		 * since the exec could involve hitting disk and hence
>   		 * be a slow process */
>   		mutex_unlock(&cgroup_mutex);
> -		err = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
> -		if (err < 0)
> +
> +		err = call_usermodehelper_fns_ve(ve, argv[0], argv,
> +			envp, UMH_WAIT_EXEC, NULL, NULL, NULL);
> +		if (err < 0 && ve != &ve0 &&
> +			!(ve->init_task->flags & PF_EXITING))
>   			pr_warn_ratelimited("cgroup release_agent "
>   					    "%s %s failed: %d\n",
>   					    agentbuf, pathbuf, err);
> 

-- 
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.


More information about the Devel mailing list