[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