aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kmod.c')
-rw-r--r--kernel/kmod.c27
1 files changed, 16 insertions, 11 deletions
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;