[systemd-commits] 14 commits - Makefile.am src/condition.c src/dbus-manager.c src/main.c src/manager.c src/manager.h src/service.c src/shutdown.c src/special.h src/systemctl.c src/systemd-interfaces.vala src/umount.c units/.gitignore units/kexec.service.in units/kexec.target units/session
Lennart Poettering
lennart at kemper.freedesktop.org
Wed Oct 13 15:58:04 PDT 2010
Makefile.am | 8 +++-
src/condition.c | 2 -
src/dbus-manager.c | 52 ++++++++++++++++++++++++++++++++
src/main.c | 29 +++++++++++++++++
src/manager.c | 33 ++++++++++++++++----
src/manager.h | 6 +++
src/service.c | 2 -
src/shutdown.c | 47 ++++++++++++-----------------
src/special.h | 3 +
src/systemctl.c | 48 ++++++++++++++++++++++-------
src/systemd-interfaces.vala | 4 ++
src/umount.c | 68 ++++++++++++++++++++++--------------------
units/.gitignore | 1
units/kexec.service.in | 16 +++++++++
units/kexec.target | 18 +++++++++++
units/session/exit.service.in | 13 ++++++--
units/session/exit.target | 18 +++++++++++
17 files changed, 285 insertions(+), 83 deletions(-)
New commits:
commit 85ed27f699939f75b8422ae67e016bdf9f439da9
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:57:52 2010 +0200
units: introduce kexec.service, kexec.target and exit.target
diff --git a/Makefile.am b/Makefile.am
index e432dcb..b15cb12 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -162,6 +162,7 @@ dist_systemunit_DATA = \
units/basic.target \
units/getty.target \
units/halt.target \
+ units/kexec.target \
units/local-fs.target \
units/network.target \
units/nss-lookup.target \
@@ -229,10 +230,12 @@ nodist_systemunit_DATA = \
units/systemd-readahead-done.service \
units/systemd-tmpfiles.service \
units/systemd-user-sessions.service \
- units/syslog.target
+ units/syslog.target \
+ units/kexec.service
dist_sessionunit_DATA = \
- units/session/default.target
+ units/session/default.target \
+ units/session/exit.target
nodist_sessionunit_DATA = \
units/session/remote-fs.target \
@@ -262,6 +265,7 @@ EXTRA_DIST = \
units/systemd-tmpfiles.service.in \
units/systemd-user-sessions.service.in \
units/syslog.target.in \
+ units/kexec.service.in \
units/session/exit.service.in \
systemd.pc.in
diff --git a/units/.gitignore b/units/.gitignore
index 00a40d4..83fc32c 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -1,3 +1,4 @@
+kexec.service
systemd-user-sessions.service
systemd-readahead-done.service
systemd-tmpfiles.service
diff --git a/units/kexec.service.in b/units/kexec.service.in
new file mode 100644
index 0000000..70ad227
--- /dev/null
+++ b/units/kexec.service.in
@@ -0,0 +1,16 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Reboot via kexec
+DefaultDependencies=no
+Requires=shutdown.target umount.target
+After=shutdown.target umount.target
+
+[Service]
+Type=oneshot
+ExecStart=@SYSTEMCTL@ --force kexec
diff --git a/units/kexec.target b/units/kexec.target
new file mode 100644
index 0000000..b77e6a4
--- /dev/null
+++ b/units/kexec.target
@@ -0,0 +1,18 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# See systemd.special(7) for details
+
+[Unit]
+Description=Reboot via kexec
+DefaultDependencies=no
+Requires=kexec.service
+After=kexec.service
+AllowIsolate=yes
+
+[Install]
+Alias=ctrl-alt-del.target
diff --git a/units/session/exit.service.in b/units/session/exit.service.in
index d098d0d..024fbe1 100644
--- a/units/session/exit.service.in
+++ b/units/session/exit.service.in
@@ -1,9 +1,18 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# See systemd.special(7) for details
+
[Unit]
-Description=Exit
+Description=Exit the Session
DefaultDependencies=no
Requires=shutdown.target
After=shutdown.target
[Service]
Type=oneshot
-ExecStart=@SYSTEMCTL@ --session daemon-exit
+ExecStart=@SYSTEMCTL@ --session --force exit
diff --git a/units/session/exit.target b/units/session/exit.target
new file mode 100644
index 0000000..f34844c
--- /dev/null
+++ b/units/session/exit.target
@@ -0,0 +1,18 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# See systemd.special(7) for details
+
+[Unit]
+Description=Exit the Session
+DefaultDependencies=no
+Requires=exit.service
+After=exit.service
+AllowIsolate=yes
+
+[Install]
+Alias=ctrl-alt-del.target
commit bec9996d6aab890f82fb58a470fe6cf37cbaf40d
Author: Fabiano Fidencio <fidencio at profusion.mobi>
Date: Thu Oct 14 00:56:50 2010 +0200
vala: register new D-Bus calls
diff --git a/src/systemd-interfaces.vala b/src/systemd-interfaces.vala
index b7229ce..1d202e0 100644
--- a/src/systemd-interfaces.vala
+++ b/src/systemd-interfaces.vala
@@ -74,6 +74,10 @@ public interface Manager : DBus.Object {
public abstract void reload() throws DBus.Error;
public abstract void reexecute() throws DBus.Error;
public abstract void exit() throws DBus.Error;
+ public abstract void halt() throws DBus.Error;
+ public abstract void power_off() throws DBus.Error;
+ public abstract void reboot() throws DBus.Error;
+ public abstract void kexec() throws DBus.Error;
public abstract ObjectPath create_snapshot(string name = "", bool cleanup = false) throws DBus.Error;
commit 20b09ca7fd4bf2be665951dbf908dc41c6fc903d
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:56:12 2010 +0200
systemctl: rework halt/reboot/poweroff/kexec/exit logic around --force
diff --git a/src/systemctl.c b/src/systemctl.c
index 671745b..ffb4f73 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -81,6 +81,8 @@ static enum action {
ACTION_HALT,
ACTION_POWEROFF,
ACTION_REBOOT,
+ ACTION_KEXEC,
+ ACTION_EXIT,
ACTION_RUNLEVEL2,
ACTION_RUNLEVEL3,
ACTION_RUNLEVEL4,
@@ -193,6 +195,7 @@ static void warn_wall(enum action action) {
[ACTION_HALT] = "The system is going down for system halt NOW!",
[ACTION_REBOOT] = "The system is going down for reboot NOW!",
[ACTION_POWEROFF] = "The system is going down for power-off NOW!",
+ [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
[ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
[ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!"
};
@@ -1220,12 +1223,16 @@ static enum action verb_to_action(const char *verb) {
return ACTION_POWEROFF;
else if (streq(verb, "reboot"))
return ACTION_REBOOT;
+ else if (streq(verb, "kexec"))
+ return ACTION_KEXEC;
else if (streq(verb, "rescue"))
return ACTION_RESCUE;
else if (streq(verb, "emergency"))
return ACTION_EMERGENCY;
else if (streq(verb, "default"))
return ACTION_DEFAULT;
+ else if (streq(verb, "exit"))
+ return ACTION_EXIT;
else
return ACTION_INVALID;
}
@@ -1236,13 +1243,15 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) {
[ACTION_HALT] = SPECIAL_HALT_TARGET,
[ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET,
[ACTION_REBOOT] = SPECIAL_REBOOT_TARGET,
+ [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET,
[ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET,
[ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET,
[ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET,
[ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET,
[ACTION_RESCUE] = SPECIAL_RESCUE_TARGET,
[ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET,
- [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET
+ [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET,
+ [ACTION_EXIT] = SPECIAL_EXIT_TARGET
};
int r, ret = 0;
@@ -1337,6 +1346,14 @@ static int start_special(DBusConnection *bus, char **args, unsigned n) {
assert(bus);
assert(args);
+ if (arg_force &&
+ (streq(args[0], "halt") ||
+ streq(args[0], "poweroff") ||
+ streq(args[0], "reboot") ||
+ streq(args[0], "kexec") ||
+ streq(args[0], "exit")))
+ return daemon_reload(bus, args, n);
+
r = start_unit(bus, args, n);
if (r >= 0)
@@ -2968,12 +2985,16 @@ static int daemon_reload(DBusConnection *bus, char **args, unsigned n) {
assert(arg_action == ACTION_SYSTEMCTL);
method =
- streq(args[0], "clear-jobs") ||
- streq(args[0], "cancel") ? "ClearJobs" :
- streq(args[0], "daemon-reexec") ? "Reexecute" :
- streq(args[0], "reset-failed") ? "ResetFailed" :
- streq(args[0], "daemon-exit") ? "Exit" :
- "Reload";
+ streq(args[0], "clear-jobs") ||
+ streq(args[0], "cancel") ? "ClearJobs" :
+ streq(args[0], "daemon-reexec") ? "Reexecute" :
+ streq(args[0], "reset-failed") ? "ResetFailed" :
+ streq(args[0], "halt") ? "Halt" :
+ streq(args[0], "poweroff") ? "PowerOff" :
+ streq(args[0], "reboot") ? "Reboot" :
+ streq(args[0], "kexec") ? "KExec" :
+ streq(args[0], "exit") ? "Exit" :
+ /* "daemon-reload" */ "Reload";
}
if (!(m = dbus_message_new_method_call(
@@ -3919,6 +3940,7 @@ static int systemctl_help(void) {
" --no-reload When enabling/disabling unit files, don't reload daemon\n"
" configuration\n"
" --force When enabling unit files, override existing symlinks\n"
+ " When shutting down, execute action immediately\n"
" --defaults When disabling unit files, remove default symlinks only\n\n"
"Commands:\n"
" list-units List units\n"
@@ -3951,16 +3973,17 @@ static int systemctl_help(void) {
" delete [NAME...] Remove one or more snapshots\n"
" daemon-reload Reload systemd manager configuration\n"
" daemon-reexec Reexecute systemd manager\n"
- " daemon-exit Ask the systemd manager to quit\n"
" show-environment Dump environment\n"
" set-environment [NAME=VALUE...] Set one or more environment variables\n"
" unset-environment [NAME...] Unset one or more environment variables\n"
+ " default Enter system default mode\n"
+ " rescue Enter system rescue mode\n"
+ " emergency Enter system emergency mode\n"
" halt Shut down and halt the system\n"
" poweroff Shut down and power-off the system\n"
" reboot Shut down and reboot the system\n"
- " rescue Enter system rescue mode\n"
- " emergency Enter system emergency mode\n"
- " default Enter system default mode\n",
+ " kexec Shut down and reboot the system with kexec\n"
+ " exit Ask for session termination\n",
program_invocation_short_name);
return 0;
@@ -4772,16 +4795,17 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
{ "delete", MORE, 2, delete_snapshot },
{ "daemon-reload", EQUAL, 1, daemon_reload },
{ "daemon-reexec", EQUAL, 1, daemon_reload },
- { "daemon-exit", EQUAL, 1, daemon_reload },
{ "show-environment", EQUAL, 1, show_enviroment },
{ "set-environment", MORE, 2, set_environment },
{ "unset-environment", MORE, 2, set_environment },
{ "halt", EQUAL, 1, start_special },
{ "poweroff", EQUAL, 1, start_special },
{ "reboot", EQUAL, 1, start_special },
+ { "kexec", EQUAL, 1, start_special },
{ "default", EQUAL, 1, start_special },
{ "rescue", EQUAL, 1, start_special },
{ "emergency", EQUAL, 1, start_special },
+ { "exit", EQUAL, 1, start_special },
{ "reset-failed", MORE, 1, reset_failed },
{ "enable", MORE, 2, enable_unit },
{ "disable", MORE, 2, enable_unit },
commit 0003d1ab75f82dd6aa143582c5bd815b3b8f65e8
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:54:48 2010 +0200
manager: hookup shutdown helper and signals
diff --git a/src/manager.c b/src/manager.c
index 1fe8936..f2ec2b7 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -164,11 +164,16 @@ static int manager_setup_signals(Manager *m) {
SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */
SIGPWR, /* Some kernel drivers and upsd send us this on power failure */
SIGRTMIN+0, /* systemd: start default.target */
- SIGRTMIN+1, /* systemd: start rescue.target */
+ SIGRTMIN+1, /* systemd: isolate rescue.target */
SIGRTMIN+2, /* systemd: isolate emergency.target */
SIGRTMIN+3, /* systemd: start halt.target */
SIGRTMIN+4, /* systemd: start poweroff.target */
SIGRTMIN+5, /* systemd: start reboot.target */
+ SIGRTMIN+6, /* systemd: start kexec.target */
+ SIGRTMIN+13, /* systemd: Immediate halt */
+ SIGRTMIN+14, /* systemd: Immediate poweroff */
+ SIGRTMIN+15, /* systemd: Immediate reboot */
+ SIGRTMIN+16, /* systemd: Immediate kexec */
-1);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
@@ -1987,7 +1992,7 @@ static int manager_process_signal_fd(Manager *m) {
}
/* Run the exit target if there is one, if not, just exit. */
- if (manager_start_target(m, SPECIAL_EXIT_SERVICE, JOB_REPLACE) < 0) {
+ if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) {
m->exit_code = MANAGER_EXIT;
return 0;
}
@@ -2058,22 +2063,38 @@ static int manager_process_signal_fd(Manager *m) {
break;
default: {
- static const char * const table[] = {
+ /* Starting SIGRTMIN+0 */
+ static const char * const target_table[] = {
[0] = SPECIAL_DEFAULT_TARGET,
[1] = SPECIAL_RESCUE_TARGET,
[2] = SPECIAL_EMERGENCY_TARGET,
[3] = SPECIAL_HALT_TARGET,
[4] = SPECIAL_POWEROFF_TARGET,
- [5] = SPECIAL_REBOOT_TARGET
+ [5] = SPECIAL_REBOOT_TARGET,
+ [6] = SPECIAL_KEXEC_TARGET
+ };
+
+ /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
+ static const ManagerExitCode code_table[] = {
+ [0] = MANAGER_HALT,
+ [1] = MANAGER_POWEROFF,
+ [2] = MANAGER_REBOOT,
+ [3] = MANAGER_KEXEC
};
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
- (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(table)) {
- manager_start_target(m, table[sfsi.ssi_signo - SIGRTMIN],
+ (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
+ manager_start_target(m, target_table[sfsi.ssi_signo - SIGRTMIN],
(sfsi.ssi_signo == 1 || sfsi.ssi_signo == 2) ? JOB_ISOLATE : JOB_REPLACE);
break;
}
+ if ((int) sfsi.ssi_signo >= SIGRTMIN+13 &&
+ (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) {
+ m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13];
+ break;
+ }
+
log_warning("Got unhandled signal <%s>.", strna(signal_to_string(sfsi.ssi_signo)));
}
}
diff --git a/src/service.c b/src/service.c
index 310aa28..3ebe60e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -316,7 +316,7 @@ static int sysv_translate_facility(const char *name, const char *filename, char
}
/* If we don't know this name, fallback heuristics to figure
- * out whether something is a target or an service alias. */
+ * out whether something is a target or a service alias. */
if (*name == '$')
/* Facilities starting with $ are most likely targets */
diff --git a/src/special.h b/src/special.h
index ca24121..0b37353 100644
--- a/src/special.h
+++ b/src/special.h
@@ -54,11 +54,12 @@
#define SPECIAL_SYSINIT_TARGET "sysinit.target"
#define SPECIAL_FSCK_TARGET "fsck.target"
#define SPECIAL_RESCUE_TARGET "rescue.target"
-#define SPECIAL_EXIT_SERVICE "exit.service"
+#define SPECIAL_EXIT_TARGET "exit.target"
#define SPECIAL_EMERGENCY_TARGET "emergency.target"
#define SPECIAL_HALT_TARGET "halt.target"
#define SPECIAL_POWEROFF_TARGET "poweroff.target"
#define SPECIAL_REBOOT_TARGET "reboot.target"
+#define SPECIAL_KEXEC_TARGET "kexec.target"
#define SPECIAL_DBUS_SERVICE "dbus.service"
#define SPECIAL_DBUS_SOCKET "dbus.socket"
#define SPECIAL_GETTY_TARGET "getty.target"
commit 6652a2b9e5f837e8a7e6b0c7b890e5d0e7d85794
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:53:51 2010 +0200
dbus: expose shutdown helper via D-Bus
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index 3754a0c..c700abb 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -104,6 +104,10 @@
" <method name=\"Reload\"/>\n" \
" <method name=\"Reexecute\"/>\n" \
" <method name=\"Exit\"/>\n" \
+ " <method name=\"Reboot\"/>\n" \
+ " <method name=\"PowerOff\"/>\n" \
+ " <method name=\"Halt\"/>\n" \
+ " <method name=\"KExec\"/>\n" \
" <method name=\"SetEnvironment\">\n" \
" <arg name=\"names\" type=\"as\" direction=\"in\"/>\n" \
" </method>\n" \
@@ -808,6 +812,54 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
m->exit_code = MANAGER_EXIT;
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reboot")) {
+
+ if (m->running_as != MANAGER_SYSTEM) {
+ dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
+ return bus_send_error_reply(m, connection, message, &error, -ENOTSUP);
+ }
+
+ if (!(reply = dbus_message_new_method_return(message)))
+ goto oom;
+
+ m->exit_code = MANAGER_REBOOT;
+
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PowerOff")) {
+
+ if (m->running_as != MANAGER_SYSTEM) {
+ dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
+ return bus_send_error_reply(m, connection, message, &error, -ENOTSUP);
+ }
+
+ if (!(reply = dbus_message_new_method_return(message)))
+ goto oom;
+
+ m->exit_code = MANAGER_POWEROFF;
+
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Halt")) {
+
+ if (m->running_as != MANAGER_SYSTEM) {
+ dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Halting is only supported for system managers.");
+ return bus_send_error_reply(m, connection, message, &error, -ENOTSUP);
+ }
+
+ if (!(reply = dbus_message_new_method_return(message)))
+ goto oom;
+
+ m->exit_code = MANAGER_HALT;
+
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KExec")) {
+
+ if (m->running_as != MANAGER_SYSTEM) {
+ dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "kexec is only supported for system managers.");
+ return bus_send_error_reply(m, connection, message, &error, -ENOTSUP);
+ }
+
+ if (!(reply = dbus_message_new_method_return(message)))
+ goto oom;
+
+ m->exit_code = MANAGER_KEXEC;
+
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) {
char **l = NULL, **e = NULL;
commit b9080b03a98252ccccb332d0c892403b8b841916
Author: Fabiano Fidencio <fidencio at profusion.mobi>
Date: Thu Oct 14 00:52:26 2010 +0200
manager: hookup execution of systemd-shutdown helper
(Modified by Lennart Poettering)
diff --git a/src/main.c b/src/main.c
index 15bd2e4..88ba09d 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 15ffb2c..a573deb 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;
commit e61cd18666de1c26d41b4f189c8fac8a0bf8ee61
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:50:11 2010 +0200
shutdown: make use of wait_for_terminate_and_warn()
diff --git a/src/shutdown.c b/src/shutdown.c
index 43165fe..176327b 100644
--- a/src/shutdown.c
+++ b/src/shutdown.c
@@ -307,28 +307,29 @@ int main(int argc, char *argv[]) {
if (cmd == LINUX_REBOOT_CMD_KEXEC) {
/* we cheat and exec kexec to avoid doing all its work */
pid_t pid = fork();
- if (pid < 0) {
- log_error("Could not fork: %m. Falling back to reboot.");
- cmd = RB_AUTOBOOT;
- } else if (pid > 0) {
- waitpid(pid, NULL, 0);
- log_warning("Failed %s -e -x -f. Falling back to reboot", KEXEC_BINARY_PATH);
- cmd = RB_AUTOBOOT;
+ if (pid < 0)
+ log_error("Could not fork: %m. Falling back to normal reboot.");
+ else if (pid > 0) {
+ wait_for_terminate_and_warn("kexec", pid);
+ log_warning("kexec failed. Falling back to normal reboot.");
} else {
- const char *args[5] = {KEXEC_BINARY_PATH, "-e", "-f", "-x", NULL};
+ /* Child */
+ const char *args[5] = { KEXEC_BINARY_PATH, "-e", "-f", "-x", NULL };
execv(args[0], (char * const *) args);
return EXIT_FAILURE;
}
+
+ cmd = RB_AUTOBOOT;
}
reboot(cmd);
- r = errno;
+ log_error("Failed to invoke reboot(): %m");
+ r = -errno;
error:
sync();
- if (r < 0)
- r = -r;
- log_error("Critical error while doing system shutdown: %s", strerror(r));
+ log_error("Critical error while doing system shutdown: %s", strerror(-r));
+
freeze();
return EXIT_FAILURE;
}
commit d37fb98bbcf85115a03664437ae02aa95f6af4bc
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:49:53 2010 +0200
shutdown: execute rescue kill only once
diff --git a/src/shutdown.c b/src/shutdown.c
index 3c9a531..43165fe 100644
--- a/src/shutdown.c
+++ b/src/shutdown.c
@@ -286,18 +286,18 @@ int main(int argc, char *argv[]) {
if (need_umount || need_swapoff || need_loop_detach) {
retries--;
- if (retries <= FINALIZE_CRITICAL_ATTEMPTS) {
+ if (retries == FINALIZE_CRITICAL_ATTEMPTS) {
log_warning("Approaching critical level to finalize filesystem and devices, try to kill all processes.");
rescue_send_signal(SIGTERM);
rescue_send_signal(SIGKILL);
}
if (retries > 0)
- log_info("Action still required, %d tries left", retries);
+ log_info("Action still required, %d tries left.", retries);
else {
- log_error("Tried enough but still action required need_umount=%d, need_swapoff=%d, need_loop_detach=%d", need_umount, need_swapoff, need_loop_detach);
- r = -EBUSY;
- goto error;
+ log_error("Giving up. Actions left: Umount=%s, Swap off=%s, Loop detach=%s",
+ yes_no(need_umount), yes_no(need_swapoff), yes_no(need_loop_detach));
+ break;
}
}
}
commit 567ea02a89b358090032c8d1ec89286db07ab2ff
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:49:22 2010 +0200
shutdown: don't chdir to /, since init is running with / as cwd anyway
diff --git a/src/shutdown.c b/src/shutdown.c
index b78c741..3c9a531 100644
--- a/src/shutdown.c
+++ b/src/shutdown.c
@@ -36,7 +36,7 @@
#include "umount.h"
#include "util.h"
-#define TIMEOUT_USEC (5 * USEC_PER_SEC)
+#define TIMEOUT_USEC (5 * USEC_PER_SEC)
#define FINALIZE_ATTEMPTS 50
#define FINALIZE_CRITICAL_ATTEMPTS 10
@@ -198,7 +198,6 @@ finish:
return r;
}
-
int main(int argc, char *argv[]) {
int cmd, r, retries;
bool need_umount = true, need_swapoff = true, need_loop_detach = true;
@@ -208,7 +207,7 @@ int main(int argc, char *argv[]) {
log_open();
if (getpid() != 1) {
- log_error("Not executed by init (pid-1).");
+ log_error("Not executed by init (pid 1).");
r = -EPERM;
goto error;
}
@@ -247,12 +246,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_warning("Cannot send SIGKILL to all process: %s", strerror(r));
-
- /* preventing that we won't block umounts */
- if (chdir("/") != 0)
- log_warning("Cannot chdir(\"/\"): %m. Unmounts likely to fail.");
-
- /* umount all mountpoints, swaps, and loopback devices */
+ /* Unmount all mountpoints, swaps, and loopback devices */
retries = FINALIZE_ATTEMPTS;
while (need_umount || need_swapoff || need_loop_detach) {
if (need_umount) {
commit 7e23b34c7da85e24c92e984f1d99eead3e9817f5
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:43:35 2010 +0200
umount: be a bit more verbose when unable to umount/unswap/delete loopbacks
diff --git a/src/umount.c b/src/umount.c
index ff1296f..44bed61 100644
--- a/src/umount.c
+++ b/src/umount.c
@@ -293,7 +293,7 @@ static int mount_points_list_umount(MountPoint **mount_point_list_head) {
if (umount2(mp->path, MNT_FORCE) == 0)
mount_point_remove_and_free(mp, mount_point_list_head);
else {
- log_debug("Could not unmount %s: %m", mp->path);
+ log_warning("Could not unmount %s: %m", mp->path);
failed++;
}
}
@@ -310,7 +310,7 @@ static int mount_points_list_remount_read_only(MountPoint **mount_point_list_hea
if (mount(NULL, mp->path, NULL, MS_MGC_VAL|MS_REMOUNT|MS_RDONLY, NULL) == 0)
mount_point_remove_and_free(mp, mount_point_list_head);
else {
- log_debug("Could not remount as read-only %s: %m", mp->path);
+ log_warning("Could not remount as read-only %s: %m", mp->path);
failed++;
}
}
@@ -326,7 +326,7 @@ static int swap_points_list_off(MountPoint **swap_list_head) {
if (swapoff(swap->path) == 0)
mount_point_remove_and_free(swap, swap_list_head);
else {
- log_debug("Could not swapoff %s: %m", swap->path);
+ log_warning("Could not deactivate swap %s: %m", swap->path);
failed++;
}
}
@@ -342,7 +342,7 @@ static int loopback_points_list_detach(MountPoint **loopback_list_head) {
if (delete_loopback(loopback->path) == 0)
mount_point_remove_and_free(loopback, loopback_list_head);
else {
- log_debug("Could not delete loopback %s: %m", loopback->path);
+ log_warning("Could not delete loopback %s: %m", loopback->path);
failed++;
}
}
commit ce726252a9a9487a694cbd68f4d13542ba965258
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:43:13 2010 +0200
umount: simplify code for deactivating loop devices
diff --git a/src/umount.c b/src/umount.c
index bd4f01f..ff1296f 100644
--- a/src/umount.c
+++ b/src/umount.c
@@ -271,23 +271,14 @@ finish:
static int delete_loopback(const char *device) {
int fd, r;
- if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0) {
- if (errno == ENOENT) {
- log_debug("Loop device %s does not exist.", device);
- errno = 0;
- return 0;
- }
+ if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0)
return -errno;
- }
- ioctl(fd, LOOP_CLR_FD, 0);
- r = errno;
+ r = ioctl(fd, LOOP_CLR_FD, 0);
close_nointr_nofail(fd);
- if (r == ENXIO) /* not bound, so no error */
- r = 0;
- errno = r;
- return -errno;
+ /* ENXIO: not bound, so no error */
+ return (r >= 0 || errno == ENXIO) ? 0 : -errno;
}
static int mount_points_list_umount(MountPoint **mount_point_list_head) {
commit b854a7e7289e0b136c6a4fa03ad76640c59bcfa0
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:42:44 2010 +0200
umount: properly enumerate loopback devices
diff --git a/src/umount.c b/src/umount.c
index 79fbba7..bd4f01f 100644
--- a/src/umount.c
+++ b/src/umount.c
@@ -227,16 +227,27 @@ static int loopback_list_get(MountPoint **loopback_list_head) {
udev_list_entry_foreach(item, first) {
MountPoint *lb;
+ struct udev_device *d;
char *loop;
+ const char *dn;
- loop = cunescape(udev_list_entry_get_name(item));
- if (!loop) {
+ if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) {
r = -ENOMEM;
goto finish;
}
- lb = mount_point_alloc(loop);
- if (!lb) {
+ if ((dn = udev_device_get_devnode(d))) {
+ loop = strdup(dn);
+ udev_device_unref(d);
+
+ if (!loop) {
+ r = -ENOMEM;
+ goto finish;
+ }
+ } else
+ udev_device_unref(d);
+
+ if (!(lb = mount_point_alloc(loop))) {
free(loop);
r = -ENOMEM;
goto finish;
@@ -251,7 +262,9 @@ finish:
if (e)
udev_enumerate_unref(e);
- free(udev);
+ if (udev)
+ udev_unref(udev);
+
return r;
}
commit 2054a5b8cb52a66462b7d967ed9a6c179777bc0f
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:41:57 2010 +0200
umount: unescape path from /proc/self/mountinfo first, then check against api mount list
diff --git a/src/umount.c b/src/umount.c
index 468eb71..79fbba7 100644
--- a/src/umount.c
+++ b/src/umount.c
@@ -38,6 +38,7 @@ typedef struct MountPoint {
LIST_FIELDS (struct MountPoint, mount_point);
} MountPoint;
+/* Takes over possession of path */
static MountPoint *mount_point_alloc(char *path) {
MountPoint *mp;
@@ -98,23 +99,26 @@ static int mount_points_list_get(MountPoint **mount_point_list_head) {
continue;
}
- if (mount_point_is_api(path)) {
- free(path);
- continue;
- }
+ p = cunescape(path);
+ free(path);
- if (!(p = cunescape(path))) {
+ if (!p) {
r = -ENOMEM;
goto finish;
}
+ if (mount_point_is_api(p)) {
+ free(p);
+ continue;
+ }
+
if (!(mp = mount_point_alloc(p))) {
+ free(p);
r = -ENOMEM;
goto finish;
}
- LIST_PREPEND(MountPoint, mount_point, *mount_point_list_head, mp);
- free(path);
+ LIST_PREPEND(MountPoint, mount_point, *mount_point_list_head, mp);
}
r = 0;
@@ -122,8 +126,6 @@ static int mount_points_list_get(MountPoint **mount_point_list_head) {
finish:
fclose(proc_self_mountinfo);
- free(path);
-
return r;
}
commit f23c09b0fdec4a421cc002a38621e5be05ed770b
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Oct 14 00:40:39 2010 +0200
condition: fix copyright
diff --git a/src/condition.c b/src/condition.c
index 8c2db2d..1e69b61 100644
--- a/src/condition.c
+++ b/src/condition.c
@@ -3,7 +3,7 @@
/***
This file is part of systemd.
- Copyright 2010 ProFUSION embedded systems
+ Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
More information about the systemd-commits
mailing list