diff options
author | Jeremy Fitzhardinge <jeremy@xensource.com> | 2007-07-17 21:37:03 -0400 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy@goop.org> | 2007-07-18 11:47:40 -0400 |
commit | 86313c488a6848b7ec2ba04e74f25f79dd32a0b7 (patch) | |
tree | 3b190f7afc338362470573b563f65a1eb83795ac | |
parent | 10a0a8d4e3f6bf2d077f94344441909abe670f5a (diff) |
usermodehelper: Tidy up waiting
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>
-rw-r--r-- | arch/i386/mach-voyager/voyager_thread.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/mce.c | 2 | ||||
-rw-r--r-- | drivers/macintosh/therm_pm72.c | 3 | ||||
-rw-r--r-- | drivers/macintosh/windfarm_core.c | 3 | ||||
-rw-r--r-- | drivers/net/hamradio/baycom_epp.c | 2 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/core.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/heartbeat.c | 2 | ||||
-rw-r--r-- | include/linux/kmod.h | 12 | ||||
-rw-r--r-- | kernel/cpuset.c | 2 | ||||
-rw-r--r-- | kernel/kmod.c | 27 | ||||
-rw-r--r-- | kernel/sys.c | 2 | ||||
-rw-r--r-- | lib/kobject_uevent.c | 2 | ||||
-rw-r--r-- | net/bridge/br_stp_if.c | 2 | ||||
-rw-r--r-- | security/keys/request_key.c | 3 |
14 files changed, 40 insertions, 26 deletions
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c index b4b24e0e45e1..f9d595338159 100644 --- a/arch/i386/mach-voyager/voyager_thread.c +++ b/arch/i386/mach-voyager/voyager_thread.c | |||
@@ -52,7 +52,7 @@ execute(const char *string) | |||
52 | NULL, | 52 | NULL, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | if ((ret = call_usermodehelper(argv[0], argv, envp, 1)) != 0) { | 55 | if ((ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC)) != 0) { |
56 | printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", | 56 | printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", |
57 | string, ret); | 57 | string, ret); |
58 | } | 58 | } |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index aa1d15991794..f3fb8174559e 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -174,7 +174,7 @@ static void do_mce_trigger(void) | |||
174 | if (events != atomic_read(&mce_logged) && trigger[0]) { | 174 | if (events != atomic_read(&mce_logged) && trigger[0]) { |
175 | /* Small race window, but should be harmless. */ | 175 | /* Small race window, but should be harmless. */ |
176 | atomic_set(&mce_logged, events); | 176 | atomic_set(&mce_logged, events); |
177 | call_usermodehelper(trigger, trigger_argv, NULL, -1); | 177 | call_usermodehelper(trigger, trigger_argv, NULL, UMH_NO_WAIT); |
178 | } | 178 | } |
179 | } | 179 | } |
180 | 180 | ||
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index dbb22403979f..3d90fc002097 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -1770,7 +1770,8 @@ static int call_critical_overtemp(void) | |||
1770 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", | 1770 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", |
1771 | NULL }; | 1771 | NULL }; |
1772 | 1772 | ||
1773 | return call_usermodehelper(critical_overtemp_path, argv, envp, 0); | 1773 | return call_usermodehelper(critical_overtemp_path, |
1774 | argv, envp, UMH_WAIT_EXEC); | ||
1774 | } | 1775 | } |
1775 | 1776 | ||
1776 | 1777 | ||
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index e18d265d5d33..516d943227e2 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
@@ -80,7 +80,8 @@ int wf_critical_overtemp(void) | |||
80 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", | 80 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", |
81 | NULL }; | 81 | NULL }; |
82 | 82 | ||
83 | return call_usermodehelper(critical_overtemp_path, argv, envp, 0); | 83 | return call_usermodehelper(critical_overtemp_path, |
84 | argv, envp, UMH_WAIT_EXEC); | ||
84 | } | 85 | } |
85 | EXPORT_SYMBOL_GPL(wf_critical_overtemp); | 86 | EXPORT_SYMBOL_GPL(wf_critical_overtemp); |
86 | 87 | ||
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 84aa2117c0ee..355c6cf3d112 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -320,7 +320,7 @@ static int eppconfig(struct baycom_state *bc) | |||
320 | sprintf(portarg, "%ld", bc->pdev->port->base); | 320 | sprintf(portarg, "%ld", bc->pdev->port->base); |
321 | printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg); | 321 | printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg); |
322 | 322 | ||
323 | return call_usermodehelper(eppconfig_path, argv, envp, 1); | 323 | return call_usermodehelper(eppconfig_path, argv, envp, UMH_WAIT_PROC); |
324 | } | 324 | } |
325 | 325 | ||
326 | /* ---------------------------------------------------------------------- */ | 326 | /* ---------------------------------------------------------------------- */ |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 03baf1c64a2e..ed112ee16012 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -147,7 +147,7 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) | |||
147 | info->location_id, info->serial, info->capabilities); | 147 | info->location_id, info->serial, info->capabilities); |
148 | envp[i] = NULL; | 148 | envp[i] = NULL; |
149 | 149 | ||
150 | value = call_usermodehelper (argv [0], argv, envp, 0); | 150 | value = call_usermodehelper (argv [0], argv, envp, UMH_WAIT_EXEC); |
151 | kfree (buf); | 151 | kfree (buf); |
152 | kfree (envp); | 152 | kfree (envp); |
153 | return 0; | 153 | return 0; |
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index 352eb4a13f98..c4c36171240d 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c | |||
@@ -209,7 +209,7 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb) | |||
209 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | 209 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; |
210 | envp[2] = NULL; | 210 | envp[2] = NULL; |
211 | 211 | ||
212 | ret = call_usermodehelper(argv[0], argv, envp, 1); | 212 | ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); |
213 | if (ret < 0) | 213 | if (ret < 0) |
214 | mlog_errno(ret); | 214 | mlog_errno(ret); |
215 | } | 215 | } |
diff --git a/include/linux/kmod.h b/include/linux/kmod.h index c4cbe59d9c67..5dc13848891b 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h | |||
@@ -51,15 +51,21 @@ int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info, | |||
51 | void call_usermodehelper_setcleanup(struct subprocess_info *info, | 51 | void call_usermodehelper_setcleanup(struct subprocess_info *info, |
52 | void (*cleanup)(char **argv, char **envp)); | 52 | void (*cleanup)(char **argv, char **envp)); |
53 | 53 | ||
54 | enum umh_wait { | ||
55 | UMH_NO_WAIT = -1, /* don't wait at all */ | ||
56 | UMH_WAIT_EXEC = 0, /* wait for the exec, but not the process */ | ||
57 | UMH_WAIT_PROC = 1, /* wait for the process to complete */ | ||
58 | }; | ||
59 | |||
54 | /* Actually execute the sub-process */ | 60 | /* Actually execute the sub-process */ |
55 | int call_usermodehelper_exec(struct subprocess_info *info, int wait); | 61 | int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait); |
56 | 62 | ||
57 | /* Free the subprocess_info. This is only needed if you're not going | 63 | /* Free the subprocess_info. This is only needed if you're not going |
58 | to call call_usermodehelper_exec */ | 64 | to call call_usermodehelper_exec */ |
59 | void call_usermodehelper_freeinfo(struct subprocess_info *info); | 65 | void call_usermodehelper_freeinfo(struct subprocess_info *info); |
60 | 66 | ||
61 | static inline int | 67 | static inline int |
62 | call_usermodehelper(char *path, char **argv, char **envp, int wait) | 68 | call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait) |
63 | { | 69 | { |
64 | struct subprocess_info *info; | 70 | struct subprocess_info *info; |
65 | 71 | ||
@@ -71,7 +77,7 @@ call_usermodehelper(char *path, char **argv, char **envp, int wait) | |||
71 | 77 | ||
72 | static inline int | 78 | static inline int |
73 | call_usermodehelper_keys(char *path, char **argv, char **envp, | 79 | call_usermodehelper_keys(char *path, char **argv, char **envp, |
74 | struct key *session_keyring, int wait) | 80 | struct key *session_keyring, enum umh_wait wait) |
75 | { | 81 | { |
76 | struct subprocess_info *info; | 82 | struct subprocess_info *info; |
77 | 83 | ||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index b4796d850140..57e6448b171e 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -516,7 +516,7 @@ static void cpuset_release_agent(const char *pathbuf) | |||
516 | envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | 516 | envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; |
517 | envp[i] = NULL; | 517 | envp[i] = NULL; |
518 | 518 | ||
519 | call_usermodehelper(argv[0], argv, envp, 0); | 519 | call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); |
520 | kfree(pathbuf); | 520 | kfree(pathbuf); |
521 | } | 521 | } |
522 | 522 | ||
diff --git a/kernel/kmod.c b/kernel/kmod.c index d2dce71115d8..78d365c524ed 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -119,7 +119,7 @@ struct subprocess_info { | |||
119 | char **argv; | 119 | char **argv; |
120 | char **envp; | 120 | char **envp; |
121 | struct key *ring; | 121 | struct key *ring; |
122 | int wait; | 122 | enum umh_wait wait; |
123 | int retval; | 123 | int retval; |
124 | struct file *stdin; | 124 | struct file *stdin; |
125 | void (*cleanup)(char **argv, char **envp); | 125 | void (*cleanup)(char **argv, char **envp); |
@@ -225,7 +225,7 @@ static int wait_for_helper(void *data) | |||
225 | sub_info->retval = ret; | 225 | sub_info->retval = ret; |
226 | } | 226 | } |
227 | 227 | ||
228 | if (sub_info->wait < 0) | 228 | if (sub_info->wait == UMH_NO_WAIT) |
229 | call_usermodehelper_freeinfo(sub_info); | 229 | call_usermodehelper_freeinfo(sub_info); |
230 | else | 230 | else |
231 | complete(sub_info->complete); | 231 | complete(sub_info->complete); |
@@ -238,26 +238,31 @@ static void __call_usermodehelper(struct work_struct *work) | |||
238 | struct subprocess_info *sub_info = | 238 | struct subprocess_info *sub_info = |
239 | container_of(work, struct subprocess_info, work); | 239 | container_of(work, struct subprocess_info, work); |
240 | pid_t pid; | 240 | pid_t pid; |
241 | int wait = sub_info->wait; | 241 | enum umh_wait wait = sub_info->wait; |
242 | 242 | ||
243 | /* CLONE_VFORK: wait until the usermode helper has execve'd | 243 | /* CLONE_VFORK: wait until the usermode helper has execve'd |
244 | * successfully We need the data structures to stay around | 244 | * successfully We need the data structures to stay around |
245 | * until that is done. */ | 245 | * until that is done. */ |
246 | if (wait) | 246 | if (wait == UMH_WAIT_PROC || wait == UMH_NO_WAIT) |
247 | pid = kernel_thread(wait_for_helper, sub_info, | 247 | pid = kernel_thread(wait_for_helper, sub_info, |
248 | CLONE_FS | CLONE_FILES | SIGCHLD); | 248 | CLONE_FS | CLONE_FILES | SIGCHLD); |
249 | else | 249 | else |
250 | pid = kernel_thread(____call_usermodehelper, sub_info, | 250 | pid = kernel_thread(____call_usermodehelper, sub_info, |
251 | CLONE_VFORK | SIGCHLD); | 251 | CLONE_VFORK | SIGCHLD); |
252 | 252 | ||
253 | if (wait < 0) | 253 | switch (wait) { |
254 | return; | 254 | case UMH_NO_WAIT: |
255 | break; | ||
255 | 256 | ||
256 | if (pid < 0) { | 257 | case UMH_WAIT_PROC: |
258 | if (pid > 0) | ||
259 | break; | ||
257 | sub_info->retval = pid; | 260 | sub_info->retval = pid; |
261 | /* FALLTHROUGH */ | ||
262 | |||
263 | case UMH_WAIT_EXEC: | ||
258 | complete(sub_info->complete); | 264 | complete(sub_info->complete); |
259 | } else if (!wait) | 265 | } |
260 | complete(sub_info->complete); | ||
261 | } | 266 | } |
262 | 267 | ||
263 | /** | 268 | /** |
@@ -359,7 +364,7 @@ EXPORT_SYMBOL(call_usermodehelper_stdinpipe); | |||
359 | * (ie. it runs with full root capabilities). | 364 | * (ie. it runs with full root capabilities). |
360 | */ | 365 | */ |
361 | int call_usermodehelper_exec(struct subprocess_info *sub_info, | 366 | int call_usermodehelper_exec(struct subprocess_info *sub_info, |
362 | int wait) | 367 | enum umh_wait wait) |
363 | { | 368 | { |
364 | DECLARE_COMPLETION_ONSTACK(done); | 369 | DECLARE_COMPLETION_ONSTACK(done); |
365 | int retval; | 370 | int retval; |
@@ -378,7 +383,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, | |||
378 | sub_info->wait = wait; | 383 | sub_info->wait = wait; |
379 | 384 | ||
380 | queue_work(khelper_wq, &sub_info->work); | 385 | queue_work(khelper_wq, &sub_info->work); |
381 | if (wait < 0) /* task has freed sub_info */ | 386 | if (wait == UMH_NO_WAIT) /* task has freed sub_info */ |
382 | return 0; | 387 | return 0; |
383 | wait_for_completion(&done); | 388 | wait_for_completion(&done); |
384 | retval = sub_info->retval; | 389 | retval = sub_info->retval; |
diff --git a/kernel/sys.c b/kernel/sys.c index aeded9ad66ce..18987c7f6add 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -2327,7 +2327,7 @@ int orderly_poweroff(bool force) | |||
2327 | 2327 | ||
2328 | call_usermodehelper_setcleanup(info, argv_cleanup); | 2328 | call_usermodehelper_setcleanup(info, argv_cleanup); |
2329 | 2329 | ||
2330 | ret = call_usermodehelper_exec(info, -1); | 2330 | ret = call_usermodehelper_exec(info, UMH_NO_WAIT); |
2331 | 2331 | ||
2332 | out: | 2332 | out: |
2333 | if (ret && force) { | 2333 | if (ret && force) { |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 12e311dc664c..bd5ecbbafab1 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -208,7 +208,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | |||
208 | argv [0] = uevent_helper; | 208 | argv [0] = uevent_helper; |
209 | argv [1] = (char *)subsystem; | 209 | argv [1] = (char *)subsystem; |
210 | argv [2] = NULL; | 210 | argv [2] = NULL; |
211 | call_usermodehelper (argv[0], argv, envp, 0); | 211 | call_usermodehelper (argv[0], argv, envp, UMH_WAIT_EXEC); |
212 | } | 212 | } |
213 | 213 | ||
214 | exit: | 214 | exit: |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index a786e7863200..1ea2f86f7683 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
@@ -125,7 +125,7 @@ static void br_stp_start(struct net_bridge *br) | |||
125 | char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL }; | 125 | char *argv[] = { BR_STP_PROG, br->dev->name, "start", NULL }; |
126 | char *envp[] = { NULL }; | 126 | char *envp[] = { NULL }; |
127 | 127 | ||
128 | r = call_usermodehelper(BR_STP_PROG, argv, envp, 1); | 128 | r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); |
129 | if (r == 0) { | 129 | if (r == 0) { |
130 | br->stp_enabled = BR_USER_STP; | 130 | br->stp_enabled = BR_USER_STP; |
131 | printk(KERN_INFO "%s: userspace STP started\n", br->dev->name); | 131 | printk(KERN_INFO "%s: userspace STP started\n", br->dev->name); |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index f573ac189a0a..557500110a13 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -108,7 +108,8 @@ static int call_sbin_request_key(struct key *key, | |||
108 | argv[i] = NULL; | 108 | argv[i] = NULL; |
109 | 109 | ||
110 | /* do it */ | 110 | /* do it */ |
111 | ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1); | 111 | ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, |
112 | UMH_WAIT_PROC); | ||
112 | 113 | ||
113 | error_link: | 114 | error_link: |
114 | key_put(keyring); | 115 | key_put(keyring); |