chiark / gitweb /
systemctl: introduce systemctl reboot -ff
authorLennart Poettering <lennart@poettering.net>
Wed, 15 Feb 2012 19:05:49 +0000 (20:05 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 15 Feb 2012 19:05:49 +0000 (20:05 +0100)
TODO
man/systemctl.xml
src/systemctl.c

diff --git a/TODO b/TODO
index cba2c8cfec427ecf13f63fb8950a73f9dd8aa3a5..46d4c0402d3a7f854c1102fa206889c903b34731 100644 (file)
--- a/TODO
+++ b/TODO
@@ -21,8 +21,6 @@ Bugfixes:
 
 Features:
 
-* systemctl reboot -ff should trigger an immediate reboot
-
 * support units generated by a generator and placed in /run/systemd/system/; the directory is
   currently ignored because it is empty before the generatores are executed
 
index 5adee45163b3bcc61c9585ef2fb9878ec24e8290..3266333be1b41b80174508f2758c4a2941780740 100644 (file)
                                 <command>halt</command>,
                                 <command>poweroff</command>,
                                 <command>reboot</command> or
-                                <command>kexec</command> execute
+                                <command>kexec</command> execute the
                                 selected operation without shutting
                                 down all units. However, all processes
                                 will be killed forcibly and all file
                                 systems are unmounted or remounted
                                 read-only. This is hence a drastic but
                                 relatively safe option to request an
-                                immediate reboot.</para></listitem>
+                                immediate reboot. If
+                                <option>--force</option> is specified
+                                twice for these operations, they will
+                                be executed immediately without
+                                terminating any processes or umounting
+                                any file systems. Warning: specifying
+                                <option>--force</option> twice with
+                                any of these operations might result
+                                in data loss.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
                                 system. This is mostly equivalent to
                                 <command>start halt.target</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
+                                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
-                                followed by the
-                                system halt.</para></listitem>
+                                followed by the system halt.  If
+                                <option>--force</option> is specified
+                                twice the the operation is immediately
+                                executed without terminating any
+                                processes or unmounting any file
+                                systems. This may result in data
+                                loss.</para></listitem>
                         </varlistentry>
                         <varlistentry>
                                 <term><command>poweroff</command></term>
                                 power-off the system. This is mostly
                                 equivalent to <command>start
                                 poweroff.target</command> but also
-                                prints a wall message to all
-                                users. If
+                                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
-                                followed by the
-                                powering off.</para></listitem>
+                                skipped, however all processes are
+                                killed and all file systems are
+                                unmounted or mounted read-only,
+                                immediately followed by the powering
+                                off. If <option>--force</option> is
+                                specified twice the the operation is
+                                immediately executed without
+                                terminating any processes or
+                                unmounting any file systems. This may
+                                result in data loss.</para></listitem>
                         </varlistentry>
                         <varlistentry>
                                 <term><command>reboot</command></term>
 
-                                <listitem><para>Shut down and
-                                reboot the system. This is mostly
-                                equivalent to <command>start
+                                <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
+                                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
-                                followed by the
-                                reboot.</para></listitem>
+                                skipped, however all processes are
+                                killed and all file systems are
+                                unmounted or mounted read-only,
+                                immediately followed by the reboot. If
+                                <option>--force</option> is specified
+                                twice the the operation is immediately
+                                executed without terminating any
+                                processes or unmounting any file
+                                systems. This may result in data
+                                loss.</para></listitem>
                         </varlistentry>
                         <varlistentry>
                                 <term><command>kexec</command></term>
index ab6d126a26deca84c75b72861c310ebb591a0fd5..dc3703050e50dc0a8da2fb03433323aa4cd3bb73 100644 (file)
@@ -77,7 +77,7 @@ static bool arg_no_reload = false;
 static bool arg_dry = false;
 static bool arg_quiet = false;
 static bool arg_full = false;
-static bool arg_force = false;
+static int arg_force = 0;
 static bool arg_ask_password = false;
 static bool arg_failed = false;
 static bool arg_runtime = false;
@@ -126,6 +126,7 @@ static OutputMode arg_output = OUTPUT_SHORT;
 static bool private_bus = false;
 
 static int daemon_reload(DBusConnection *bus, char **args);
+static void halt_now(int action);
 
 static bool on_tty(void) {
         static int t = -1;
@@ -1687,6 +1688,15 @@ static int start_special(DBusConnection *bus, char **args) {
         assert(bus);
         assert(args);
 
+        if (arg_force >= 2 && streq(args[0], "halt"))
+                halt_now(ACTION_HALT);
+
+        if (arg_force >= 2 && streq(args[0], "poweroff"))
+                halt_now(ACTION_POWEROFF);
+
+        if (arg_force >= 2 && streq(args[0], "reboot"))
+                halt_now(ACTION_POWEROFF);
+
         if (arg_force &&
             (streq(args[0], "halt") ||
              streq(args[0], "poweroff") ||
@@ -4291,7 +4301,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'f':
-                        arg_force = true;
+                        arg_force ++;
                         break;
 
                 case ARG_NO_RELOAD:
@@ -5171,6 +5181,36 @@ done:
         return 0;
 }
 
+static void halt_now(int action) {
+
+       /* Make sure C-A-D is handled by the kernel from this
+         * point on... */
+        reboot(RB_ENABLE_CAD);
+
+        switch (action) {
+
+        case ACTION_HALT:
+                log_info("Halting.");
+                reboot(RB_HALT_SYSTEM);
+                break;
+
+        case ACTION_POWEROFF:
+                log_info("Powering off.");
+                reboot(RB_POWER_OFF);
+                break;
+
+        case ACTION_REBOOT:
+                log_info("Rebooting.");
+                reboot(RB_AUTOBOOT);
+                break;
+
+        default:
+                assert_not_reached("Unknown halt action.");
+        }
+
+        assert_not_reached("Uh? This shouldn't happen.");
+}
+
 static int halt_main(DBusConnection *bus) {
         int r;
 
@@ -5218,31 +5258,7 @@ static int halt_main(DBusConnection *bus) {
         if (arg_dry)
                 return 0;
 
-        /* Make sure C-A-D is handled by the kernel from this
-         * point on... */
-        reboot(RB_ENABLE_CAD);
-
-        switch (arg_action) {
-
-        case ACTION_HALT:
-                log_info("Halting.");
-                reboot(RB_HALT_SYSTEM);
-                break;
-
-        case ACTION_POWEROFF:
-                log_info("Powering off.");
-                reboot(RB_POWER_OFF);
-                break;
-
-        case ACTION_REBOOT:
-                log_info("Rebooting.");
-                reboot(RB_AUTOBOOT);
-                break;
-
-        default:
-                assert_not_reached("Unknown halt action.");
-        }
-
+        halt_now(arg_action);
         /* We should never reach this. */
         return -ENOSYS;
 }