Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Rafael J. Wysocki and committed by
Linus Torvalds
8cdd4936 b10d9117

+30 -1
+30 -1
kernel/kmod.c
··· 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; 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; 41 51 42 52 #ifdef CONFIG_KMOD 43 53 ··· 275 265 } 276 266 } 277 267 268 + static int usermodehelper_pm_callback(struct notifier_block *nfb, 269 + unsigned long action, 270 + void *ignored) 271 + { 272 + switch (action) { 273 + case PM_HIBERNATION_PREPARE: 274 + case PM_SUSPEND_PREPARE: 275 + usermodehelper_disabled = 1; 276 + return NOTIFY_OK; 277 + case PM_POST_HIBERNATION: 278 + case PM_POST_SUSPEND: 279 + usermodehelper_disabled = 0; 280 + return NOTIFY_OK; 281 + } 282 + 283 + return NOTIFY_DONE; 284 + } 285 + 278 286 /** 279 287 * call_usermodehelper_setup - prepare to call a usermode helper 280 288 * @path - path to usermode executable ··· 402 374 goto out; 403 375 } 404 376 405 - if (!khelper_wq) { 377 + if (!khelper_wq || usermodehelper_disabled) { 406 378 retval = -EBUSY; 407 379 goto out; 408 380 } ··· 459 431 { 460 432 khelper_wq = create_singlethread_workqueue("khelper"); 461 433 BUG_ON(!khelper_wq); 434 + pm_notifier(usermodehelper_pm_callback, 0); 462 435 }