Commit 8cdd4936c17bd8085cb0dfacc4a37ccf8d0ada7b
Committed by
Linus Torvalds
1 parent
b10d911749
Exists in
master
and in
4 other branches
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>
Showing 1 changed file with 30 additions and 1 deletions Side-by-side Diff
kernel/kmod.c
... | ... | @@ -33,12 +33,22 @@ |
33 | 33 | #include <linux/kernel.h> |
34 | 34 | #include <linux/init.h> |
35 | 35 | #include <linux/resource.h> |
36 | +#include <linux/notifier.h> | |
37 | +#include <linux/suspend.h> | |
36 | 38 | #include <asm/uaccess.h> |
37 | 39 | |
38 | 40 | extern int max_threads; |
39 | 41 | |
40 | 42 | static 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 | + */ | |
50 | +static int usermodehelper_disabled; | |
51 | + | |
42 | 52 | #ifdef CONFIG_KMOD |
43 | 53 | |
44 | 54 | /* |
... | ... | @@ -265,6 +275,24 @@ |
265 | 275 | } |
266 | 276 | } |
267 | 277 | |
278 | +static 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 | 297 | * call_usermodehelper_setup - prepare to call a usermode helper |
270 | 298 | * @path - path to usermode executable |
... | ... | @@ -374,7 +402,7 @@ |
374 | 402 | goto out; |
375 | 403 | } |
376 | 404 | |
377 | - if (!khelper_wq) { | |
405 | + if (!khelper_wq || usermodehelper_disabled) { | |
378 | 406 | retval = -EBUSY; |
379 | 407 | goto out; |
380 | 408 | } |
... | ... | @@ -431,5 +459,6 @@ |
431 | 459 | { |
432 | 460 | khelper_wq = create_singlethread_workqueue("khelper"); |
433 | 461 | BUG_ON(!khelper_wq); |
462 | + pm_notifier(usermodehelper_pm_callback, 0); | |
434 | 463 | } |