summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.c29
-rw-r--r--src/manager.h6
2 files changed, 34 insertions, 1 deletions
diff --git a/src/main.c b/src/main.c
index 15bd2e4d15..88ba09d43e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -889,6 +889,7 @@ int main(int argc, char *argv[]) {
int r, retval = EXIT_FAILURE;
FDSet *fds = NULL;
bool reexecute = false;
+ const char *shutdown_verb = NULL;
if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
/* This is compatbility support for SysV, where
@@ -1127,6 +1128,23 @@ int main(int argc, char *argv[]) {
log_notice("Reexecuting.");
goto finish;
+ case MANAGER_REBOOT:
+ case MANAGER_POWEROFF:
+ case MANAGER_HALT:
+ case MANAGER_KEXEC: {
+ static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
+ [MANAGER_REBOOT] = "reboot",
+ [MANAGER_POWEROFF] = "poweroff",
+ [MANAGER_HALT] = "halt",
+ [MANAGER_KEXEC] = "kexec"
+ };
+
+ assert_se(shutdown_verb = table[m->exit_code]);
+
+ log_notice("Shutting down.");
+ goto finish;
+ }
+
default:
assert_not_reached("Unknown exit code.");
}
@@ -1206,6 +1224,17 @@ finish:
if (fds)
fdset_free(fds);
+ if (shutdown_verb) {
+ const char * command_line[] = {
+ SYSTEMD_SHUTDOWN_BINARY_PATH,
+ shutdown_verb,
+ NULL
+ };
+
+ execv(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line);
+ log_error("Failed to execute shutdown binary, freezing: %m");
+ }
+
if (getpid() == 1)
freeze();
diff --git a/src/manager.h b/src/manager.h
index 15ffb2c1a5..a573debe03 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -41,6 +41,10 @@ typedef enum ManagerExitCode {
MANAGER_EXIT,
MANAGER_RELOAD,
MANAGER_REEXECUTE,
+ MANAGER_REBOOT,
+ MANAGER_POWEROFF,
+ MANAGER_HALT,
+ MANAGER_KEXEC,
_MANAGER_EXIT_CODE_MAX,
_MANAGER_EXIT_CODE_INVALID = -1
} ManagerExitCode;
@@ -197,7 +201,7 @@ struct Manager {
/* Flags */
ManagerRunningAs running_as;
- ManagerExitCode exit_code:4;
+ ManagerExitCode exit_code:5;
bool dispatching_load_queue:1;
bool dispatching_run_queue:1;