summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--man/systemctl.xml73
-rw-r--r--src/systemctl.c70
3 files changed, 90 insertions, 55 deletions
diff --git a/TODO b/TODO
index cba2c8cfec..46d4c0402d 100644
--- 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
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 5adee45163..3266333be1 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -349,14 +349,22 @@
<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>
@@ -1017,14 +1025,19 @@
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>
@@ -1033,32 +1046,40 @@
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>
diff --git a/src/systemctl.c b/src/systemctl.c
index ab6d126a26..dc3703050e 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -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;
}