X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Ffailure-action.c;h=ce522a4e4fee33244a80004c8b333f39f1da1594;hp=ca807b68da67991c5edd59cb1f840f88a8fd8f3b;hb=f131770b1465fbf423881f16ba85523a05f846fe;hpb=2928b0a863091f8f291fddb168988711afd389ef diff --git a/src/core/failure-action.c b/src/core/failure-action.c index ca807b68d..ce522a4e4 100644 --- a/src/core/failure-action.c +++ b/src/core/failure-action.c @@ -29,6 +29,13 @@ #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);