diff options
| author | Robin Holt <holt@sgi.com> | 2013-07-08 19:01:32 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-09 13:33:29 -0400 |
| commit | 15d94b82565ebfb0cf27830b96e6cf5ed2d12a9a (patch) | |
| tree | 21aad9ff42bf328777956e835ef7962bc307da9a /kernel/sys.c | |
| parent | 0efbee70890c992f31a7b294ac654ff6c62d51c5 (diff) | |
reboot: move shutdown/reboot related functions to kernel/reboot.c
This patch is preparatory. It moves reboot related syscall, etc
functions from kernel/sys.c to kernel/reboot.c.
Signed-off-by: Robin Holt <holt@sgi.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Russ Anderson <rja@sgi.com>
Cc: Robin Holt <holt@sgi.com>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 331 |
1 files changed, 0 insertions, 331 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index b882440bd0c0..771129b299f8 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -116,20 +116,6 @@ EXPORT_SYMBOL(fs_overflowuid); | |||
| 116 | EXPORT_SYMBOL(fs_overflowgid); | 116 | EXPORT_SYMBOL(fs_overflowgid); |
| 117 | 117 | ||
| 118 | /* | 118 | /* |
| 119 | * this indicates whether you can reboot with ctrl-alt-del: the default is yes | ||
| 120 | */ | ||
| 121 | |||
| 122 | int C_A_D = 1; | ||
| 123 | struct pid *cad_pid; | ||
| 124 | EXPORT_SYMBOL(cad_pid); | ||
| 125 | |||
| 126 | /* | ||
| 127 | * If set, this is used for preparing the system to power off. | ||
| 128 | */ | ||
| 129 | |||
| 130 | void (*pm_power_off_prepare)(void); | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Returns true if current's euid is same as p's uid or euid, | 119 | * Returns true if current's euid is same as p's uid or euid, |
| 134 | * or has CAP_SYS_NICE to p's user_ns. | 120 | * or has CAP_SYS_NICE to p's user_ns. |
| 135 | * | 121 | * |
| @@ -308,261 +294,6 @@ out_unlock: | |||
| 308 | return retval; | 294 | return retval; |
| 309 | } | 295 | } |
| 310 | 296 | ||
| 311 | /** | ||
| 312 | * emergency_restart - reboot the system | ||
| 313 | * | ||
| 314 | * Without shutting down any hardware or taking any locks | ||
| 315 | * reboot the system. This is called when we know we are in | ||
| 316 | * trouble so this is our best effort to reboot. This is | ||
| 317 | * safe to call in interrupt context. | ||
| 318 | */ | ||
| 319 | void emergency_restart(void) | ||
| 320 | { | ||
| 321 | kmsg_dump(KMSG_DUMP_EMERG); | ||
| 322 | machine_emergency_restart(); | ||
| 323 | } | ||
| 324 | EXPORT_SYMBOL_GPL(emergency_restart); | ||
| 325 | |||
| 326 | void kernel_restart_prepare(char *cmd) | ||
| 327 | { | ||
| 328 | blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); | ||
| 329 | system_state = SYSTEM_RESTART; | ||
| 330 | usermodehelper_disable(); | ||
| 331 | device_shutdown(); | ||
| 332 | } | ||
| 333 | |||
| 334 | /** | ||
| 335 | * register_reboot_notifier - Register function to be called at reboot time | ||
| 336 | * @nb: Info about notifier function to be called | ||
| 337 | * | ||
| 338 | * Registers a function with the list of functions | ||
| 339 | * to be called at reboot time. | ||
| 340 | * | ||
| 341 | * Currently always returns zero, as blocking_notifier_chain_register() | ||
| 342 | * always returns zero. | ||
| 343 | */ | ||
| 344 | int register_reboot_notifier(struct notifier_block *nb) | ||
| 345 | { | ||
| 346 | return blocking_notifier_chain_register(&reboot_notifier_list, nb); | ||
| 347 | } | ||
| 348 | EXPORT_SYMBOL(register_reboot_notifier); | ||
| 349 | |||
| 350 | /** | ||
| 351 | * unregister_reboot_notifier - Unregister previously registered reboot notifier | ||
| 352 | * @nb: Hook to be unregistered | ||
| 353 | * | ||
| 354 | * Unregisters a previously registered reboot | ||
| 355 | * notifier function. | ||
| 356 | * | ||
| 357 | * Returns zero on success, or %-ENOENT on failure. | ||
| 358 | */ | ||
| 359 | int unregister_reboot_notifier(struct notifier_block *nb) | ||
| 360 | { | ||
| 361 | return blocking_notifier_chain_unregister(&reboot_notifier_list, nb); | ||
| 362 | } | ||
| 363 | EXPORT_SYMBOL(unregister_reboot_notifier); | ||
| 364 | |||
| 365 | static void migrate_to_reboot_cpu(void) | ||
| 366 | { | ||
| 367 | /* The boot cpu is always logical cpu 0 */ | ||
| 368 | int cpu = 0; | ||
| 369 | |||
| 370 | cpu_hotplug_disable(); | ||
| 371 | |||
| 372 | /* Make certain the cpu I'm about to reboot on is online */ | ||
| 373 | if (!cpu_online(cpu)) | ||
| 374 | cpu = cpumask_first(cpu_online_mask); | ||
| 375 | |||
| 376 | /* Prevent races with other tasks migrating this task */ | ||
| 377 | current->flags |= PF_NO_SETAFFINITY; | ||
| 378 | |||
| 379 | /* Make certain I only run on the appropriate processor */ | ||
| 380 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); | ||
| 381 | } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * kernel_restart - reboot the system | ||
| 385 | * @cmd: pointer to buffer containing command to execute for restart | ||
| 386 | * or %NULL | ||
| 387 | * | ||
| 388 | * Shutdown everything and perform a clean reboot. | ||
| 389 | * This is not safe to call in interrupt context. | ||
| 390 | */ | ||
| 391 | void kernel_restart(char *cmd) | ||
| 392 | { | ||
| 393 | kernel_restart_prepare(cmd); | ||
| 394 | migrate_to_reboot_cpu(); | ||
| 395 | syscore_shutdown(); | ||
| 396 | if (!cmd) | ||
| 397 | printk(KERN_EMERG "Restarting system.\n"); | ||
| 398 | else | ||
| 399 | printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd); | ||
| 400 | kmsg_dump(KMSG_DUMP_RESTART); | ||
| 401 | machine_restart(cmd); | ||
| 402 | } | ||
| 403 | EXPORT_SYMBOL_GPL(kernel_restart); | ||
| 404 | |||
| 405 | static void kernel_shutdown_prepare(enum system_states state) | ||
| 406 | { | ||
| 407 | blocking_notifier_call_chain(&reboot_notifier_list, | ||
| 408 | (state == SYSTEM_HALT)?SYS_HALT:SYS_POWER_OFF, NULL); | ||
| 409 | system_state = state; | ||
| 410 | usermodehelper_disable(); | ||
| 411 | device_shutdown(); | ||
| 412 | } | ||
| 413 | /** | ||
| 414 | * kernel_halt - halt the system | ||
| 415 | * | ||
| 416 | * Shutdown everything and perform a clean system halt. | ||
| 417 | */ | ||
| 418 | void kernel_halt(void) | ||
| 419 | { | ||
| 420 | kernel_shutdown_prepare(SYSTEM_HALT); | ||
| 421 | migrate_to_reboot_cpu(); | ||
| 422 | syscore_shutdown(); | ||
| 423 | printk(KERN_EMERG "System halted.\n"); | ||
| 424 | kmsg_dump(KMSG_DUMP_HALT); | ||
| 425 | machine_halt(); | ||
| 426 | } | ||
| 427 | |||
| 428 | EXPORT_SYMBOL_GPL(kernel_halt); | ||
| 429 | |||
| 430 | /** | ||
| 431 | * kernel_power_off - power_off the system | ||
| 432 | * | ||
| 433 | * Shutdown everything and perform a clean system power_off. | ||
| 434 | */ | ||
| 435 | void kernel_power_off(void) | ||
| 436 | { | ||
| 437 | kernel_shutdown_prepare(SYSTEM_POWER_OFF); | ||
| 438 | if (pm_power_off_prepare) | ||
| 439 | pm_power_off_prepare(); | ||
| 440 | migrate_to_reboot_cpu(); | ||
| 441 | syscore_shutdown(); | ||
| 442 | printk(KERN_EMERG "Power down.\n"); | ||
| 443 | kmsg_dump(KMSG_DUMP_POWEROFF); | ||
| 444 | machine_power_off(); | ||
| 445 | } | ||
| 446 | EXPORT_SYMBOL_GPL(kernel_power_off); | ||
| 447 | |||
| 448 | static DEFINE_MUTEX(reboot_mutex); | ||
| 449 | |||
| 450 | /* | ||
| 451 | * Reboot system call: for obvious reasons only root may call it, | ||
| 452 | * and even root needs to set up some magic numbers in the registers | ||
| 453 | * so that some mistake won't make this reboot the whole machine. | ||
| 454 | * You can also set the meaning of the ctrl-alt-del-key here. | ||
| 455 | * | ||
| 456 | * reboot doesn't sync: do that yourself before calling this. | ||
| 457 | */ | ||
| 458 | SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, | ||
| 459 | void __user *, arg) | ||
| 460 | { | ||
| 461 | struct pid_namespace *pid_ns = task_active_pid_ns(current); | ||
| 462 | char buffer[256]; | ||
| 463 | int ret = 0; | ||
| 464 | |||
| 465 | /* We only trust the superuser with rebooting the system. */ | ||
| 466 | if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT)) | ||
| 467 | return -EPERM; | ||
| 468 | |||
| 469 | /* For safety, we require "magic" arguments. */ | ||
| 470 | if (magic1 != LINUX_REBOOT_MAGIC1 || | ||
| 471 | (magic2 != LINUX_REBOOT_MAGIC2 && | ||
| 472 | magic2 != LINUX_REBOOT_MAGIC2A && | ||
| 473 | magic2 != LINUX_REBOOT_MAGIC2B && | ||
| 474 | magic2 != LINUX_REBOOT_MAGIC2C)) | ||
| 475 | return -EINVAL; | ||
| 476 | |||
| 477 | /* | ||
| 478 | * If pid namespaces are enabled and the current task is in a child | ||
| 479 | * pid_namespace, the command is handled by reboot_pid_ns() which will | ||
| 480 | * call do_exit(). | ||
| 481 | */ | ||
| 482 | ret = reboot_pid_ns(pid_ns, cmd); | ||
| 483 | if (ret) | ||
| 484 | return ret; | ||
| 485 | |||
| 486 | /* Instead of trying to make the power_off code look like | ||
| 487 | * halt when pm_power_off is not set do it the easy way. | ||
| 488 | */ | ||
| 489 | if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off) | ||
| 490 | cmd = LINUX_REBOOT_CMD_HALT; | ||
