diff options
Diffstat (limited to 'kernel/kmod.c')
| -rw-r--r-- | kernel/kmod.c | 67 |
1 files changed, 29 insertions, 38 deletions
diff --git a/kernel/kmod.c b/kernel/kmod.c index 2456d1a0befb..3d3c3ea3a023 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
| @@ -113,7 +113,7 @@ int request_module(const char *fmt, ...) | |||
| 113 | return ret; | 113 | return ret; |
| 114 | } | 114 | } |
| 115 | EXPORT_SYMBOL(request_module); | 115 | EXPORT_SYMBOL(request_module); |
| 116 | #endif /* CONFIG_KMOD */ | 116 | #endif /* CONFIG_MODULES */ |
| 117 | 117 | ||
| 118 | struct subprocess_info { | 118 | struct subprocess_info { |
| 119 | struct work_struct work; | 119 | struct work_struct work; |
| @@ -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 | } |
