usermodehelper在Linux内核中直接运行用户空间程序(2)



 105static inline int
 106call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
 107{
 108        return call_usermodehelper_fns(path, argv, envp, wait,
 109                                       NULL, NULL, NULL);
 110}
 111


  50enum umh_wait {
  51        UMH_NO_WAIT = -1,       /* don't wait at all */
  52        UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
  53        UMH_WAIT_PROC = 1,      /* wait for the process to complete */
  54};
  55
  56struct subprocess_info {
  57        struct work_struct work;
  58        struct completion *complete;
  59        char *path;
  60        char **argv;
  61        char **envp;
  62        enum umh_wait wait;
  63        int retval;
  64        int (*init)(struct subprocess_info *info);
  65        void (*cleanup)(struct subprocess_info *info);
  66        void *data;
  67};
  68


kernel/kmod.c实现文件

377/**
 378 * call_usermodehelper_exec - start a usermode application
 379 * @sub_info: information about the subprocessa  子进程的信息
 380 * @wait: wait for the application to finish and return status.等待用户空间子进程的完成,并返回结果。
 381 *        when -1 don't wait at all, but you get no useful error back when
 382 *        the program couldn't be exec'ed. This makes it safe to call
 383 *        from interrupt context.
-1表示根本不等待子进程的结束。 但这样你就无法对程序出错进行处理。
如果使用中断上下文,那么应该使用-1。
 384 *
 385 * Runs a user-space application.  The application is started
 386 * asynchronously if wait is not set, and runs as a child of keventd.
 387 * (ie. it runs with full root capabilities).
call_usermodehelper_exec函数,启动一个用户模式应用程序。
如果不设置wait,那么用户空间应用程序会被异步启动。  它在root权限下运行。是keventd进程的子进程。


 388 */
 389int call_usermodehelper_exec(struct subprocess_info *sub_info,
 390                             enum umh_wait wait)
 391{
 392        DECLARE_COMPLETION_ONSTACK(done);
 393        int retval = 0;
 394
 395        helper_lock();
 396        if (sub_info->path[0] == '\0')
 397                goto out;
 398
 399        if (!khelper_wq || usermodehelper_disabled) {
 400                retval = -EBUSY;
 401                goto out;
 402        }
 403
 404        sub_info->complete = &done;
 405        sub_info->wait = wait;
 406把用户空间进程挂到一个内核工作队列。
 407        queue_work(khelper_wq, &sub_info->work);
 408        if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
 409                goto unlock;
如果等待子进程完成,那么执行等待完成的  事件通知和唤醒。就是说当前进程sleep。
 410        wait_for_completion(&done);
 411        retval = sub_info->retval;
 412
 413out:
 414        call_usermodehelper_freeinfo(sub_info);
 415unlock:
 416        helper_unlock();
 417        return retval;
 418}
 419EXPORT_SYMBOL(call_usermodehelper_exec);
 420
 421void __init usermodehelper_init(void)
 422{
 423        khelper_wq = create_singlethread_workqueue("khelper");
 424        BUG_ON(!khelper_wq);
 425}



内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjxsp.html