chiark / gitweb /
systemctl: make shutdown operations use irreversible jobs
authorMichal Schmidt <mschmidt@redhat.com>
Fri, 22 Feb 2013 10:21:47 +0000 (11:21 +0100)
committerMichal Schmidt <mschmidt@redhat.com>
Fri, 22 Feb 2013 15:06:17 +0000 (16:06 +0100)
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".`

man/systemctl.xml
src/login/logind-dbus.c
src/systemctl/systemctl.c

index 0ceb26d59b40406bbc3182ee1f58fb2be5417eda..39229a0075724f36ea6767d58a64a23860510615 100644 (file)
@@ -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
index d235474a23555f9ceeb0cffa1910487f5ea80307..818f2fa808e2163ea0ff9c2714a86840d715a79e 100644 (file)
@@ -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;
 
index 723be76cdbad6a7b168d9a2224d4677a69d5596c..3d59a8bb1d3b6a01918aff79e5cefc4ba65ee58a 100644 (file)
@@ -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];
         }