diff options
Diffstat (limited to 'include/linux/kmod.h')
-rw-r--r-- | include/linux/kmod.h | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/include/linux/kmod.h b/include/linux/kmod.h index facb27fe7de..f9edf63e90e 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -23,6 +23,7 @@ #include <linux/stddef.h> #include <linux/errno.h> #include <linux/compiler.h> +#include <linux/workqueue.h> #define KMOD_PATH_LEN 256 @@ -45,7 +46,27 @@ static inline int request_module_nowait(const char *name, ...) { return -ENOSYS; struct key; struct file; -struct subprocess_info; + +enum umh_wait { + UMH_NO_WAIT = -1, /* don't wait at all */ + UMH_WAIT_EXEC = 0, /* wait for the exec, but not the process */ + UMH_WAIT_PROC = 1, /* wait for the process to complete */ +}; + +struct subprocess_info { + struct work_struct work; + struct completion *complete; + struct cred *cred; + char *path; + char **argv; + char **envp; + enum umh_wait wait; + int retval; + struct file *stdin; + int (*init)(struct subprocess_info *info); + void (*cleanup)(struct subprocess_info *info); + void *data; +}; /* Allocate a subprocess_info structure */ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv, @@ -56,14 +77,10 @@ void call_usermodehelper_setkeys(struct subprocess_info *info, struct key *session_keyring); int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info, struct file **filp); -void call_usermodehelper_setcleanup(struct subprocess_info *info, - void (*cleanup)(char **argv, char **envp)); - -enum umh_wait { - UMH_NO_WAIT = -1, /* don't wait at all */ - UMH_WAIT_EXEC = 0, /* wait for the exec, but not the process */ - UMH_WAIT_PROC = 1, /* wait for the process to complete */ -}; +void call_usermodehelper_setfns(struct subprocess_info *info, + int (*init)(struct subprocess_info *info), + void (*cleanup)(struct subprocess_info *info), + void *data); /* Actually execute the sub-process */ int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait); @@ -73,18 +90,32 @@ int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait); void call_usermodehelper_freeinfo(struct subprocess_info *info); static inline int -call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) +call_usermodehelper_fns(char *path, char **argv, char **envp, + enum umh_wait wait, + int (*init)(struct subprocess_info *info), + void (*cleanup)(struct subprocess_info *), void *data) { 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); + if (info == NULL) return -ENOMEM; + + call_usermodehelper_setfns(info, init, cleanup, data); + return call_usermodehelper_exec(info, wait); } static inline int +call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) +{ + return call_usermodehelper_fns(path, argv, envp, wait, + NULL, NULL, NULL); +} + +static inline int call_usermodehelper_keys(char *path, char **argv, char **envp, struct key *session_keyring, enum umh_wait wait) { |