[RHEL8,COMMIT] cgroup/ve: Do not run release_agent on non-running ve

Submitted by Konstantin Khorenko on March 3, 2021, 5:21 p.m.

Details

Message ID 202103031721.123HLGAH295421@finist-co8.sw.ru
State New
Series "Port release_agent virtualization from vz7"
Headers show

Commit Message

Konstantin Khorenko March 3, 2021, 5:21 p.m.
The commit is pushed to "branch-rh8-4.18.0-240.1.1.vz8.5.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-240.1.1.vz8.5.5
------>
commit b731c902e757211385077720bb021e0e56bf1d81
Author: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
Date:   Wed Mar 3 20:21:16 2021 +0300

    cgroup/ve: Do not run release_agent on non-running ve
    
    cgroup1_release_agent is a function that runs within a private
    ve workqueue. When executed, it runs an executable in a userspace
    by a call to call_usermodehelper_ve.
    
    There is conflict that when ve is getting shutdown and some of last
    cgroups gets deleted at the same time, the workqueue might still be
    running, but ve_stop_ns has already been called.
    
    ve_stop_ns will stop usermode helper threads, needed for
    call_usermodehelper_ve. Because of that a call to call_usermodehelper_ve
    will never return, causing a hang.
    
    To defeat that hang VZ7 code of call_usermodehelper_ve included the
    check that ve is still running before running the userspace executable.
    It also checked for ve->init_task->flags & PF_EXITING condition.
    
    But in VZ8 the whole usermodehelper infrastructure is much more different.
    Also VZ8 does not have ve->init_task in it's fields.
    That's why it seems more relevant right now to do ve->is_running
    check before the call to call_usermodehelper_ve.
    
    Signed-off-by: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
    Reviewed-by: Kirill Tkhai <ktkhai@virtuozzo.com>
    
    =====================
    Patchset description:
    
    ve/cgroup: Port release_agent virtualization from vz7
    
    This patchset ports virtualization of cgroup release_agent
    virtualization from vz7.
    
    Major challanges of porting are differences between vz7 and vz8 cgroup
    implementations:
    - transition of cgroups to kernfs
    - slightly changed locking scheme, which relies on css_set_lock in
      places, previously relied on cgroup_mutex.
    
    There is a small number of patches that have been ported without
    modifications, but most of the patches had suffered a lot of
    modification due to the factors described above.
    
    v1:
      - original patchset
    v2:
      - removed port of CGRP_REMOVED due to the use of CSS_ONLINE in VZ8 for
        same reason
      - changed ve_set(get)_release_agent_path signature for more optimal
      - added ve->is_running check before calling userspace executable
    v3:
      - use goto after check for ve->is_running in last patch
---
 kernel/cgroup/cgroup-v1.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c
index 993ac38b895f..cd1a0df6c528 100644
--- a/kernel/cgroup/cgroup-v1.c
+++ b/kernel/cgroup/cgroup-v1.c
@@ -934,9 +934,12 @@  void cgroup1_release_agent(struct work_struct *work)
 		envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
 		envp[i] = NULL;
 
-
 		mutex_unlock(&cgroup_mutex);
 
+		down_write(&ve->op_sem);
+		if (!ve->is_running)
+			goto continue_with_mutex;
+
 		err = call_usermodehelper_ve(ve, argv[0], argv,
 			envp, UMH_WAIT_EXEC);
 
@@ -944,6 +947,7 @@  void cgroup1_release_agent(struct work_struct *work)
 			pr_warn_ratelimited("cgroup1_release_agent "
 					    "%s %s failed: %d\n",
 					    agentbuf, pathbuf, err);
+continue_with_mutex:
 		up_write(&ve->op_sem);
 		mutex_lock(&cgroup_mutex);
 continue_free: