[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