chiark / gitweb /
tree-wide: spelling fixes
[elogind.git] / src / core / failure-action.c
index ca807b68da67991c5edd59cb1f840f88a8fd8f3b..ce522a4e4fee33244a80004c8b333f39f1da1594 100644 (file)
 #include "special.h"
 #include "failure-action.h"
 
+static void log_and_status(Manager *m, const char *message) {
+        log_warning("%s", message);
+        manager_status_printf(m, STATUS_TYPE_EMERGENCY,
+                              ANSI_HIGHLIGHT_RED_ON " !!  " ANSI_HIGHLIGHT_OFF,
+                              "%s", message);
+}
+
 int failure_action(
                 Manager *m,
                 FailureAction action,
@@ -40,15 +47,24 @@ int failure_action(
         assert(action >= 0);
         assert(action < _FAILURE_ACTION_MAX);
 
-        switch (action) {
+        if (action == FAILURE_ACTION_NONE)
+                return -ECANCELED;
 
-        case FAILURE_ACTION_NONE:
-                break;
+        if (m->running_as == SYSTEMD_USER) {
+                /* Downgrade all options to simply exiting if we run
+                 * in user mode */
+
+                log_warning("Exiting as result of failure.");
+                m->exit_code = MANAGER_EXIT;
+                return -ECANCELED;
+        }
+
+        switch (action) {
 
         case FAILURE_ACTION_REBOOT: {
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                log_warning("Rebooting as result of failure.");
+                log_and_status(m, "Rebooting as result of failure.");
 
                 update_reboot_param_file(reboot_arg);
                 r = manager_add_job_by_name(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
@@ -59,13 +75,14 @@ int failure_action(
         }
 
         case FAILURE_ACTION_REBOOT_FORCE:
-                log_warning("Forcibly rebooting as result of failure.");
+                log_and_status(m, "Forcibly rebooting as result of failure.");
+
                 update_reboot_param_file(reboot_arg);
                 m->exit_code = MANAGER_REBOOT;
                 break;
 
         case FAILURE_ACTION_REBOOT_IMMEDIATE:
-                log_warning("Rebooting immediately as result of failure.");
+                log_and_status(m, "Rebooting immediately as result of failure.");
 
                 sync();
 
@@ -78,6 +95,32 @@ int failure_action(
                 reboot(RB_AUTOBOOT);
                 break;
 
+        case FAILURE_ACTION_POWEROFF: {
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+                log_and_status(m, "Powering off as result of failure.");
+
+                r = manager_add_job_by_name(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE, true, &error, NULL);
+                if (r < 0)
+                        log_error("Failed to poweroff: %s.", bus_error_message(&error, r));
+
+                break;
+        }
+
+        case FAILURE_ACTION_POWEROFF_FORCE:
+                log_and_status(m, "Forcibly powering off as result of failure.");
+                m->exit_code = MANAGER_POWEROFF;
+                break;
+
+        case FAILURE_ACTION_POWEROFF_IMMEDIATE:
+                log_and_status(m, "Powering off immediately as result of failure.");
+
+                sync();
+
+                log_info("Powering off.");
+                reboot(RB_POWER_OFF);
+                break;
+
         default:
                 assert_not_reached("Unknown failure action");
         }
@@ -89,6 +132,9 @@ static const char* const failure_action_table[_FAILURE_ACTION_MAX] = {
         [FAILURE_ACTION_NONE] = "none",
         [FAILURE_ACTION_REBOOT] = "reboot",
         [FAILURE_ACTION_REBOOT_FORCE] = "reboot-force",
-        [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate"
+        [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
+        [FAILURE_ACTION_POWEROFF] = "poweroff",
+        [FAILURE_ACTION_POWEROFF_FORCE] = "poweroff-force",
+        [FAILURE_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
 };
 DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);