diff options
-rw-r--r-- | include/linux/kmod.h | 3 | ||||
-rw-r--r-- | kernel/kmod.c | 65 | ||||
-rw-r--r-- | kernel/power/disk.c | 11 | ||||
-rw-r--r-- | kernel/power/main.c | 7 | ||||
-rw-r--r-- | kernel/power/user.c | 10 |
5 files changed, 58 insertions, 38 deletions
diff --git a/include/linux/kmod.h b/include/linux/kmod.h index a1a91577813c..92213a9194e1 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h | |||
@@ -99,4 +99,7 @@ struct file; | |||
99 | extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[], | 99 | extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[], |
100 | struct file **filp); | 100 | struct file **filp); |
101 | 101 | ||
102 | extern int usermodehelper_disable(void); | ||
103 | extern void usermodehelper_enable(void); | ||
104 | |||
102 | #endif /* __LINUX_KMOD_H__ */ | 105 | #endif /* __LINUX_KMOD_H__ */ |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 2456d1a0befb..ab7dd08472fc 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -265,7 +265,7 @@ static void __call_usermodehelper(struct work_struct *work) | |||
265 | } | 265 | } |
266 | } | 266 | } |
267 | 267 | ||
268 | #ifdef CONFIG_PM | 268 | #ifdef CONFIG_PM_SLEEP |
269 | /* | 269 | /* |
270 | * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY | 270 | * If set, call_usermodehelper_exec() will exit immediately returning -EBUSY |
271 | * (used for preventing user land processes from being created after the user | 271 | * (used for preventing user land processes from being created after the user |
@@ -288,39 +288,37 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); | |||
288 | */ | 288 | */ |
289 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) | 289 | #define RUNNING_HELPERS_TIMEOUT (5 * HZ) |
290 | 290 | ||
291 | static int usermodehelper_pm_callback(struct notifier_block *nfb, | 291 | /** |
292 | unsigned long action, | 292 | * usermodehelper_disable - prevent new helpers from being started |
293 | void *ignored) | 293 | */ |
294 | int usermodehelper_disable(void) | ||
294 | { | 295 | { |
295 | long retval; | 296 | long retval; |
296 | 297 | ||
297 | switch (action) { | 298 | usermodehelper_disabled = 1; |
298 | case PM_HIBERNATION_PREPARE: | 299 | smp_mb(); |
299 | case PM_SUSPEND_PREPARE: | 300 | /* |
300 | usermodehelper_disabled = 1; | 301 | * From now on call_usermodehelper_exec() won't start any new |
301 | smp_mb(); | 302 | * helpers, so it is sufficient if running_helpers turns out to |
302 | /* | 303 | * be zero at one point (it may be increased later, but that |
303 | * From now on call_usermodehelper_exec() won't start any new | 304 | * doesn't matter). |
304 | * helpers, so it is sufficient if running_helpers turns out to | 305 | */ |
305 | * be zero at one point (it may be increased later, but that | 306 | retval = wait_event_timeout(running_helpers_waitq, |
306 | * doesn't matter). | ||
307 | */ | ||
308 | retval = wait_event_timeout(running_helpers_waitq, | ||
309 | atomic_read(&running_helpers) == 0, | 307 | atomic_read(&running_helpers) == 0, |
310 | RUNNING_HELPERS_TIMEOUT); | 308 | RUNNING_HELPERS_TIMEOUT); |
311 | if (retval) { | 309 | if (retval) |
312 | return NOTIFY_OK; | 310 | return 0; |
313 | } else { | ||
314 | usermodehelper_disabled = 0; | ||
315 | return NOTIFY_BAD; | ||
316 | } | ||
317 | case PM_POST_HIBERNATION: | ||
318 | case PM_POST_SUSPEND: | ||
319 | usermodehelper_disabled = 0; | ||
320 | return NOTIFY_OK; | ||
321 | } | ||
322 | 311 | ||
323 | return NOTIFY_DONE; | 312 | usermodehelper_disabled = 0; |
313 | return -EAGAIN; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * usermodehelper_enable - allow new helpers to be started again | ||
318 | */ | ||
319 | void usermodehelper_enable(void) | ||
320 | { | ||
321 | usermodehelper_disabled = 0; | ||
324 | } | 322 | } |
325 | 323 | ||
326 | static void helper_lock(void) | 324 | static void helper_lock(void) |
@@ -334,18 +332,12 @@ static void helper_unlock(void) | |||
334 | if (atomic_dec_and_test(&running_helpers)) | 332 | if (atomic_dec_and_test(&running_helpers)) |
335 | wake_up(&running_helpers_waitq); | 333 | wake_up(&running_helpers_waitq); |
336 | } | 334 | } |
337 | 335 | #else /* CONFIG_PM_SLEEP */ | |
338 | static void register_pm_notifier_callback(void) | ||
339 | { | ||
340 | pm_notifier(usermodehelper_pm_callback, 0); | ||
341 | } | ||
342 | #else /* CONFIG_PM */ | ||
343 | #define usermodehelper_disabled 0 | 336 | #define usermodehelper_disabled 0 |
344 | 337 | ||
345 | static inline void helper_lock(void) {} | 338 | static inline void helper_lock(void) {} |
346 | static inline void helper_unlock(void) {} | 339 | static inline void helper_unlock(void) {} |
347 | static inline void register_pm_notifier_callback(void) {} | 340 | #endif /* CONFIG_PM_SLEEP */ |
348 | #endif /* CONFIG_PM */ | ||
349 | 341 | ||
350 | /** | 342 | /** |
351 | * call_usermodehelper_setup - prepare to call a usermode helper | 343 | * call_usermodehelper_setup - prepare to call a usermode helper |
@@ -515,5 +507,4 @@ void __init usermodehelper_init(void) | |||
515 | { | 507 | { |
516 | khelper_wq = create_singlethread_workqueue("khelper"); | 508 | khelper_wq = create_singlethread_workqueue("khelper"); |
517 | BUG_ON(!khelper_wq); | 509 | BUG_ON(!khelper_wq); |
518 | register_pm_notifier_callback(); | ||
519 | } | 510 | } |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index bbd85c60f741..331f9836383f 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/reboot.h> | 14 | #include <linux/reboot.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/kmod.h> | ||
17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
18 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
19 | #include <linux/mount.h> | 20 | #include <linux/mount.h> |
@@ -520,6 +521,10 @@ int hibernate(void) | |||
520 | if (error) | 521 | if (error) |
521 | goto Exit; | 522 | goto Exit; |
522 | 523 | ||
524 | error = usermodehelper_disable(); | ||
525 | if (error) | ||
526 | goto Exit; | ||
527 | |||
523 | /* Allocate memory management structures */ | 528 | /* Allocate memory management structures */ |
524 | error = create_basic_memory_bitmaps(); | 529 | error = create_basic_memory_bitmaps(); |
525 | if (error) | 530 | if (error) |
@@ -558,6 +563,7 @@ int hibernate(void) | |||
558 | thaw_processes(); | 563 | thaw_processes(); |
559 | Finish: | 564 | Finish: |
560 | free_basic_memory_bitmaps(); | 565 | free_basic_memory_bitmaps(); |
566 | usermodehelper_enable(); | ||
561 | Exit: | 567 | Exit: |
562 | pm_notifier_call_chain(PM_POST_HIBERNATION); | 568 | pm_notifier_call_chain(PM_POST_HIBERNATION); |
563 | pm_restore_console(); | 569 | pm_restore_console(); |
@@ -634,6 +640,10 @@ static int software_resume(void) | |||
634 | if (error) | 640 | if (error) |
635 | goto Finish; | 641 | goto Finish; |
636 | 642 | ||
643 | error = usermodehelper_disable(); | ||
644 | if (error) | ||
645 | goto Finish; | ||
646 | |||
637 | error = create_basic_memory_bitmaps(); | 647 | error = create_basic_memory_bitmaps(); |
638 | if (error) | 648 | if (error) |
639 | goto Finish; | 649 | goto Finish; |
@@ -656,6 +666,7 @@ static int software_resume(void) | |||
656 | thaw_processes(); | 666 | thaw_processes(); |
657 | Done: | 667 | Done: |
658 | free_basic_memory_bitmaps(); | 668 | free_basic_memory_bitmaps(); |
669 | usermodehelper_enable(); | ||
659 | Finish: | 670 | Finish: |
660 | pm_notifier_call_chain(PM_POST_RESTORE); | 671 | pm_notifier_call_chain(PM_POST_RESTORE); |
661 | pm_restore_console(); | 672 | pm_restore_console(); |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 540b16b68565..19122cf6d827 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/kmod.h> | ||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/console.h> | 19 | #include <linux/console.h> |
19 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
@@ -237,6 +238,10 @@ static int suspend_prepare(void) | |||
237 | if (error) | 238 | if (error) |
238 | goto Finish; | 239 | goto Finish; |
239 | 240 | ||
241 | error = usermodehelper_disable(); | ||
242 | if (error) | ||
243 | goto Finish; | ||
244 | |||
240 | if (suspend_freeze_processes()) { | 245 | if (suspend_freeze_processes()) { |
241 | error = -EAGAIN; | 246 | error = -EAGAIN; |
242 | goto Thaw; | 247 | goto Thaw; |
@@ -256,6 +261,7 @@ static int suspend_prepare(void) | |||
256 | 261 | ||
257 | Thaw: | 262 | Thaw: |
258 | suspend_thaw_processes(); | 263 | suspend_thaw_processes(); |
264 | usermodehelper_enable(); | ||
259 | Finish: | 265 | Finish: |
260 | pm_notifier_call_chain(PM_POST_SUSPEND); | 266 | pm_notifier_call_chain(PM_POST_SUSPEND); |
261 | pm_restore_console(); | 267 | pm_restore_console(); |
@@ -376,6 +382,7 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
376 | static void suspend_finish(void) | 382 | static void suspend_finish(void) |
377 | { | 383 | { |
378 | suspend_thaw_processes(); | 384 | suspend_thaw_processes(); |
385 | usermodehelper_enable(); | ||
379 | pm_notifier_call_chain(PM_POST_SUSPEND); | 386 | pm_notifier_call_chain(PM_POST_SUSPEND); |
380 | pm_restore_console(); | 387 | pm_restore_console(); |
381 | } | 388 | } |
diff --git a/kernel/power/user.c b/kernel/power/user.c index a6332a313262..005b93d839ba 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -212,13 +212,20 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
212 | case SNAPSHOT_FREEZE: | 212 | case SNAPSHOT_FREEZE: |
213 | if (data->frozen) | 213 | if (data->frozen) |
214 | break; | 214 | break; |
215 | |||
215 | printk("Syncing filesystems ... "); | 216 | printk("Syncing filesystems ... "); |
216 | sys_sync(); | 217 | sys_sync(); |
217 | printk("done.\n"); | 218 | printk("done.\n"); |
218 | 219 | ||
219 | error = freeze_processes(); | 220 | error = usermodehelper_disable(); |
220 | if (error) | 221 | if (error) |
222 | break; | ||
223 | |||
224 | error = freeze_processes(); | ||
225 | if (error) { | ||
221 | thaw_processes(); | 226 | thaw_processes(); |
227 | usermodehelper_enable(); | ||
228 | } | ||
222 | if (!error) | 229 | if (!error) |
223 | data->frozen = 1; | 230 | data->frozen = 1; |
224 | break; | 231 | break; |
@@ -227,6 +234,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
227 | if (!data->frozen || data->ready) | 234 | if (!data->frozen || data->ready) |
228 | break; | 235 | break; |
229 | thaw_processes(); | 236 | thaw_processes(); |
237 | usermodehelper_enable(); | ||
230 | data->frozen = 0; | 238 | data->frozen = 0; |
231 | break; | 239 | break; |
232 | 240 | ||