aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/mach-voyager/voyager_thread.c2
-rw-r--r--arch/x86_64/kernel/mce.c2
-rw-r--r--drivers/macintosh/therm_pm72.c3
-rw-r--r--drivers/macintosh/windfarm_core.c3
-rw-r--r--drivers/net/hamradio/baycom_epp.c2
-rw-r--r--drivers/pnp/pnpbios/core.c2
-rw-r--r--fs/ocfs2/heartbeat.c2
-rw-r--r--include/linux/kmod.h12
-rw-r--r--kernel/cpuset.c2
-rw-r--r--kernel/kmod.c27
-rw-r--r--kernel/sys.c2
-rw-r--r--lib/kobject_uevent.c2
-rw-r--r--net/bridge/br_stp_if.c2
-rw-r--r--security/keys/request_key.c3
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}
85EXPORT_SYMBOL_GPL(wf_critical_overtemp); 86EXPORT_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,
51void call_usermodehelper_setcleanup(struct subprocess_info *info, 51void call_usermodehelper_setcleanup(struct subprocess_info *info,
52 void (*cleanup)(char **argv, char **envp)); 52 void (*cleanup)(char **argv, char **envp));
53 53
54enum 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 */
55int call_usermodehelper_exec(struct subprocess_info *info, int wait); 61int 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 */
59void call_usermodehelper_freeinfo(struct subprocess_info *info); 65void call_usermodehelper_freeinfo(struct subprocess_info *info);
60 66
61static inline int 67static inline int
62call_usermodehelper(char *path, char **argv, char **envp, int wait) 68call_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
72static inline int 78static inline int
73call_usermodehelper_keys(char *path, char **argv, char **envp, 79call_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 */
361int call_usermodehelper_exec(struct subprocess_info *sub_info, 366int 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
214exit: 214exit:
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
113error_link: 114error_link:
114 key_put(keyring); 115 key_put(keyring);