[systemd-devel] [PATCH 2/4] special shutdown targets will now cause manager to exit.

Gustavo Sverzut Barbieri barbieri at profusion.mobi
Thu Sep 30 22:28:38 PDT 2010


---
 Makefile.am   |    1 +
 src/main.c    |   39 ++++++++++++++++++++++++++++++++++++++-
 src/manager.h |    3 +++
 src/target.c  |    8 ++++++++
 4 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 4d8e181..bf9d9ab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,7 @@ AM_CPPFLAGS = \
 	-DSESSION_DATA_UNIT_PATH=\"$(sessionunitdir)\" \
 	-DCGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \
 	-DSYSTEMD_BINARY_PATH=\"$(rootbindir)/systemd\" \
+	-DSYSTEMD_HALT_BINARY_PATH=\"$(rootlibexecdir)/systemd-halt\" \
 	-DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \
 	-DRUNTIME_DIR=\"$(localstatedir)/run\" \
 	-DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \
diff --git a/src/main.c b/src/main.c
index ee12e1f..e6dc157 100644
--- a/src/main.c
+++ b/src/main.c
@@ -896,6 +896,7 @@ int main(int argc, char *argv[]) {
         int r, retval = EXIT_FAILURE;
         FDSet *fds = NULL;
         bool reexecute = false;
+        ManagerExitCode exit_action = _MANAGER_EXIT_CODE_INVALID;
 
         if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
                 /* This is compatbility support for SysV, where
@@ -1127,6 +1128,21 @@ int main(int argc, char *argv[]) {
                         log_notice("Reexecuting.");
                         goto finish;
 
+                case MANAGER_REBOOT:
+                        log_info("Reboot.");
+                        exit_action = MANAGER_REBOOT;
+                        goto finish;
+
+                case MANAGER_POWEROFF:
+                        log_info("Poweroff.");
+                        exit_action = MANAGER_POWEROFF;
+                        goto finish;
+
+                case MANAGER_HALT:
+                        log_info("Halt.");
+                        exit_action = MANAGER_HALT;
+                        goto finish;
+
                 default:
                         assert_not_reached("Unknown exit code.");
                 }
@@ -1206,8 +1222,29 @@ finish:
         if (fds)
                 fdset_free(fds);
 
-        if (getpid() == 1)
+        if (getpid() == 1) {
+                const char *args[3] = {SYSTEMD_HALT_BINARY_PATH, NULL, NULL};
+
+                switch (exit_action) {
+                case MANAGER_REBOOT:
+                        args[1] = "-r";
+                        break;
+                case MANAGER_POWEROFF:
+                        args[1] = "-p";
+                        break;
+                case MANAGER_HALT:
+                        args[1] = "-h";
+                        break;
+                default:
+                        log_error("Unknown exit_action code %d", exit_action);
+                }
+
+                if (args[1]) {
+                        execv(args[0], (char* const*) args);
+                        log_error("failed to exit with action %d", exit_action);
+                }
                 freeze();
+        }
 
         return retval;
 }
diff --git a/src/manager.h b/src/manager.h
index 10ff24c..cb8988d 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -41,6 +41,9 @@ typedef enum ManagerExitCode {
         MANAGER_EXIT,
         MANAGER_RELOAD,
         MANAGER_REEXECUTE,
+        MANAGER_REBOOT,
+        MANAGER_HALT,
+        MANAGER_POWEROFF,
         _MANAGER_EXIT_CODE_MAX,
         _MANAGER_EXIT_CODE_INVALID = -1
 } ManagerExitCode;
diff --git a/src/target.c b/src/target.c
index 3522bf1..dc3af2e 100644
--- a/src/target.c
+++ b/src/target.c
@@ -172,6 +172,14 @@ static int target_start(Unit *u) {
         assert(t->state == TARGET_DEAD);
 
         target_set_state(t, TARGET_ACTIVE);
+
+        if (unit_has_name(u, SPECIAL_REBOOT_TARGET))
+                t->meta.manager->exit_code = MANAGER_REBOOT;
+        else if (unit_has_name(u, SPECIAL_POWEROFF_TARGET))
+                t->meta.manager->exit_code = MANAGER_POWEROFF;
+        else if (unit_has_name(u, SPECIAL_HALT_TARGET))
+                t->meta.manager->exit_code = MANAGER_HALT;
+
         return 0;
 }
 
-- 
1.7.2.2



More information about the systemd-devel mailing list