usermodehelper: Tidy up waiting
Jeremy Fitzhardinge [Wed, 18 Jul 2007 01:37:03 +0000 (18:37 -0700)]
Rather than using a tri-state integer for the wait flag in
call_usermodehelper_exec, define a proper enum, and use that.  I've
preserved the integer values so that any callers I've missed should
still work OK.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Andi Kleen <ak@suse.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Joel Becker <joel.becker@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Srivatsa Vaddagiri <vatsa@in.ibm.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: David Howells <dhowells@redhat.com>

14 files changed:
arch/i386/mach-voyager/voyager_thread.c
arch/x86_64/kernel/mce.c
drivers/macintosh/therm_pm72.c
drivers/macintosh/windfarm_core.c
drivers/net/hamradio/baycom_epp.c
drivers/pnp/pnpbios/core.c
fs/ocfs2/heartbeat.c
include/linux/kmod.h
kernel/cpuset.c
kernel/kmod.c
kernel/sys.c
lib/kobject_uevent.c
net/bridge/br_stp_if.c
security/keys/request_key.c

index b4b24e0..f9d5953 100644 (file)
@@ -52,7 +52,7 @@ execute(const char *string)
                NULL,
        };
 
-       if ((ret = call_usermodehelper(argv[0], argv, envp, 1)) != 0) {
+       if ((ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) {
                printk(KERN_ERR "Voyager failed to run \"%s\": %i\n",
                       string, ret);
        }
index aa1d159..f3fb817 100644 (file)
@@ -174,7 +174,7 @@ static void do_mce_trigger(void)
        if (events != atomic_read(&mce_logged) && trigger[0]) {
                /* Small race window, but should be harmless.  */
                atomic_set(&mce_logged, events);
-               call_usermodehelper(trigger, trigger_argv, NULL, -1);
+               call_usermodehelper(trigger, trigger_argv, NULL, UMH_NO_WAIT);
        }
 }
 
index dbb2240..3d90fc0 100644 (file)
@@ -1770,7 +1770,8 @@ static int call_critical_overtemp(void)
                                "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
                                NULL };
 
-       return call_usermodehelper(critical_overtemp_path, argv, envp, 0);
+       return call_usermodehelper(critical_overtemp_path,
+                                  argv, envp, UMH_WAIT_EXEC);
 }
 
 
index e18d265..516d943 100644 (file)
@@ -80,7 +80,8 @@ int wf_critical_overtemp(void)
                                "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
                                NULL };
 
-       return call_usermodehelper(critical_overtemp_path, argv, envp, 0);
+       return call_usermodehelper(critical_overtemp_path,
+                                  argv, envp, UMH_WAIT_EXEC);
 }
 EXPORT_SYMBOL_GPL(wf_critical_overtemp);
 
index 84aa211..355c6cf 100644 (file)
@@ -320,7 +320,7 @@ static int eppconfig(struct baycom_state *bc)
        sprintf(portarg, "%ld", bc->pdev->port->base);
        printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
 
-       return call_usermodehelper(eppconfig_path, argv, envp, 1);
+       return call_usermodehelper(eppconfig_path, argv, envp, UMH_WAIT_PROC);
 }
 
 /* ---------------------------------------------------------------------- */
index 03baf1c..ed112ee 100644 (file)
@@ -147,7 +147,7 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
                info->location_id, info->serial, info->capabilities);
        envp[i] = NULL;
        
-       value = call_usermodehelper (argv [0], argv, envp, 0);
+       value = call_usermodehelper (argv [0], argv, envp, UMH_WAIT_EXEC);
        kfree (buf);
        kfree (envp);
        return 0;
index 352eb4a..c4c3617 100644 (file)
@@ -209,7 +209,7 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
        envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
        envp[2] = NULL;
 
-       ret = call_usermodehelper(argv[0], argv, envp, 1);
+       ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
        if (ret < 0)
                mlog_errno(ret);
 }
index c4cbe59..5dc1384 100644 (file)
@@ -51,15 +51,21 @@ int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info,
 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 */
+};
+
 /* Actually execute the sub-process */
-int call_usermodehelper_exec(struct subprocess_info *info, int wait);
+int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait);
 
 /* Free the subprocess_info. This is only needed if you're not going
    to call call_usermodehelper_exec */
 void call_usermodehelper_freeinfo(struct subprocess_info *info);
 
 static inline int
-call_usermodehelper(char *path, char **argv, char **envp, int wait)
+call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
 {
        struct subprocess_info *info;
 
@@ -71,7 +77,7 @@ call_usermodehelper(char *path, char **argv, char **envp, int wait)
 
 static inline int
 call_usermodehelper_keys(char *path, char **argv, char **envp,
-                        struct key *session_keyring, int wait)
+                        struct key *session_keyring, enum umh_wait wait)
 {
        struct subprocess_info *info;
 
index b4796d8..57e6448 100644 (file)
@@ -516,7 +516,7 @@ static void cpuset_release_agent(const char *pathbuf)
        envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
        envp[i] = NULL;
 
-       call_usermodehelper(argv[0], argv, envp, 0);
+       call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
        kfree(pathbuf);
 }
 
index d2dce71..78d365c 100644 (file)
@@ -119,7 +119,7 @@ struct subprocess_info {
        char **argv;
        char **envp;
        struct key *ring;
-       int wait;
+       enum umh_wait wait;
        int retval;
        struct file *stdin;
        void (*cleanup)(char **argv, char **envp);
@@ -225,7 +225,7 @@ static int wait_for_helper(void *data)
                        sub_info->retval = ret;
        }
 
-       if (sub_info->wait < 0)
+       if (sub_info->wait == UMH_NO_WAIT)
                call_usermodehelper_freeinfo(sub_info);
        else
                complete(sub_info->complete);
@@ -238,26 +238,31 @@ static void __call_usermodehelper(struct work_struct *work)
        struct subprocess_info *sub_info =
                container_of(work, struct subprocess_info, work);
        pid_t pid;
-       int wait = sub_info->wait;
+       enum umh_wait wait = sub_info->wait;
 
        /* CLONE_VFORK: wait until the usermode helper has execve'd
         * successfully We need the data structures to stay around
         * until that is done.  */
-       if (wait)
+       if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT)
                pid = kernel_thread(wait_for_helper, sub_info,
                                    CLONE_FS | CLONE_FILES | SIGCHLD);
        else
                pid = kernel_thread(____call_usermodehelper, sub_info,
                                    CLONE_VFORK | SIGCHLD);
 
-       if (wait < 0)
-               return;
+       switch (wait) {
+       case UMH_NO_WAIT:
+               break;
 
-       if (pid < 0) {
+       case UMH_WAIT_PROC:
+               if (pid > 0)
+                       break;
                sub_info->retval = pid;
+               /* FALLTHROUGH */
+
+       case UMH_WAIT_EXEC:
                complete(sub_info->complete);
-       } else if (!wait)
-               complete(sub_info->complete);
+       }
 }
 
 /**
@@ -359,7 +364,7 @@ EXPORT_SYMBOL(call_usermodehelper_stdinpipe);
  * (ie. it runs with full root capabilities).
  */
 int call_usermodehelper_exec(struct subprocess_info *sub_info,
-                            int wait)
+                            enum umh_wait wait)
 {
        DECLARE_COMPLETION_ONSTACK(done);
        int retval;
@@ -378,7 +383,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
        sub_info->wait = wait;
 
        queue_work(khelper_wq, &sub_info->work);
-       if (wait < 0) /* task has freed sub_info */
+       if (wait == UMH_NO_WAIT) /* task has freed sub_info */
                return 0;
        wait_for_completion(&done);
        retval = sub_info->retval;
index aeded9a..18987c7 100644 (file)
@@ -2327,7 +2327,7 @@ int orderly_poweroff(bool force)
 
        call_usermodehelper_setcleanup(info, argv_cleanup);
 
-       ret = call_usermodehelper_exec(info, -1);
+       ret = call_usermodehelper_exec(info, UMH_NO_WAIT);
 
   out:
        if (ret && force) {
index 12e311d..bd5ecbb 100644 (file)
@@ -208,7 +208,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
                argv [0] = uevent_helper;
                argv [1] = (char *)subsystem;
                argv [2] = NULL;
-               call_usermodehelper (argv[0], argv, envp, 0);
+               call_usermodehelper (argv[0], argv, envp, UMH_WAIT_EXEC);
        }
 
 exit:
index a786e78..1ea2f86 100644 (file)
@@ -125,7 +125,7 @@ static void br_stp_start(struct net_bridge *br)
        char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL };
        char *envp[] = { NULL };
 
-       r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
+       r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
        if (r == 0) {
                br->stp_enabled = BR_USER_STP;
                printk(KERN_INFO "%s: userspace STP started\n", br->dev->name);
index f573ac1..5575001 100644 (file)
@@ -108,7 +108,8 @@ static int call_sbin_request_key(struct key *key,
        argv[i] = NULL;
 
        /* do it */
-       ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1);
+       ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
+                                      UMH_WAIT_PROC);
 
 error_link:
        key_put(keyring);