summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Schmidt <mschmidt@redhat.com>2013-02-22 11:21:47 +0100
committerMichal Schmidt <mschmidt@redhat.com>2013-02-22 16:06:17 +0100
commitb85bdddafb321fa870b9250a2ff17040d6996061 (patch)
tree7063d5b8cb26bdf13575b1c54a484e08c563d212
parent23ade460e5a118daa575a961b405d089f95e0617 (diff)
downloadsystemd-b85bdddafb321fa870b9250a2ff17040d6996061.tar.gz
systemctl: make shutdown operations use irreversible jobs
Occasionally people report problem with reboot/poweroff operations hanging in the middle. One known cause is when a new transaction to start a unit is enqueued while the shutdown is going on. The start of the unit conflicts with the shutdown jobs, so they get cancelled. The failure case can be quite unpleasant, becase getty and sshd may already be stopped. Fix it by using irreversible jobs for shutdown (reboot/poweroff/...) actions. This applies to commands like "reboot", "telinit 6", "systemctl reboot". Should someone desire to use reversible jobs, they can say "systemctl start reboot.target".`
-rw-r--r--man/systemctl.xml14
-rw-r--r--src/login/logind-dbus.c2
-rw-r--r--src/systemctl/systemctl.c23
3 files changed, 25 insertions, 14 deletions
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 0ceb26d59b..39229a0075 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -1006,8 +1006,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
<term><command>halt</command></term>
<listitem>
- <para>Shut down and halt the system. This is mostly
- equivalent to <command>start halt.target</command> but also
+ <para>Shut down and halt the system. This is mostly equivalent to
+ <command>start halt.target --irreversible</command> but also
prints a wall message to all users. If combined with
<option>--force</option> shutdown of all running services is
skipped, however all processes are killed and all file
@@ -1023,8 +1023,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
<listitem>
<para>Shut down and power-off the system. This is mostly
- equivalent to <command>start poweroff.target</command> but
- also prints a wall message to all users. If combined with
+ equivalent to <command>start poweroff.target --irreversible</command>
+ but also prints a wall message to all users. If combined with
<option>--force</option> shutdown of all running services is
skipped, however all processes are killed and all file
systems are unmounted or mounted read-only, immediately
@@ -1039,8 +1039,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
<listitem>
<para>Shut down and reboot the system. This is mostly
- equivalent to <command>start reboot.target</command> but
- also prints a wall message to all users. If combined with
+ equivalent to <command>start reboot.target --irreversible</command>
+ but also prints a wall message to all users. If combined with
<option>--force</option> shutdown of all running services is
skipped, however all processes are killed and all file
systems are unmounted or mounted read-only, immediately
@@ -1055,7 +1055,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
<listitem>
<para>Shut down and reboot the system via kexec. This is
- mostly equivalent to <command>start kexec.target</command>
+ mostly equivalent to <command>start kexec.target --irreversible</command>
but also prints a wall message to all users. If combined
with <option>--force</option> shutdown of all running
services is skipped, however all processes are killed and
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index d235474a23..818f2fa808 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1051,7 +1051,7 @@ static int execute_shutdown_or_sleep(
DBusError *error) {
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- const char *mode = "replace", *p;
+ const char *mode = "replace-irreversibly", *p;
int r;
char *c;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 723be76cdb..3d59a8bb1d 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1595,11 +1595,22 @@ static int start_unit(DBusConnection *bus, char **args) {
streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
"StartUnit";
- mode =
- (streq(args[0], "isolate") ||
- streq(args[0], "rescue") ||
- streq(args[0], "emergency") ||
- streq(args[0], "default")) ? "isolate" : arg_job_mode;
+ if (streq(args[0], "isolate") ||
+ streq(args[0], "rescue") ||
+ streq(args[0], "emergency") ||
+ streq(args[0], "default"))
+ mode = "isolate";
+ else if (streq(args[0], "halt") ||
+ streq(args[0], "poweroff") ||
+ streq(args[0], "reboot") ||
+ streq(args[0], "kexec") ||
+ streq(args[0], "exit") ||
+ streq(args[0], "suspend") ||
+ streq(args[0], "hibernate") ||
+ streq(args[0], "hybrid-sleep"))
+ mode = "replace-irreversibly";
+ else
+ mode = arg_job_mode;
one_name = table[verb_to_action(args[0])];
@@ -1614,7 +1625,7 @@ static int start_unit(DBusConnection *bus, char **args) {
arg_action == ACTION_RUNLEVEL2 ||
arg_action == ACTION_RUNLEVEL3 ||
arg_action == ACTION_RUNLEVEL4 ||
- arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace";
+ arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace-irreversibly";
one_name = table[arg_action];
}