From e606bb61d09d00ecce5f51f793dfdd8c85122cc4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Feb 2012 20:05:49 +0100 Subject: [PATCH] systemctl: introduce systemctl reboot -ff --- TODO | 2 -- man/systemctl.xml | 73 ++++++++++++++++++++++++++++++----------------- src/systemctl.c | 70 +++++++++++++++++++++++++++------------------ 3 files changed, 90 insertions(+), 55 deletions(-) diff --git a/TODO b/TODO index cba2c8cf..46d4c040 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 5adee451..3266333b 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -349,14 +349,22 @@ halt, poweroff, reboot or - kexec execute + kexec 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. + immediate reboot. If + is specified + twice for these operations, they will + be executed immediately without + terminating any processes or umounting + any file systems. Warning: specifying + twice with + any of these operations might result + in data loss. @@ -1017,14 +1025,19 @@ system. This is mostly equivalent to start halt.target but also prints a wall message to all - users. If - combined with - shutdown of all running services is - skipped, however all processes are killed - and all file systems are unmounted or + users. If combined with + 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. + followed by the system halt. If + is specified + twice the the operation is immediately + executed without terminating any + processes or unmounting any file + systems. This may result in data + loss. poweroff @@ -1033,32 +1046,40 @@ power-off the system. This is mostly equivalent to start poweroff.target but also - prints a wall message to all - users. If + prints a wall message to all users. If combined with 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. + skipped, however all processes are + killed and all file systems are + unmounted or mounted read-only, + immediately followed by the powering + off. If is + specified twice the the operation is + immediately executed without + terminating any processes or + unmounting any file systems. This may + result in data loss. reboot - Shut down and - reboot the system. This is mostly - equivalent to start + Shut down and reboot + the system. This is mostly equivalent + to start reboot.target but also - prints a wall message to all - users. If + prints a wall message to all users. If combined with 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. + skipped, however all processes are + killed and all file systems are + unmounted or mounted read-only, + immediately followed by the reboot. If + is specified + twice the the operation is immediately + executed without terminating any + processes or unmounting any file + systems. This may result in data + loss. kexec diff --git a/src/systemctl.c b/src/systemctl.c index ab6d126a..dc370305 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; } -- 2.39.5