diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | man/systemctl.xml | 73 | ||||
-rw-r--r-- | src/systemctl.c | 70 |
3 files changed, 90 insertions, 55 deletions
@@ -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; } |