summaryrefslogtreecommitdiff
path: root/src/systemctl/systemctl.c
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 /src/systemctl/systemctl.c
parent23ade460e5a118daa575a961b405d089f95e0617 (diff)
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".`
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r--src/systemctl/systemctl.c23
1 files changed, 17 insertions, 6 deletions
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];
}