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 <[email protected]> Reviewed-by: Kirill Tkhai <[email protected]> --- kernel/cgroup.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index e379d83..aa93cf2 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -5539,7 +5539,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, @@ -5550,8 +5551,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, true) < 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_access_pointer(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; @@ -5571,8 +5588,12 @@ 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_task->flags & PF_EXITING))) pr_warn_ratelimited("cgroup release_agent " "%s %s failed: %d\n", agentbuf, pathbuf, err); -- 1.8.3.1 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
