LCOV - code coverage report
Current view: top level - kernel - reboot.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 11 124 8.9 %
Date: 2014-04-16 Functions: 1 16 6.2 %
Branches: 8 55 14.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  linux/kernel/reboot.c
       3                 :            :  *
       4                 :            :  *  Copyright (C) 2013  Linus Torvalds
       5                 :            :  */
       6                 :            : 
       7                 :            : #define pr_fmt(fmt)     "reboot: " fmt
       8                 :            : 
       9                 :            : #include <linux/ctype.h>
      10                 :            : #include <linux/export.h>
      11                 :            : #include <linux/kexec.h>
      12                 :            : #include <linux/kmod.h>
      13                 :            : #include <linux/kmsg_dump.h>
      14                 :            : #include <linux/reboot.h>
      15                 :            : #include <linux/suspend.h>
      16                 :            : #include <linux/syscalls.h>
      17                 :            : #include <linux/syscore_ops.h>
      18                 :            : #include <linux/uaccess.h>
      19                 :            : 
      20                 :            : /*
      21                 :            :  * this indicates whether you can reboot with ctrl-alt-del: the default is yes
      22                 :            :  */
      23                 :            : 
      24                 :            : int C_A_D = 1;
      25                 :            : struct pid *cad_pid;
      26                 :            : EXPORT_SYMBOL(cad_pid);
      27                 :            : 
      28                 :            : #if defined(CONFIG_ARM) || defined(CONFIG_UNICORE32)
      29                 :            : #define DEFAULT_REBOOT_MODE             = REBOOT_HARD
      30                 :            : #else
      31                 :            : #define DEFAULT_REBOOT_MODE
      32                 :            : #endif
      33                 :            : enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE;
      34                 :            : 
      35                 :            : /*
      36                 :            :  * This variable is used privately to keep track of whether or not
      37                 :            :  * reboot_type is still set to its default value (i.e., reboot= hasn't
      38                 :            :  * been set on the command line).  This is needed so that we can
      39                 :            :  * suppress DMI scanning for reboot quirks.  Without it, it's
      40                 :            :  * impossible to override a faulty reboot quirk without recompiling.
      41                 :            :  */
      42                 :            : int reboot_default = 1;
      43                 :            : int reboot_cpu;
      44                 :            : enum reboot_type reboot_type = BOOT_ACPI;
      45                 :            : int reboot_force;
      46                 :            : 
      47                 :            : /*
      48                 :            :  * If set, this is used for preparing the system to power off.
      49                 :            :  */
      50                 :            : 
      51                 :            : void (*pm_power_off_prepare)(void);
      52                 :            : 
      53                 :            : /**
      54                 :            :  *      emergency_restart - reboot the system
      55                 :            :  *
      56                 :            :  *      Without shutting down any hardware or taking any locks
      57                 :            :  *      reboot the system.  This is called when we know we are in
      58                 :            :  *      trouble so this is our best effort to reboot.  This is
      59                 :            :  *      safe to call in interrupt context.
      60                 :            :  */
      61                 :          0 : void emergency_restart(void)
      62                 :            : {
      63                 :          0 :         kmsg_dump(KMSG_DUMP_EMERG);
      64                 :            :         machine_emergency_restart();
      65                 :          0 : }
      66                 :            : EXPORT_SYMBOL_GPL(emergency_restart);
      67                 :            : 
      68                 :          0 : void kernel_restart_prepare(char *cmd)
      69                 :            : {
      70                 :          0 :         blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
      71                 :          0 :         system_state = SYSTEM_RESTART;
      72                 :            :         usermodehelper_disable();
      73                 :          0 :         device_shutdown();
      74                 :          0 : }
      75                 :            : 
      76                 :            : /**
      77                 :            :  *      register_reboot_notifier - Register function to be called at reboot time
      78                 :            :  *      @nb: Info about notifier function to be called
      79                 :            :  *
      80                 :            :  *      Registers a function with the list of functions
      81                 :            :  *      to be called at reboot time.
      82                 :            :  *
      83                 :            :  *      Currently always returns zero, as blocking_notifier_chain_register()
      84                 :            :  *      always returns zero.
      85                 :            :  */
      86                 :          0 : int register_reboot_notifier(struct notifier_block *nb)
      87                 :            : {
      88                 :          0 :         return blocking_notifier_chain_register(&reboot_notifier_list, nb);
      89                 :            : }
      90                 :            : EXPORT_SYMBOL(register_reboot_notifier);
      91                 :            : 
      92                 :            : /**
      93                 :            :  *      unregister_reboot_notifier - Unregister previously registered reboot notifier
      94                 :            :  *      @nb: Hook to be unregistered
      95                 :            :  *
      96                 :            :  *      Unregisters a previously registered reboot
      97                 :            :  *      notifier function.
      98                 :            :  *
      99                 :            :  *      Returns zero on success, or %-ENOENT on failure.
     100                 :            :  */
     101                 :          0 : int unregister_reboot_notifier(struct notifier_block *nb)
     102                 :            : {
     103                 :          0 :         return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
     104                 :            : }
     105                 :            : EXPORT_SYMBOL(unregister_reboot_notifier);
     106                 :            : 
     107                 :          0 : void migrate_to_reboot_cpu(void)
     108                 :            : {
     109                 :            :         /* The boot cpu is always logical cpu 0 */
     110                 :          0 :         int cpu = reboot_cpu;
     111                 :            : 
     112                 :          0 :         cpu_hotplug_disable();
     113                 :            : 
     114                 :            :         /* Make certain the cpu I'm about to reboot on is online */
     115         [ #  # ]:          0 :         if (!cpu_online(cpu))
     116                 :            :                 cpu = cpumask_first(cpu_online_mask);
     117                 :            : 
     118                 :            :         /* Prevent races with other tasks migrating this task */
     119                 :          0 :         current->flags |= PF_NO_SETAFFINITY;
     120                 :            : 
     121                 :            :         /* Make certain I only run on the appropriate processor */
     122                 :          0 :         set_cpus_allowed_ptr(current, cpumask_of(cpu));
     123                 :          0 : }
     124                 :            : 
     125                 :            : /**
     126                 :            :  *      kernel_restart - reboot the system
     127                 :            :  *      @cmd: pointer to buffer containing command to execute for restart
     128                 :            :  *              or %NULL
     129                 :            :  *
     130                 :            :  *      Shutdown everything and perform a clean reboot.
     131                 :            :  *      This is not safe to call in interrupt context.
     132                 :            :  */
     133                 :          0 : void kernel_restart(char *cmd)
     134                 :            : {
     135                 :          0 :         kernel_restart_prepare(cmd);
     136                 :          0 :         migrate_to_reboot_cpu();
     137                 :          0 :         syscore_shutdown();
     138         [ #  # ]:          0 :         if (!cmd)
     139                 :          0 :                 pr_emerg("Restarting system\n");
     140                 :            :         else
     141                 :          0 :                 pr_emerg("Restarting system with command '%s'\n", cmd);
     142                 :          0 :         kmsg_dump(KMSG_DUMP_RESTART);
     143                 :          0 :         machine_restart(cmd);
     144                 :          0 : }
     145                 :            : EXPORT_SYMBOL_GPL(kernel_restart);
     146                 :            : 
     147                 :          0 : static void kernel_shutdown_prepare(enum system_states state)
     148                 :            : {
     149         [ #  # ]:          0 :         blocking_notifier_call_chain(&reboot_notifier_list,
     150                 :            :                 (state == SYSTEM_HALT) ? SYS_HALT : SYS_POWER_OFF, NULL);
     151                 :          0 :         system_state = state;
     152                 :            :         usermodehelper_disable();
     153                 :          0 :         device_shutdown();
     154                 :          0 : }
     155                 :            : /**
     156                 :            :  *      kernel_halt - halt the system
     157                 :            :  *
     158                 :            :  *      Shutdown everything and perform a clean system halt.
     159                 :            :  */
     160                 :          0 : void kernel_halt(void)
     161                 :            : {
     162                 :          0 :         kernel_shutdown_prepare(SYSTEM_HALT);
     163                 :          0 :         migrate_to_reboot_cpu();
     164                 :          0 :         syscore_shutdown();
     165                 :          0 :         pr_emerg("System halted\n");
     166                 :          0 :         kmsg_dump(KMSG_DUMP_HALT);
     167                 :          0 :         machine_halt();
     168                 :          0 : }
     169                 :            : EXPORT_SYMBOL_GPL(kernel_halt);
     170                 :            : 
     171                 :            : /**
     172                 :            :  *      kernel_power_off - power_off the system
     173                 :            :  *
     174                 :            :  *      Shutdown everything and perform a clean system power_off.
     175                 :            :  */
     176                 :          0 : void kernel_power_off(void)
     177                 :            : {
     178                 :          0 :         kernel_shutdown_prepare(SYSTEM_POWER_OFF);
     179         [ #  # ]:          0 :         if (pm_power_off_prepare)
     180                 :          0 :                 pm_power_off_prepare();
     181                 :          0 :         migrate_to_reboot_cpu();
     182                 :          0 :         syscore_shutdown();
     183                 :          0 :         pr_emerg("Power down\n");
     184                 :          0 :         kmsg_dump(KMSG_DUMP_POWEROFF);
     185                 :          0 :         machine_power_off();
     186                 :          0 : }
     187                 :            : EXPORT_SYMBOL_GPL(kernel_power_off);
     188                 :            : 
     189                 :            : static DEFINE_MUTEX(reboot_mutex);
     190                 :            : 
     191                 :            : /*
     192                 :            :  * Reboot system call: for obvious reasons only root may call it,
     193                 :            :  * and even root needs to set up some magic numbers in the registers
     194                 :            :  * so that some mistake won't make this reboot the whole machine.
     195                 :            :  * You can also set the meaning of the ctrl-alt-del-key here.
     196                 :            :  *
     197                 :            :  * reboot doesn't sync: do that yourself before calling this.
     198                 :            :  */
     199                 :          0 : SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
     200                 :            :                 void __user *, arg)
     201                 :            : {
     202                 :          4 :         struct pid_namespace *pid_ns = task_active_pid_ns(current);
     203                 :            :         char buffer[256];
     204                 :            :         int ret = 0;
     205                 :            : 
     206                 :            :         /* We only trust the superuser with rebooting the system. */
     207         [ +  + ]:          4 :         if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))
     208                 :            :                 return -EPERM;
     209                 :            : 
     210                 :            :         /* For safety, we require "magic" arguments. */
     211 [ +  - ][ -  + ]:          3 :         if (magic1 != LINUX_REBOOT_MAGIC1 ||
     212                 :          6 :                         (magic2 != LINUX_REBOOT_MAGIC2 &&
     213                 :          3 :                         magic2 != LINUX_REBOOT_MAGIC2A &&
     214         [ #  # ]:          0 :                         magic2 != LINUX_REBOOT_MAGIC2B &&
     215                 :          0 :                         magic2 != LINUX_REBOOT_MAGIC2C))
     216                 :            :                 return -EINVAL;
     217                 :            : 
     218                 :            :         /*
     219                 :            :          * If pid namespaces are enabled and the current task is in a child
     220                 :            :          * pid_namespace, the command is handled by reboot_pid_ns() which will
     221                 :            :          * call do_exit().
     222                 :            :          */
     223                 :            :         ret = reboot_pid_ns(pid_ns, cmd);
     224                 :            :         if (ret)
     225                 :            :                 return ret;
     226                 :            : 
     227                 :            :         /* Instead of trying to make the power_off code look like
     228                 :            :          * halt when pm_power_off is not set do it the easy way.
     229                 :            :          */
     230 [ -  + ][ #  # ]:          3 :         if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
     231                 :            :                 cmd = LINUX_REBOOT_CMD_HALT;
     232                 :            : 
     233                 :          3 :         mutex_lock(&reboot_mutex);
     234   [ -  +  +  -  :          3 :         switch (cmd) {
                -  -  + ]
     235                 :            :         case LINUX_REBOOT_CMD_RESTART:
     236                 :          0 :                 kernel_restart(NULL);
     237                 :            :                 break;
     238                 :            : 
     239                 :            :         case LINUX_REBOOT_CMD_CAD_ON:
     240                 :          1 :                 C_A_D = 1;
     241                 :            :                 break;
     242                 :            : 
     243                 :            :         case LINUX_REBOOT_CMD_CAD_OFF:
     244                 :          1 :                 C_A_D = 0;
     245                 :            :                 break;
     246                 :            : 
     247                 :            :         case LINUX_REBOOT_CMD_HALT:
     248                 :          0 :                 kernel_halt();
     249                 :          0 :                 do_exit(0);
     250                 :            :                 panic("cannot halt");
     251                 :            : 
     252                 :            :         case LINUX_REBOOT_CMD_POWER_OFF:
     253                 :          0 :                 kernel_power_off();
     254                 :          0 :                 do_exit(0);
     255                 :            :                 break;
     256                 :            : 
     257                 :            :         case LINUX_REBOOT_CMD_RESTART2:
     258                 :          0 :                 ret = strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1);
     259         [ #  # ]:          0 :                 if (ret < 0) {
     260                 :            :                         ret = -EFAULT;
     261                 :            :                         break;
     262                 :            :                 }
     263                 :          0 :                 buffer[sizeof(buffer) - 1] = '\0';
     264                 :            : 
     265                 :          0 :                 kernel_restart(buffer);
     266                 :            :                 break;
     267                 :            : 
     268                 :            : #ifdef CONFIG_KEXEC
     269                 :            :         case LINUX_REBOOT_CMD_KEXEC:
     270                 :            :                 ret = kernel_kexec();
     271                 :            :                 break;
     272                 :            : #endif
     273                 :            : 
     274                 :            : #ifdef CONFIG_HIBERNATION
     275                 :            :         case LINUX_REBOOT_CMD_SW_SUSPEND:
     276                 :            :                 ret = hibernate();
     277                 :            :                 break;
     278                 :            : #endif
     279                 :            : 
     280                 :            :         default:
     281                 :            :                 ret = -EINVAL;
     282                 :            :                 break;
     283                 :            :         }
     284                 :          3 :         mutex_unlock(&reboot_mutex);
     285                 :            :         return ret;
     286                 :            : }
     287                 :            : 
     288                 :          0 : static void deferred_cad(struct work_struct *dummy)
     289                 :            : {
     290                 :          0 :         kernel_restart(NULL);
     291                 :          0 : }
     292                 :            : 
     293                 :            : /*
     294                 :            :  * This function gets called by ctrl-alt-del - ie the keyboard interrupt.
     295                 :            :  * As it's called within an interrupt, it may NOT sync: the only choice
     296                 :            :  * is whether to reboot at once, or just ignore the ctrl-alt-del.
     297                 :            :  */
     298                 :          0 : void ctrl_alt_del(void)
     299                 :            : {
     300                 :            :         static DECLARE_WORK(cad_work, deferred_cad);
     301                 :            : 
     302         [ #  # ]:          0 :         if (C_A_D)
     303                 :            :                 schedule_work(&cad_work);
     304                 :            :         else
     305                 :            :                 kill_cad_pid(SIGINT, 1);
     306                 :          0 : }
     307                 :            : 
     308                 :            : char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
     309                 :            : 
     310                 :          0 : static int __orderly_poweroff(bool force)
     311                 :            : {
     312                 :            :         char **argv;
     313                 :            :         static char *envp[] = {
     314                 :            :                 "HOME=/",
     315                 :            :                 "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
     316                 :            :                 NULL
     317                 :            :         };
     318                 :            :         int ret;
     319                 :            : 
     320                 :          0 :         argv = argv_split(GFP_KERNEL, poweroff_cmd, NULL);
     321         [ #  # ]:          0 :         if (argv) {
     322                 :          0 :                 ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
     323                 :          0 :                 argv_free(argv);
     324                 :            :         } else {
     325                 :            :                 ret = -ENOMEM;
     326                 :            :         }
     327                 :            : 
     328         [ #  # ]:          0 :         if (ret && force) {
     329                 :          0 :                 pr_warn("Failed to start orderly shutdown: forcing the issue\n");
     330                 :            :                 /*
     331                 :            :                  * I guess this should try to kick off some daemon to sync and
     332                 :            :                  * poweroff asap.  Or not even bother syncing if we're doing an
     333                 :            :                  * emergency shutdown?
     334                 :            :                  */
     335                 :          0 :                 emergency_sync();
     336                 :          0 :                 kernel_power_off();
     337                 :            :         }
     338                 :            : 
     339                 :          0 :         return ret;
     340                 :            : }
     341                 :            : 
     342                 :            : static bool poweroff_force;
     343                 :            : 
     344                 :          0 : static void poweroff_work_func(struct work_struct *work)
     345                 :            : {
     346                 :          0 :         __orderly_poweroff(poweroff_force);
     347                 :          0 : }
     348                 :            : 
     349                 :            : static DECLARE_WORK(poweroff_work, poweroff_work_func);
     350                 :            : 
     351                 :            : /**
     352                 :            :  * orderly_poweroff - Trigger an orderly system poweroff
     353                 :            :  * @force: force poweroff if command execution fails
     354                 :            :  *
     355                 :            :  * This may be called from any context to trigger a system shutdown.
     356                 :            :  * If the orderly shutdown fails, it will force an immediate shutdown.
     357                 :            :  */
     358                 :          0 : int orderly_poweroff(bool force)
     359                 :            : {
     360         [ #  # ]:          0 :         if (force) /* do not override the pending "true" */
     361                 :          0 :                 poweroff_force = true;
     362                 :            :         schedule_work(&poweroff_work);
     363                 :          0 :         return 0;
     364                 :            : }
     365                 :            : EXPORT_SYMBOL_GPL(orderly_poweroff);
     366                 :            : 
     367                 :          0 : static int __init reboot_setup(char *str)
     368                 :            : {
     369                 :            :         for (;;) {
     370                 :            :                 /*
     371                 :            :                  * Having anything passed on the command line via
     372                 :            :                  * reboot= will cause us to disable DMI checking
     373                 :            :                  * below.
     374                 :            :                  */
     375                 :          0 :                 reboot_default = 0;
     376                 :            : 
     377   [ #  #  #  #  :          0 :                 switch (*str) {
             #  #  #  # ]
     378                 :            :                 case 'w':
     379                 :          0 :                         reboot_mode = REBOOT_WARM;
     380                 :          0 :                         break;
     381                 :            : 
     382                 :            :                 case 'c':
     383                 :          0 :                         reboot_mode = REBOOT_COLD;
     384                 :          0 :                         break;
     385                 :            : 
     386                 :            :                 case 'h':
     387                 :          0 :                         reboot_mode = REBOOT_HARD;
     388                 :          0 :                         break;
     389                 :            : 
     390                 :            :                 case 's':
     391         [ #  # ]:          0 :                         if (isdigit(*(str+1)))
     392                 :          0 :                                 reboot_cpu = simple_strtoul(str+1, NULL, 0);
     393 [ #  # ][ #  # ]:          0 :                         else if (str[1] == 'm' && str[2] == 'p' &&
                 [ #  # ]
     394                 :          0 :                                                         isdigit(*(str+3)))
     395                 :          0 :                                 reboot_cpu = simple_strtoul(str+3, NULL, 0);
     396                 :            :                         else
     397                 :          0 :                                 reboot_mode = REBOOT_SOFT;
     398                 :            :                         break;
     399                 :            : 
     400                 :            :                 case 'g':
     401                 :          0 :                         reboot_mode = REBOOT_GPIO;
     402                 :          0 :                         break;
     403                 :            : 
     404                 :            :                 case 'b':
     405                 :            :                 case 'a':
     406                 :            :                 case 'k':
     407                 :            :                 case 't':
     408                 :            :                 case 'e':
     409                 :            :                 case 'p':
     410                 :          0 :                         reboot_type = *str;
     411                 :          0 :                         break;
     412                 :            : 
     413                 :            :                 case 'f':
     414                 :          0 :                         reboot_force = 1;
     415                 :          0 :                         break;
     416                 :            :                 }
     417                 :            : 
     418                 :          0 :                 str = strchr(str, ',');
     419         [ #  # ]:          0 :                 if (str)
     420                 :          0 :                         str++;
     421                 :            :                 else
     422                 :            :                         break;
     423                 :          0 :         }
     424                 :          0 :         return 1;
     425                 :            : }
     426                 :            : __setup("reboot=", reboot_setup);

Generated by: LCOV version 1.9