aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-07-19 04:47:36 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:42 -0400
commit8cdd4936c17bd8085cb0dfacc4a37ccf8d0ada7b (patch)
tree0a9ff7cf1b1a797b1267beeb317507210f4dd170
parentb10d911749d37dccfa5873d2088aea3f074b9e45 (diff)
PM: disable usermode helper before hibernation and suspend
Use a hibernation and suspend notifier to disable the user mode helper before a hibernation/suspend and enable it after the operation. [akpm@linux-foundation.org: build fix] Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Acked-by: Nigel Cunningham <nigel@nigel.suspend2.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/kmod.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 78d365c524ed..928f3678142a 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -33,12 +33,22 @@
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/resource.h> 35#include <linux/resource.h>
36#include <linux/notifier.h>
37#include <linux/suspend.h>
36#include <asm/uaccess.h> 38#include <asm/uaccess.h>
37 39
38extern int max_threads; 40extern int max_threads;
39 41
40static struct workqueue_struct *khelper_wq; 42static struct workqueue_struct *khelper_wq;
41 43
44/*
45 * If set, both call_usermodehelper_keys() and call_usermodehelper_pipe() exit
46 * immediately returning -EBUSY. Used for preventing user land processes from
47 * being created after the user land has been frozen during a system-wide
48 * hibernation or suspend operation.
49 */
50static int usermodehelper_disabled;
51
42#ifdef CONFIG_KMOD 52#ifdef CONFIG_KMOD
43 53
44/* 54/*
@@ -265,6 +275,24 @@ static void __call_usermodehelper(struct work_struct *work)
265 } 275 }
266} 276}
267 277
278static int usermodehelper_pm_callback(struct notifier_block *nfb,
279 unsigned long action,
280 void *ignored)
281{
282 switch (action) {
283 case PM_HIBERNATION_PREPARE:
284 case PM_SUSPEND_PREPARE:
285 usermodehelper_disabled = 1;
286 return NOTIFY_OK;
287 case PM_POST_HIBERNATION:
288 case PM_POST_SUSPEND:
289 usermodehelper_disabled = 0;
290 return NOTIFY_OK;
291 }
292
293 return NOTIFY_DONE;
294}
295
268/** 296/**
269 * call_usermodehelper_setup - prepare to call a usermode helper 297 * call_usermodehelper_setup - prepare to call a usermode helper
270 * @path - path to usermode executable 298 * @path - path to usermode executable
@@ -374,7 +402,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
374 goto out; 402 goto out;
375 } 403 }
376 404
377 if (!khelper_wq) { 405 if (!khelper_wq || usermodehelper_disabled) {
378 retval = -EBUSY; 406 retval = -EBUSY;
379 goto out; 407 goto out;
380 } 408 }
@@ -431,4 +459,5 @@ void __init usermodehelper_init(void)
431{ 459{
432 khelper_wq = create_singlethread_workqueue("khelper"); 460 khelper_wq = create_singlethread_workqueue("khelper");
433 BUG_ON(!khelper_wq); 461 BUG_ON(!khelper_wq);
462 pm_notifier(usermodehelper_pm_callback, 0);
434} 463}