systemctl: introduce systemctl reboot -ff

This commit is contained in:
Lennart Poettering 2012-02-15 20:05:49 +01:00
parent d4eb120a23
commit e606bb61d0
3 changed files with 90 additions and 55 deletions

2
TODO
View file

@ -21,8 +21,6 @@ Bugfixes:
Features: Features:
* systemctl reboot -ff should trigger an immediate reboot
* support units generated by a generator and placed in /run/systemd/system/; the directory is * 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 currently ignored because it is empty before the generatores are executed

View file

@ -349,14 +349,22 @@
<command>halt</command>, <command>halt</command>,
<command>poweroff</command>, <command>poweroff</command>,
<command>reboot</command> or <command>reboot</command> or
<command>kexec</command> execute <command>kexec</command> execute the
selected operation without shutting selected operation without shutting
down all units. However, all processes down all units. However, all processes
will be killed forcibly and all file will be killed forcibly and all file
systems are unmounted or remounted systems are unmounted or remounted
read-only. This is hence a drastic but read-only. This is hence a drastic but
relatively safe option to request an 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>
<varlistentry> <varlistentry>
@ -1017,14 +1025,19 @@
system. This is mostly equivalent to system. This is mostly equivalent to
<command>start halt.target</command> <command>start halt.target</command>
but also prints a wall message to all but also prints a wall message to all
users. If users. If combined with
combined with <option>--force</option> <option>--force</option> shutdown of
shutdown of all running services is all running services is skipped,
skipped, however all processes are killed however all processes are killed and
and all file systems are unmounted or all file systems are unmounted or
mounted read-only, immediately mounted read-only, immediately
followed by the followed by the system halt. If
system halt.</para></listitem> <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>
<varlistentry> <varlistentry>
<term><command>poweroff</command></term> <term><command>poweroff</command></term>
@ -1033,32 +1046,40 @@
power-off the system. This is mostly power-off the system. This is mostly
equivalent to <command>start equivalent to <command>start
poweroff.target</command> but also poweroff.target</command> but also
prints a wall message to all prints a wall message to all users. If
users. If
combined with <option>--force</option> combined with <option>--force</option>
shutdown of all running services is shutdown of all running services is
skipped, however all processes are killed skipped, however all processes are
and all file systems are unmounted or killed and all file systems are
mounted read-only, immediately unmounted or mounted read-only,
followed by the immediately followed by the powering
powering off.</para></listitem> 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>
<varlistentry> <varlistentry>
<term><command>reboot</command></term> <term><command>reboot</command></term>
<listitem><para>Shut down and <listitem><para>Shut down and reboot
reboot the system. This is mostly the system. This is mostly equivalent
equivalent to <command>start to <command>start
reboot.target</command> but also reboot.target</command> but also
prints a wall message to all prints a wall message to all users. If
users. If
combined with <option>--force</option> combined with <option>--force</option>
shutdown of all running services is shutdown of all running services is
skipped, however all processes are killed skipped, however all processes are
and all file systems are unmounted or killed and all file systems are
mounted read-only, immediately unmounted or mounted read-only,
followed by the immediately followed by the reboot. If
reboot.</para></listitem> <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>
<varlistentry> <varlistentry>
<term><command>kexec</command></term> <term><command>kexec</command></term>

View file

@ -77,7 +77,7 @@ static bool arg_no_reload = false;
static bool arg_dry = false; static bool arg_dry = false;
static bool arg_quiet = false; static bool arg_quiet = false;
static bool arg_full = 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_ask_password = false;
static bool arg_failed = false; static bool arg_failed = false;
static bool arg_runtime = false; static bool arg_runtime = false;
@ -126,6 +126,7 @@ static OutputMode arg_output = OUTPUT_SHORT;
static bool private_bus = false; static bool private_bus = false;
static int daemon_reload(DBusConnection *bus, char **args); static int daemon_reload(DBusConnection *bus, char **args);
static void halt_now(int action);
static bool on_tty(void) { static bool on_tty(void) {
static int t = -1; static int t = -1;
@ -1687,6 +1688,15 @@ static int start_special(DBusConnection *bus, char **args) {
assert(bus); assert(bus);
assert(args); 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 && if (arg_force &&
(streq(args[0], "halt") || (streq(args[0], "halt") ||
streq(args[0], "poweroff") || streq(args[0], "poweroff") ||
@ -4291,7 +4301,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break; break;
case 'f': case 'f':
arg_force = true; arg_force ++;
break; break;
case ARG_NO_RELOAD: case ARG_NO_RELOAD:
@ -5171,6 +5181,36 @@ done:
return 0; 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) { static int halt_main(DBusConnection *bus) {
int r; int r;
@ -5218,31 +5258,7 @@ static int halt_main(DBusConnection *bus) {
if (arg_dry) if (arg_dry)
return 0; return 0;
/* Make sure C-A-D is handled by the kernel from this halt_now(arg_action);
* 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.");
}
/* We should never reach this. */ /* We should never reach this. */
return -ENOSYS; return -ENOSYS;
} }