Merge pull request #6944 from poettering/suspend-fix
systemctl reboot/suspend tweaks
This commit is contained in:
commit
c9905d4dd2
16
NEWS
16
NEWS
|
@ -190,6 +190,20 @@ CHANGES WITH 235:
|
||||||
used to control how the kernel keyring is set up for executed
|
used to control how the kernel keyring is set up for executed
|
||||||
processes.
|
processes.
|
||||||
|
|
||||||
|
* "systemctl poweroff", "systemctl reboot", "systemctl halt",
|
||||||
|
"systemctl kexec" and "systemctl exit" are now always asynchronous in
|
||||||
|
behaviour (that is: these commands return immediately after the
|
||||||
|
operation was enqueued instead of waiting until the operation was
|
||||||
|
completed). Previously, "systemctl poweroff" and "systemctl reboot"
|
||||||
|
were asynchronous on systems using systemd-logind (i.e. almost
|
||||||
|
always, and like they were on sysvinit), and the other three commands
|
||||||
|
were unconditionally synchronous. With this release this is cleaned
|
||||||
|
up, and callers will see the same asynchronous behaviour on all
|
||||||
|
systems for all five operations.
|
||||||
|
|
||||||
|
* systemd-logind gained new Halt() and CanHalt() bus calls for halting
|
||||||
|
the system.
|
||||||
|
|
||||||
* .timer units now accept calendar specifications in other timezones
|
* .timer units now accept calendar specifications in other timezones
|
||||||
than UTC or the local timezone.
|
than UTC or the local timezone.
|
||||||
|
|
||||||
|
@ -222,7 +236,7 @@ CHANGES WITH 235:
|
||||||
userwithuid, Vito Caputo, vliaskov, WaLyong Cho, William Douglas, Xiang
|
userwithuid, Vito Caputo, vliaskov, WaLyong Cho, William Douglas, Xiang
|
||||||
Fan, Yu Watanabe, Zbigniew Jędrzejewski-Szmek
|
Fan, Yu Watanabe, Zbigniew Jędrzejewski-Szmek
|
||||||
|
|
||||||
— Berlin, 2017-09-XX
|
— Berlin, 2017-10-XX
|
||||||
|
|
||||||
CHANGES WITH 234:
|
CHANGES WITH 234:
|
||||||
|
|
||||||
|
|
|
@ -407,8 +407,7 @@
|
||||||
<term><option>--no-wall</option></term>
|
<term><option>--no-wall</option></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Do not send wall message before halt, power-off,
|
<para>Do not send wall message before halt, power-off and reboot.</para>
|
||||||
reboot.</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -525,7 +524,7 @@
|
||||||
<option>--force</option> twice with any of these operations might result in data loss. Note that when
|
<option>--force</option> twice with any of these operations might result in data loss. Note that when
|
||||||
<option>--force</option> is specified twice the selected operation is executed by
|
<option>--force</option> is specified twice the selected operation is executed by
|
||||||
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
||||||
succeed even when the system manager hangs or crashed.</para>
|
succeed even when the system manager has crashed.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -533,11 +532,9 @@
|
||||||
<term><option>--message=</option></term>
|
<term><option>--message=</option></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>When used with <command>halt</command>,
|
<para>When used with <command>halt</command>, <command>poweroff</command> or <command>reboot</command>, set a
|
||||||
<command>poweroff</command>, <command>reboot</command> or
|
short message explaining the reason for the operation. The message will be logged together with the default
|
||||||
<command>kexec</command>, set a short message explaining the reason
|
shutdown message.</para>
|
||||||
for the operation. The message will be logged together with the
|
|
||||||
default shutdown message.</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1690,8 +1687,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<term><command>default</command></term>
|
<term><command>default</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Enter default mode. This is mostly equivalent to
|
<para>Enter default mode. This is equivalent to <command>systemctl isolate default.target</command>. This
|
||||||
<command>isolate default.target</command>.</para>
|
operation is blocking by default, use <option>--no-block</option> to request asynchronous behavior.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1699,72 +1696,77 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<term><command>rescue</command></term>
|
<term><command>rescue</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Enter rescue mode. This is mostly equivalent to
|
<para>Enter rescue mode. This is equivalent to <command>systemctl isolate rescue.target</command>. This
|
||||||
<command>isolate rescue.target</command>, but also prints a
|
operation is blocking by default, use <option>--no-block</option> to request asynchronous behavior.</para>
|
||||||
wall message to all users.</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>emergency</command></term>
|
<term><command>emergency</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Enter emergency mode. This is mostly equivalent to
|
<para>Enter emergency mode. This is equivalent to <command>systemctl isolate
|
||||||
<command>isolate emergency.target</command>, but also prints
|
emergency.target</command>. This operation is blocking by default, use <option>--no-block</option> to
|
||||||
a wall message to all users.</para>
|
request asynchronous behavior.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>halt</command></term>
|
<term><command>halt</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Shut down and halt the system. This is mostly equivalent to <command>start halt.target
|
<para>Shut down and halt the system. This is mostly equivalent to <command>systemctl start halt.target
|
||||||
--job-mode=replace-irreversibly</command>, but also prints a wall message to all users. If combined with
|
--job-mode=replace-irreversibly --no-block</command>, but also prints a wall message to all users. This command is
|
||||||
<option>--force</option>, shutdown of all running services is skipped, however all processes are killed and
|
asynchronous; it will return after the halt operation is enqueued, without waiting for it to complete. Note
|
||||||
all file systems are unmounted or mounted read-only, immediately followed by the system halt. If
|
that this operation will simply halt the OS kernel after shutting down, leaving the hardware powered
|
||||||
<option>--force</option> is specified twice, the operation is immediately executed without terminating any
|
on. Use <command>systemctl poweroff</command> for powering off the system (see below).</para>
|
||||||
processes or unmounting any file systems. This may result in data loss. Note that when
|
|
||||||
<option>--force</option> is specified twice the halt operation is executed by
|
<para>If combined with <option>--force</option>, shutdown of all running services is skipped, however all
|
||||||
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the
|
||||||
succeed even when the system manager hangs or crashed.</para>
|
system halt. If <option>--force</option> is specified twice, the operation is immediately executed without
|
||||||
|
terminating any processes or unmounting any file systems. This may result in data loss. Note that when
|
||||||
|
<option>--force</option> is specified twice the halt operation is executed by <command>systemctl</command>
|
||||||
|
itself, and the system manager is not contacted. This means the command should succeed even when the system
|
||||||
|
manager has crashed.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>poweroff</command></term>
|
<term><command>poweroff</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Shut down and power-off the system. This is mostly equivalent to <command>start poweroff.target
|
<para>Shut down and power-off the system. This is mostly equivalent to <command>systemctl start
|
||||||
--job-mode=replace-irreversibly</command>, but also prints a wall message to all users. If combined with
|
poweroff.target --job-mode=replace-irreversibly --no-block</command>, but also prints a wall message to all
|
||||||
<option>--force</option>, shutdown of all running services is skipped, however all processes are killed and
|
users. This command is asynchronous; it will return after the power-off operation is enqueued, without
|
||||||
all file systems are unmounted or mounted read-only, immediately followed by the powering off. If
|
waiting for it to complete.</para>
|
||||||
<option>--force</option> is specified twice, the operation is immediately executed without terminating any
|
|
||||||
processes or unmounting any file systems. This may result in data loss. Note that when
|
<para>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. If <option>--force</option> is specified twice, the operation is immediately executed without
|
||||||
|
terminating any processes or unmounting any file systems. This may result in data loss. Note that when
|
||||||
<option>--force</option> is specified twice the power-off operation is executed by
|
<option>--force</option> is specified twice the power-off operation is executed by
|
||||||
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
||||||
succeed even when the system manager hangs or crashed.</para>
|
succeed even when the system manager has crashed.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><command>reboot <optional><replaceable>arg</replaceable></optional></command></term>
|
<term><command>reboot <optional><replaceable>arg</replaceable></optional></command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Shut down and reboot the system. This is mostly equivalent to <command>start reboot.target
|
<para>Shut down and reboot the system. This is mostly equivalent to <command>systemctl start reboot.target
|
||||||
--job-mode=replace-irreversibly</command>, but also prints a wall message to all users. If combined with
|
--job-mode=replace-irreversibly --no-block</command>, but also prints a wall message to all users. This
|
||||||
<option>--force</option>, shutdown of all running services is skipped, however all processes are killed and
|
command is asynchronous; it will return after the reboot operation is enqueued, without waiting for it to
|
||||||
all file systems are unmounted or mounted read-only, immediately followed by the reboot. If
|
complete.</para>
|
||||||
<option>--force</option> is specified twice, the operation is immediately executed without terminating any
|
|
||||||
processes or unmounting any file systems. This may result in data loss. Note that when
|
<para>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. If <option>--force</option> is specified twice, the operation is immediately executed without
|
||||||
|
terminating any processes or unmounting any file systems. This may result in data loss. Note that when
|
||||||
<option>--force</option> is specified twice the reboot operation is executed by
|
<option>--force</option> is specified twice the reboot operation is executed by
|
||||||
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should
|
||||||
succeed even when the system manager hangs or crashed.</para>
|
succeed even when the system manager has crashed.</para>
|
||||||
|
|
||||||
<para>If the optional argument
|
<para>If the optional argument <replaceable>arg</replaceable> is given, it will be passed as the optional
|
||||||
<replaceable>arg</replaceable> is given, it will be passed
|
argument to the <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
as the optional argument to the
|
system call. The value is architecture and firmware specific. As an example, <literal>recovery</literal>
|
||||||
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
might be used to trigger system recovery, and <literal>fota</literal> might be used to trigger a
|
||||||
system call. The value is architecture and firmware
|
|
||||||
specific. As an example, <literal>recovery</literal> might
|
|
||||||
be used to trigger system recovery, and
|
|
||||||
<literal>fota</literal> might be used to trigger a
|
|
||||||
<quote>firmware over the air</quote> update.</para>
|
<quote>firmware over the air</quote> update.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -1773,13 +1775,14 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<term><command>kexec</command></term>
|
<term><command>kexec</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Shut down and reboot the system via kexec. This is
|
<para>Shut down and reboot the system via <command>kexec</command>. This is equivalent to
|
||||||
mostly equivalent to <command>start kexec.target --job-mode=replace-irreversibly</command>,
|
<command>systemctl start kexec.target --job-mode=replace-irreversibly --no-block</command>. This command is
|
||||||
but also prints a wall message to all users. If combined
|
asynchronous; it will return after the reboot operation is enqueued, without waiting for it to
|
||||||
with <option>--force</option>, shutdown of all running
|
complete.</para>
|
||||||
services is skipped, however all processes are killed and
|
|
||||||
all file systems are unmounted or mounted read-only,
|
<para>If combined with <option>--force</option>, shutdown of all running services is skipped, however all
|
||||||
immediately followed by the reboot.</para>
|
processes are killed and all file systems are unmounted or mounted read-only, immediately followed by the
|
||||||
|
reboot.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1787,14 +1790,13 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<term><command>exit <optional><replaceable>EXIT_CODE</replaceable></optional></command></term>
|
<term><command>exit <optional><replaceable>EXIT_CODE</replaceable></optional></command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Ask the systemd manager to quit. This is only
|
<para>Ask the service manager to quit. This is only supported for user service managers (i.e. in
|
||||||
supported for user service managers (i.e. in conjunction
|
conjunction with the <option>--user</option> option) or in containers and is equivalent to
|
||||||
with the <option>--user</option> option) or in containers
|
<command>poweroff</command> otherwise. This command is asynchronous; it will return after the exit
|
||||||
and is equivalent to <command>poweroff</command> otherwise.</para>
|
operation is enqueued, without waiting for it to complete.</para>
|
||||||
|
|
||||||
<para>The systemd manager can exit with a non-zero exit
|
<para>The service manager will exit with the the specified exit code, if
|
||||||
code if the optional argument
|
<replaceable>EXIT_CODE</replaceable> is passed.</para>
|
||||||
<replaceable>EXIT_CODE</replaceable> is given.</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1818,9 +1820,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<term><command>suspend</command></term>
|
<term><command>suspend</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Suspend the system. This will trigger activation of
|
<para>Suspend the system. This will trigger activation of the special target unit
|
||||||
the special <filename>suspend.target</filename> target.
|
<filename>suspend.target</filename>. This command is asynchronous, and will return after the suspend
|
||||||
</para>
|
operation is successfully enqueued. It will not wait for the suspend/resume cycle to complete.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1828,9 +1830,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<term><command>hibernate</command></term>
|
<term><command>hibernate</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Hibernate the system. This will trigger activation of
|
<para>Hibernate the system. This will trigger activation of the special target unit
|
||||||
the special <filename>hibernate.target</filename> target.
|
<filename>hibernate.target</filename>. This command is asynchronous, and will return after the hibernation
|
||||||
</para>
|
operation is successfully enqueued. It will not wait for the hibernate/thaw cycle to complete.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1838,9 +1840,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||||
<term><command>hybrid-sleep</command></term>
|
<term><command>hybrid-sleep</command></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Hibernate and suspend the system. This will trigger
|
<para>Hibernate and suspend the system. This will trigger activation of the special target unit
|
||||||
activation of the special
|
<filename>hybrid-sleep.target</filename>. This command is asynchronous, and will return after the hybrid
|
||||||
<filename>hybrid-sleep.target</filename> target.</para>
|
sleep operation is successfully enqueued. It will not wait for the sleep/wake-up cycle to complete.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
|
@ -1409,12 +1409,12 @@ static int bus_manager_log_shutdown(
|
||||||
if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
|
if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
|
||||||
p = "MESSAGE=System is powering down";
|
p = "MESSAGE=System is powering down";
|
||||||
q = "SHUTDOWN=power-off";
|
q = "SHUTDOWN=power-off";
|
||||||
} else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
|
|
||||||
p = "MESSAGE=System is halting";
|
|
||||||
q = "SHUTDOWN=halt";
|
|
||||||
} else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
|
} else if (streq(unit_name, SPECIAL_REBOOT_TARGET)) {
|
||||||
p = "MESSAGE=System is rebooting";
|
p = "MESSAGE=System is rebooting";
|
||||||
q = "SHUTDOWN=reboot";
|
q = "SHUTDOWN=reboot";
|
||||||
|
} else if (streq(unit_name, SPECIAL_HALT_TARGET)) {
|
||||||
|
p = "MESSAGE=System is halting";
|
||||||
|
q = "SHUTDOWN=halt";
|
||||||
} else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
|
} else if (streq(unit_name, SPECIAL_KEXEC_TARGET)) {
|
||||||
p = "MESSAGE=System is rebooting with kexec";
|
p = "MESSAGE=System is rebooting with kexec";
|
||||||
q = "SHUTDOWN=kexec";
|
q = "SHUTDOWN=kexec";
|
||||||
|
@ -1822,6 +1822,20 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
return method_do_shutdown_or_sleep(
|
||||||
|
m, message,
|
||||||
|
SPECIAL_HALT_TARGET,
|
||||||
|
INHIBIT_SHUTDOWN,
|
||||||
|
"org.freedesktop.login1.halt",
|
||||||
|
"org.freedesktop.login1.halt-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.halt-ignore-inhibit",
|
||||||
|
NULL,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
Manager *m = userdata;
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
@ -1836,6 +1850,34 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
return method_do_shutdown_or_sleep(
|
||||||
|
m, message,
|
||||||
|
SPECIAL_HIBERNATE_TARGET,
|
||||||
|
INHIBIT_SLEEP,
|
||||||
|
"org.freedesktop.login1.hibernate",
|
||||||
|
"org.freedesktop.login1.hibernate-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.hibernate-ignore-inhibit",
|
||||||
|
"hibernate",
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
return method_do_shutdown_or_sleep(
|
||||||
|
m, message,
|
||||||
|
SPECIAL_HYBRID_SLEEP_TARGET,
|
||||||
|
INHIBIT_SLEEP,
|
||||||
|
"org.freedesktop.login1.hibernate",
|
||||||
|
"org.freedesktop.login1.hibernate-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.hibernate-ignore-inhibit",
|
||||||
|
"hybrid-sleep",
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
static int nologin_timeout_handler(
|
static int nologin_timeout_handler(
|
||||||
sd_event_source *s,
|
sd_event_source *s,
|
||||||
uint64_t usec,
|
uint64_t usec,
|
||||||
|
@ -1911,9 +1953,12 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_scheduled_shutdown(Manager *m) {
|
static void reset_scheduled_shutdown(Manager *m) {
|
||||||
|
assert(m);
|
||||||
|
|
||||||
m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
|
m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
|
||||||
m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
|
m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
|
||||||
m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
|
m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
|
||||||
|
|
||||||
m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
|
m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
|
||||||
m->scheduled_shutdown_timeout = 0;
|
m->scheduled_shutdown_timeout = 0;
|
||||||
m->shutdown_dry_run = false;
|
m->shutdown_dry_run = false;
|
||||||
|
@ -1922,6 +1967,7 @@ static void reset_scheduled_shutdown(Manager *m) {
|
||||||
(void) unlink("/run/nologin");
|
(void) unlink("/run/nologin");
|
||||||
m->unlink_nologin = false;
|
m->unlink_nologin = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) unlink("/run/systemd/shutdown/scheduled");
|
(void) unlink("/run/systemd/shutdown/scheduled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1940,12 +1986,14 @@ static int manager_scheduled_shutdown_handler(
|
||||||
if (isempty(m->scheduled_shutdown_type))
|
if (isempty(m->scheduled_shutdown_type))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (streq(m->scheduled_shutdown_type, "halt"))
|
if (streq(m->scheduled_shutdown_type, "poweroff"))
|
||||||
target = SPECIAL_HALT_TARGET;
|
|
||||||
else if (streq(m->scheduled_shutdown_type, "poweroff"))
|
|
||||||
target = SPECIAL_POWEROFF_TARGET;
|
target = SPECIAL_POWEROFF_TARGET;
|
||||||
else
|
else if (streq(m->scheduled_shutdown_type, "reboot"))
|
||||||
target = SPECIAL_REBOOT_TARGET;
|
target = SPECIAL_REBOOT_TARGET;
|
||||||
|
else if (streq(m->scheduled_shutdown_type, "halt"))
|
||||||
|
target = SPECIAL_HALT_TARGET;
|
||||||
|
else
|
||||||
|
assert_not_reached("unexpected shutdown type");
|
||||||
|
|
||||||
/* Don't allow multiple jobs being executed at the same time */
|
/* Don't allow multiple jobs being executed at the same time */
|
||||||
if (m->action_what) {
|
if (m->action_what) {
|
||||||
|
@ -1989,6 +2037,7 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
|
||||||
uint64_t elapse;
|
uint64_t elapse;
|
||||||
char *type;
|
char *type;
|
||||||
int r;
|
int r;
|
||||||
|
bool dry_run = false;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(message);
|
assert(message);
|
||||||
|
@ -1999,10 +2048,14 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
|
||||||
|
|
||||||
if (startswith(type, "dry-")) {
|
if (startswith(type, "dry-")) {
|
||||||
type += 4;
|
type += 4;
|
||||||
m->shutdown_dry_run = true;
|
dry_run = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(type, "reboot")) {
|
if (streq(type, "poweroff")) {
|
||||||
|
action = "org.freedesktop.login1.power-off";
|
||||||
|
action_multiple_sessions = "org.freedesktop.login1.power-off-multiple-sessions";
|
||||||
|
action_ignore_inhibit = "org.freedesktop.login1.power-off-ignore-inhibit";
|
||||||
|
} else if (streq(type, "reboot")) {
|
||||||
action = "org.freedesktop.login1.reboot";
|
action = "org.freedesktop.login1.reboot";
|
||||||
action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
|
action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
|
||||||
action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
|
action_ignore_inhibit = "org.freedesktop.login1.reboot-ignore-inhibit";
|
||||||
|
@ -2010,10 +2063,6 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
|
||||||
action = "org.freedesktop.login1.halt";
|
action = "org.freedesktop.login1.halt";
|
||||||
action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
|
action_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
|
||||||
action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
|
action_ignore_inhibit = "org.freedesktop.login1.halt-ignore-inhibit";
|
||||||
} else if (streq(type, "poweroff")) {
|
|
||||||
action = "org.freedesktop.login1.power-off";
|
|
||||||
action_multiple_sessions = "org.freedesktop.login1.power-off-multiple-sessions";
|
|
||||||
action_ignore_inhibit = "org.freedesktop.login1.power-off-ignore-inhibit";
|
|
||||||
} else
|
} else
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
|
||||||
|
|
||||||
|
@ -2043,6 +2092,8 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
|
||||||
return log_oom();
|
return log_oom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m->shutdown_dry_run = dry_run;
|
||||||
|
|
||||||
if (m->nologin_timeout_source) {
|
if (m->nologin_timeout_source) {
|
||||||
r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
|
r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -2114,34 +2165,6 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
|
||||||
return sd_bus_reply_method_return(message, "b", cancelled);
|
return sd_bus_reply_method_return(message, "b", cancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
||||||
Manager *m = userdata;
|
|
||||||
|
|
||||||
return method_do_shutdown_or_sleep(
|
|
||||||
m, message,
|
|
||||||
SPECIAL_HIBERNATE_TARGET,
|
|
||||||
INHIBIT_SLEEP,
|
|
||||||
"org.freedesktop.login1.hibernate",
|
|
||||||
"org.freedesktop.login1.hibernate-multiple-sessions",
|
|
||||||
"org.freedesktop.login1.hibernate-ignore-inhibit",
|
|
||||||
"hibernate",
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
|
||||||
Manager *m = userdata;
|
|
||||||
|
|
||||||
return method_do_shutdown_or_sleep(
|
|
||||||
m, message,
|
|
||||||
SPECIAL_HYBRID_SLEEP_TARGET,
|
|
||||||
INHIBIT_SLEEP,
|
|
||||||
"org.freedesktop.login1.hibernate",
|
|
||||||
"org.freedesktop.login1.hibernate-multiple-sessions",
|
|
||||||
"org.freedesktop.login1.hibernate-ignore-inhibit",
|
|
||||||
"hybrid-sleep",
|
|
||||||
error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int method_can_shutdown_or_sleep(
|
static int method_can_shutdown_or_sleep(
|
||||||
Manager *m,
|
Manager *m,
|
||||||
sd_bus_message *message,
|
sd_bus_message *message,
|
||||||
|
@ -2260,6 +2283,19 @@ static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_err
|
||||||
error);
|
error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int method_can_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
return method_can_shutdown_or_sleep(
|
||||||
|
m, message,
|
||||||
|
INHIBIT_SHUTDOWN,
|
||||||
|
"org.freedesktop.login1.halt",
|
||||||
|
"org.freedesktop.login1.halt-multiple-sessions",
|
||||||
|
"org.freedesktop.login1.halt-ignore-inhibit",
|
||||||
|
NULL,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
static int method_can_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
Manager *m = userdata;
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
@ -2612,11 +2648,13 @@ const sd_bus_vtable manager_vtable[] = {
|
||||||
SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD("Halt", "b", NULL, method_halt, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD("CanHalt", NULL, "s", method_can_halt, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
|
|
@ -132,6 +132,10 @@
|
||||||
send_interface="org.freedesktop.login1.Manager"
|
send_interface="org.freedesktop.login1.Manager"
|
||||||
send_member="Reboot"/>
|
send_member="Reboot"/>
|
||||||
|
|
||||||
|
<allow send_destination="org.freedesktop.login1"
|
||||||
|
send_interface="org.freedesktop.login1.Manager"
|
||||||
|
send_member="Halt"/>
|
||||||
|
|
||||||
<allow send_destination="org.freedesktop.login1"
|
<allow send_destination="org.freedesktop.login1"
|
||||||
send_interface="org.freedesktop.login1.Manager"
|
send_interface="org.freedesktop.login1.Manager"
|
||||||
send_member="Suspend"/>
|
send_member="Suspend"/>
|
||||||
|
@ -152,6 +156,10 @@
|
||||||
send_interface="org.freedesktop.login1.Manager"
|
send_interface="org.freedesktop.login1.Manager"
|
||||||
send_member="CanReboot"/>
|
send_member="CanReboot"/>
|
||||||
|
|
||||||
|
<allow send_destination="org.freedesktop.login1"
|
||||||
|
send_interface="org.freedesktop.login1.Manager"
|
||||||
|
send_member="CanHalt"/>
|
||||||
|
|
||||||
<allow send_destination="org.freedesktop.login1"
|
<allow send_destination="org.freedesktop.login1"
|
||||||
send_interface="org.freedesktop.login1.Manager"
|
send_interface="org.freedesktop.login1.Manager"
|
||||||
send_member="CanSuspend"/>
|
send_member="CanSuspend"/>
|
||||||
|
|
|
@ -218,6 +218,39 @@
|
||||||
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
|
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action id="org.freedesktop.login1.halt">
|
||||||
|
<_description>Halt the system</_description>
|
||||||
|
<_message>Authentication is required for halting the system.</_message>
|
||||||
|
<defaults>
|
||||||
|
<allow_any>auth_admin_keep</allow_any>
|
||||||
|
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||||
|
<allow_active>auth_admin_keep</allow_active>
|
||||||
|
</defaults>
|
||||||
|
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.set-wall-message</annotate>
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action id="org.freedesktop.login1.halt-multiple-sessions">
|
||||||
|
<_description>Halt the system while other users are logged in</_description>
|
||||||
|
<_message>Authentication is required for halting the system while other users are logged in.</_message>
|
||||||
|
<defaults>
|
||||||
|
<allow_any>auth_admin_keep</allow_any>
|
||||||
|
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||||
|
<allow_active>auth_admin_keep</allow_active>
|
||||||
|
</defaults>
|
||||||
|
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.halt</annotate>
|
||||||
|
</action>
|
||||||
|
|
||||||
|
<action id="org.freedesktop.login1.halt-ignore-inhibit">
|
||||||
|
<_description>Halt the system while an application asked to inhibit it</_description>
|
||||||
|
<_message>Authentication is required for halting the system while an application asked to inhibit it.</_message>
|
||||||
|
<defaults>
|
||||||
|
<allow_any>auth_admin_keep</allow_any>
|
||||||
|
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||||
|
<allow_active>auth_admin_keep</allow_active>
|
||||||
|
</defaults>
|
||||||
|
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.halt</annotate>
|
||||||
|
</action>
|
||||||
|
|
||||||
<action id="org.freedesktop.login1.suspend">
|
<action id="org.freedesktop.login1.suspend">
|
||||||
<_description>Suspend the system</_description>
|
<_description>Suspend the system</_description>
|
||||||
<_message>Authentication is required for suspending the system.</_message>
|
<_message>Authentication is required for suspending the system.</_message>
|
||||||
|
|
|
@ -3267,14 +3267,19 @@ static int logind_reboot(enum action a) {
|
||||||
|
|
||||||
switch (a) {
|
switch (a) {
|
||||||
|
|
||||||
|
case ACTION_POWEROFF:
|
||||||
|
method = "PowerOff";
|
||||||
|
description = "power off system";
|
||||||
|
break;
|
||||||
|
|
||||||
case ACTION_REBOOT:
|
case ACTION_REBOOT:
|
||||||
method = "Reboot";
|
method = "Reboot";
|
||||||
description = "reboot system";
|
description = "reboot system";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_POWEROFF:
|
case ACTION_HALT:
|
||||||
method = "PowerOff";
|
method = "Halt";
|
||||||
description = "power off system";
|
description = "halt system";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_SUSPEND:
|
case ACTION_SUSPEND:
|
||||||
|
@ -3568,6 +3573,7 @@ static int start_special(int argc, char *argv[], void *userdata) {
|
||||||
if (IN_SET(a,
|
if (IN_SET(a,
|
||||||
ACTION_POWEROFF,
|
ACTION_POWEROFF,
|
||||||
ACTION_REBOOT,
|
ACTION_REBOOT,
|
||||||
|
ACTION_HALT,
|
||||||
ACTION_SUSPEND,
|
ACTION_SUSPEND,
|
||||||
ACTION_HIBERNATE,
|
ACTION_HIBERNATE,
|
||||||
ACTION_HYBRID_SLEEP)) {
|
ACTION_HYBRID_SLEEP)) {
|
||||||
|
@ -3579,8 +3585,16 @@ static int start_special(int argc, char *argv[], void *userdata) {
|
||||||
/* requested operation is not supported or already in progress */
|
/* requested operation is not supported or already in progress */
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* On all other errors, try low-level operation */
|
/* On all other errors, try low-level operation. In order to minimize the difference between
|
||||||
}
|
* operation with and without logind, we explicitly enable non-blocking mode for this, as
|
||||||
|
* logind's shutdown operations are always non-blocking. */
|
||||||
|
|
||||||
|
arg_no_block = true;
|
||||||
|
|
||||||
|
} else if (IN_SET(a, ACTION_EXIT, ACTION_KEXEC))
|
||||||
|
/* Since exit/kexec are so close in behaviour to power-off/reboot, let's also make them
|
||||||
|
* asynchronous, in order to not confuse the user needlessly with unexpected behaviour. */
|
||||||
|
arg_no_block = true;
|
||||||
|
|
||||||
r = start_unit(argc, argv, userdata);
|
r = start_unit(argc, argv, userdata);
|
||||||
}
|
}
|
||||||
|
@ -8503,7 +8517,7 @@ static int halt_main(void) {
|
||||||
/* Try logind if we are a normal user and no special
|
/* Try logind if we are a normal user and no special
|
||||||
* mode applies. Maybe PolicyKit allows us to shutdown
|
* mode applies. Maybe PolicyKit allows us to shutdown
|
||||||
* the machine. */
|
* the machine. */
|
||||||
if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT)) {
|
if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT, ACTION_HALT)) {
|
||||||
r = logind_reboot(arg_action);
|
r = logind_reboot(arg_action);
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
Loading…
Reference in a new issue