[Devel] [PATCH RHEL COMMIT] ve/umh: introduce per-container user mode helper macroses and functions

Konstantin Khorenko khorenko at virtuozzo.com
Tue Sep 28 14:42:37 MSK 2021


The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after ark-5.14
------>
commit 71ebf11e6f409a5ae72a7d2c8eedb7c55147203b
Author: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
Date:   Tue Sep 28 14:42:37 2021 +0300

    ve/umh: introduce per-container user mode helper macroses and functions
    
    The main and only difference with generic usermode helper is that
    subprocess_info is queued via additional kthread_work member to per-container
    usermode helper worker.
    
    Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
    
    (cherry-picked from vz8 commit 871dd2e11512 ("ve/umh: introduce per-container
    user mode helper macroses and functions"))
    
    Signed-off-by: Nikita Yushchenko <nikita.yushchenko at virtuozzo.com>
---
 include/linux/umh.h | 26 ++++++++++++++++++++++++++
 kernel/umh.c        | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/include/linux/umh.h b/include/linux/umh.h
index d91be2030375..f907e7bf1826 100644
--- a/include/linux/umh.h
+++ b/include/linux/umh.h
@@ -7,9 +7,11 @@
 #include <linux/compiler.h>
 #include <linux/workqueue.h>
 #include <linux/sysctl.h>
+#include <linux/kthread.h>
 
 struct cred;
 struct file;
+struct ve_struct;
 
 #define UMH_NO_WAIT	0	/* don't wait at all */
 #define UMH_WAIT_EXEC	1	/* wait for the exec, but not the process */
@@ -28,6 +30,10 @@ struct subprocess_info {
 	void (*cleanup)(struct subprocess_info *info);
 	void (*queue)(struct subprocess_info *info);
 	void *data;
+#ifdef CONFIG_VE
+	struct ve_struct *ve;
+	struct kthread_work ve_work;
+#endif
 } __randomize_layout;
 
 extern int
@@ -39,6 +45,26 @@ call_usermodehelper_setup(const char *path, char **argv, char **envp,
 			  int (*init)(struct subprocess_info *info, struct cred *new),
 			  void (*cleanup)(struct subprocess_info *), void *data);
 
+#ifdef CONFIG_VE
+
+extern int
+call_usermodehelper_ve(struct ve_struct *ve, const char *path,
+		       char **argv, char **envp, int wait);
+
+extern int
+call_usermodehelper_exec_ve(struct ve_struct *ve,
+			    struct subprocess_info *info, int wait);
+
+#else /* CONFIG_VE */
+
+#define call_usermodehelper_ve(ve, ...)		\
+		call_usermodehelper(##__VA_ARGS__)
+
+#define call_usermodehelper_exec_ve(ve, ...)	\
+		call_usermodehelper_exec_ve(##__VA_ARGS__)
+
+#endif /* CONFIG_VE */
+
 extern int
 call_usermodehelper_exec(struct subprocess_info *info, int wait);
 
diff --git a/kernel/umh.c b/kernel/umh.c
index e63fd7c9430a..15574a075c2a 100644
--- a/kernel/umh.c
+++ b/kernel/umh.c
@@ -28,6 +28,7 @@
 #include <linux/async.h>
 #include <linux/uaccess.h>
 #include <linux/initrd.h>
+#include <linux/ve.h>
 
 #include <trace/events/module.h>
 
@@ -412,6 +413,55 @@ struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv,
 }
 EXPORT_SYMBOL(call_usermodehelper_setup);
 
+#ifdef CONFIG_VE
+static void call_usermodehelper_queue_ve(struct subprocess_info *info)
+{
+	struct ve_struct *ve = info->ve;
+
+	kthread_queue_work(&ve->umh_worker, &info->ve_work);
+}
+
+static void call_usermodehelper_exec_work_ve(struct kthread_work *work)
+{
+	struct subprocess_info *sub_info =
+		container_of(work, struct subprocess_info, ve_work);
+
+	__call_usermodehelper_exec_work(sub_info);
+}
+
+int call_usermodehelper_exec_ve(struct ve_struct *ve,
+				struct subprocess_info *sub_info, int wait)
+{
+	if (!ve_is_super(ve)) {
+		sub_info->ve = ve;
+		sub_info->queue = call_usermodehelper_queue_ve;
+		kthread_init_work(&sub_info->ve_work,
+				  call_usermodehelper_exec_work_ve);
+	} else {
+		sub_info->queue = call_usermodehelper_queue;
+		INIT_WORK(&sub_info->work, call_usermodehelper_exec_work);
+	}
+
+	return call_usermodehelper_exec(sub_info, wait);
+}
+EXPORT_SYMBOL(call_usermodehelper_exec_ve);
+
+int call_usermodehelper_ve(struct ve_struct *ve, const char *path,
+			   char **argv, char **envp, int wait)
+{
+	struct subprocess_info *info;
+	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
+
+	info = call_usermodehelper_setup(path, argv, envp, gfp_mask,
+					    NULL, NULL, NULL);
+	if (info == NULL)
+		return -ENOMEM;
+
+	return call_usermodehelper_exec_ve(ve, info, wait);
+}
+EXPORT_SYMBOL(call_usermodehelper_ve);
+#endif
+
 /**
  * call_usermodehelper_exec - start a usermode application
  * @sub_info: information about the subprocess


More information about the Devel mailing list