aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@xensource.com>2007-07-17 21:37:03 -0400
committerJeremy Fitzhardinge <jeremy@goop.org>2007-07-18 11:47:40 -0400
commit86313c488a6848b7ec2ba04e74f25f79dd32a0b7 (patch)
tree3b190f7afc338362470573b563f65a1eb83795ac /kernel
parent10a0a8d4e3f6bf2d077f94344441909abe670f5a (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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpuset.c2
-rw-r--r--kernel/kmod.c27
-rw-r--r--kernel/sys.c2
3 files changed, 18 insertions, 13 deletions
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) {