Exec'ing user space helper programs

From: Thomas Sailer (sailer@ife.ee.ethz.ch)
Date: Fri Feb 11 2000 - 19:15:31 EST

  • Next message: Wakko Warner: "Re: Keyboard lock and yenta"

    kmod calls a user mode helper program (modprobe) to do the work.
    I find this concept generally useful, I have a device that requires
    complex initialization, which is currently done in userspace with
    a helper program. I'd like to keep it that way.

    Exec'ing a user mode program however is not so straigtforward,
    everytime I look into kmod.c the code gets more complex 8-)
    Up to now I just copied the code from kmod.c into my driver,
    but the code duplication starts to get annoying, furthermore
    a couple of routines (free_uid and flush_signal_handlers)
    are not even exported.

    So I'd like to export the exec-facility of kmod.

    The following is a patch to do this.

    Comments?

    Tom

    --- /mnt/hd/s/linux/include/linux/kmod.h Thu Feb 10 06:32:56 2000
    +++ include/linux/kmod.h Fri Feb 11 22:44:31 2000
    @@ -6,7 +6,12 @@
     
     #ifdef CONFIG_KMOD
     extern int request_module(const char * name);
    +extern int exec_usermodehelper(char *program_path, char *argv[], char *envp[]);
     #else
     #define request_module(x) do {} while(0)
    +extern inline int exec_usermodehelper(char *program_path, char *argv[], char *envp[])
    +{
    + return -EACCES;
    +}
     #endif
     
    --- /mnt/hd/s/linux/kernel/kmod.c Fri Jan 7 01:17:18 2000
    +++ kernel/kmod.c Fri Feb 11 22:41:53 2000
    @@ -63,10 +63,8 @@
             unlock_kernel();
     }
     
    -static int exec_modprobe(void * module_name)
    +int exec_usermodehelper(char *program_path, char *argv[], char *envp[])
     {
    - static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
    - char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
             int i;
     
             current->session = 1;
    @@ -101,13 +99,24 @@
             set_fs(KERNEL_DS);
     
             /* Go, go, go... */
    - if (execve(modprobe_path, argv, envp) < 0) {
    + if (execve(program_path, argv, envp) < 0)
    + return -errno;
    + return 0;
    +}
    +
    +static int exec_modprobe(void * module_name)
    +{
    + static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
    + char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
    + int ret;
    +
    + ret = exec_usermodehelper(modprobe_path, argv, envp);
    + if (ret) {
                     printk(KERN_ERR
                            "kmod: failed to exec %s -s -k %s, errno = %d\n",
                            modprobe_path, (char*) module_name, errno);
    - return -errno;
             }
    - return 0;
    + return ret;
     }
     
     /*
    --- /mnt/hd/s/linux/kernel/ksyms.c Sat Feb 12 00:43:52 2000
    +++ kernel/ksyms.c Fri Feb 11 22:36:42 2000
    @@ -74,6 +74,7 @@
     
     #ifdef CONFIG_KMOD
     EXPORT_SYMBOL(request_module);
    +EXPORT_SYMBOL(exec_usermodehelper);
     #endif
     
     #ifdef CONFIG_MODULES

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Sat Feb 12 2000 - 02:30:49 EST