LCOV - code coverage report
Current view: top level - core - emergency-action.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 15 77 19.5 %
Date: 2019-08-23 13:36:53 Functions: 4 5 80.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 16 67 23.9 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <sys/reboot.h>
       4                 :            : 
       5                 :            : #include "bus-error.h"
       6                 :            : #include "bus-util.h"
       7                 :            : #include "emergency-action.h"
       8                 :            : #include "raw-reboot.h"
       9                 :            : #include "reboot-util.h"
      10                 :            : #include "special.h"
      11                 :            : #include "string-table.h"
      12                 :            : #include "terminal-util.h"
      13                 :            : #include "virt.h"
      14                 :            : 
      15                 :          0 : static void log_and_status(Manager *m, bool warn, const char *message, const char *reason) {
      16   [ #  #  #  # ]:          0 :         log_full(warn ? LOG_WARNING : LOG_DEBUG, "%s: %s", message, reason);
      17         [ #  # ]:          0 :         if (warn)
      18                 :          0 :                 manager_status_printf(m, STATUS_TYPE_EMERGENCY,
      19                 :            :                                       ANSI_HIGHLIGHT_RED "  !!  " ANSI_NORMAL,
      20                 :            :                                       "%s: %s", message, reason);
      21                 :          0 : }
      22                 :            : 
      23                 :         28 : void emergency_action(
      24                 :            :                 Manager *m,
      25                 :            :                 EmergencyAction action,
      26                 :            :                 EmergencyActionFlags options,
      27                 :            :                 const char *reboot_arg,
      28                 :            :                 int exit_status,
      29                 :            :                 const char *reason) {
      30                 :            : 
      31         [ -  + ]:         28 :         assert(m);
      32         [ -  + ]:         28 :         assert(action >= 0);
      33         [ -  + ]:         28 :         assert(action < _EMERGENCY_ACTION_MAX);
      34                 :            : 
      35         [ +  - ]:         28 :         if (action == EMERGENCY_ACTION_NONE)
      36                 :         28 :                 return;
      37                 :            : 
      38   [ #  #  #  # ]:          0 :         if (FLAGS_SET(options, EMERGENCY_ACTION_IS_WATCHDOG) && !m->service_watchdogs) {
      39         [ #  # ]:          0 :                 log_warning("Watchdog disabled! Not acting on: %s", reason);
      40                 :          0 :                 return;
      41                 :            :         }
      42                 :            : 
      43                 :          0 :         bool warn = FLAGS_SET(options, EMERGENCY_ACTION_WARN);
      44                 :            : 
      45   [ #  #  #  #  :          0 :         switch (action) {
             #  #  #  #  
                      # ]
      46                 :            : 
      47                 :          0 :         case EMERGENCY_ACTION_REBOOT:
      48                 :          0 :                 log_and_status(m, warn, "Rebooting", reason);
      49                 :            : 
      50                 :          0 :                 (void) update_reboot_parameter_and_warn(reboot_arg, true);
      51                 :          0 :                 (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL);
      52                 :          0 :                 break;
      53                 :            : 
      54                 :          0 :         case EMERGENCY_ACTION_REBOOT_FORCE:
      55                 :          0 :                 log_and_status(m, warn, "Forcibly rebooting", reason);
      56                 :            : 
      57                 :          0 :                 (void) update_reboot_parameter_and_warn(reboot_arg, true);
      58                 :          0 :                 m->objective = MANAGER_REBOOT;
      59                 :            : 
      60                 :          0 :                 break;
      61                 :            : 
      62                 :          0 :         case EMERGENCY_ACTION_REBOOT_IMMEDIATE:
      63                 :          0 :                 log_and_status(m, warn, "Rebooting immediately", reason);
      64                 :            : 
      65                 :          0 :                 sync();
      66                 :            : 
      67         [ #  # ]:          0 :                 if (!isempty(reboot_arg)) {
      68         [ #  # ]:          0 :                         log_info("Rebooting with argument '%s'.", reboot_arg);
      69                 :          0 :                         (void) raw_reboot(LINUX_REBOOT_CMD_RESTART2, reboot_arg);
      70         [ #  # ]:          0 :                         log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
      71                 :            :                 }
      72                 :            : 
      73         [ #  # ]:          0 :                 log_info("Rebooting.");
      74                 :          0 :                 (void) reboot(RB_AUTOBOOT);
      75                 :          0 :                 break;
      76                 :            : 
      77                 :          0 :         case EMERGENCY_ACTION_EXIT:
      78                 :            : 
      79         [ #  # ]:          0 :                 if (exit_status >= 0)
      80                 :          0 :                         m->return_value = exit_status;
      81                 :            : 
      82   [ #  #  #  # ]:          0 :                 if (MANAGER_IS_USER(m) || detect_container() > 0) {
      83                 :          0 :                         log_and_status(m, warn, "Exiting", reason);
      84                 :          0 :                         (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL);
      85                 :          0 :                         break;
      86                 :            :                 }
      87                 :            : 
      88         [ #  # ]:          0 :                 log_notice("Doing \"poweroff\" action instead of an \"exit\" emergency action.");
      89                 :            :                 _fallthrough_;
      90                 :            : 
      91                 :          0 :         case EMERGENCY_ACTION_POWEROFF:
      92                 :          0 :                 log_and_status(m, warn, "Powering off", reason);
      93                 :          0 :                 (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL);
      94                 :          0 :                 break;
      95                 :            : 
      96                 :          0 :         case EMERGENCY_ACTION_EXIT_FORCE:
      97                 :            : 
      98         [ #  # ]:          0 :                 if (exit_status >= 0)
      99                 :          0 :                         m->return_value = exit_status;
     100                 :            : 
     101   [ #  #  #  # ]:          0 :                 if (MANAGER_IS_USER(m) || detect_container() > 0) {
     102                 :          0 :                         log_and_status(m, warn, "Exiting immediately", reason);
     103                 :          0 :                         m->objective = MANAGER_EXIT;
     104                 :          0 :                         break;
     105                 :            :                 }
     106                 :            : 
     107         [ #  # ]:          0 :                 log_notice("Doing \"poweroff-force\" action instead of an \"exit-force\" emergency action.");
     108                 :            :                 _fallthrough_;
     109                 :            : 
     110                 :          0 :         case EMERGENCY_ACTION_POWEROFF_FORCE:
     111                 :          0 :                 log_and_status(m, warn, "Forcibly powering off", reason);
     112                 :          0 :                 m->objective = MANAGER_POWEROFF;
     113                 :          0 :                 break;
     114                 :            : 
     115                 :          0 :         case EMERGENCY_ACTION_POWEROFF_IMMEDIATE:
     116                 :          0 :                 log_and_status(m, warn, "Powering off immediately", reason);
     117                 :            : 
     118                 :          0 :                 sync();
     119                 :            : 
     120         [ #  # ]:          0 :                 log_info("Powering off.");
     121                 :          0 :                 (void) reboot(RB_POWER_OFF);
     122                 :          0 :                 break;
     123                 :            : 
     124                 :          0 :         default:
     125                 :          0 :                 assert_not_reached("Unknown emergency action");
     126                 :            :         }
     127                 :            : }
     128                 :            : 
     129                 :            : static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
     130                 :            :         [EMERGENCY_ACTION_NONE] = "none",
     131                 :            :         [EMERGENCY_ACTION_REBOOT] = "reboot",
     132                 :            :         [EMERGENCY_ACTION_REBOOT_FORCE] = "reboot-force",
     133                 :            :         [EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
     134                 :            :         [EMERGENCY_ACTION_POWEROFF] = "poweroff",
     135                 :            :         [EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force",
     136                 :            :         [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate",
     137                 :            :         [EMERGENCY_ACTION_EXIT] = "exit",
     138                 :            :         [EMERGENCY_ACTION_EXIT_FORCE] = "exit-force",
     139                 :            : };
     140   [ +  +  +  + ]:        168 : DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction);
     141                 :            : 
     142                 :         80 : int parse_emergency_action(
     143                 :            :                 const char *value,
     144                 :            :                 bool system,
     145                 :            :                 EmergencyAction *ret) {
     146                 :            : 
     147                 :            :         EmergencyAction x;
     148                 :            : 
     149                 :         80 :         x = emergency_action_from_string(value);
     150         [ +  + ]:         80 :         if (x < 0)
     151                 :          8 :                 return -EINVAL;
     152                 :            : 
     153   [ +  +  +  +  :         72 :         if (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION)
                   +  + ]
     154                 :         24 :                 return -EOPNOTSUPP;
     155                 :            : 
     156                 :         48 :         *ret = x;
     157                 :         48 :         return 0;
     158                 :            : }

Generated by: LCOV version 1.14