[Devel] [PATCH RHEL7 v14 09/12] ve/cgroup: Implemented logic that uses 'cgroup->ve_owner' to run release_agent notifications.
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Apr 21 17:56:28 MSK 2020
On 21.04.2020 15:53, 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>
Reviewed-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
> kernel/cgroup.c | 33 +++++++++++++++++++++++++++------
> 1 file changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/cgroup.c b/kernel/cgroup.c
> index 6437344..ae417ce 100644
> --- a/kernel/cgroup.c
> +++ b/kernel/cgroup.c
> @@ -5436,7 +5436,8 @@ void cgroup_release_agent(struct work_struct *work)
> char *argv[3], *envp[3];
> int i, err;
> char *pathbuf = NULL, *agentbuf = NULL;
> - struct cgroup *cgrp;
> + struct cgroup *cgrp, *root_cgrp;
> + struct task_struct *ve_task;
>
> cgrp = list_entry(ve->release_list.next,
> struct cgroup,
> @@ -5447,8 +5448,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;
> @@ -5468,11 +5485,15 @@ 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);
> +
> + ve_task = ve->init_task;
> + if (err < 0 && (ve == &ve0 || !(ve_task->flags & PF_EXITING)))
> pr_warn_ratelimited("cgroup release_agent "
> - "%s %s failed: %d\n",
> - agentbuf, pathbuf, err);
> + "%s %s failed: %d\n",
> + agentbuf, pathbuf, err);
>
> mutex_lock(&cgroup_mutex);
> continue_free:
>
More information about the Devel
mailing list