mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-08 21:17:47 +03:00
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
|
||||
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
|
||||
than UTC or the local timezone.
|
||||
|
||||
@ -222,7 +236,7 @@ CHANGES WITH 235:
|
||||
userwithuid, Vito Caputo, vliaskov, WaLyong Cho, William Douglas, Xiang
|
||||
Fan, Yu Watanabe, Zbigniew Jędrzejewski-Szmek
|
||||
|
||||
— Berlin, 2017-09-XX
|
||||
— Berlin, 2017-10-XX
|
||||
|
||||
CHANGES WITH 234:
|
||||
|
||||
|
@ -407,8 +407,7 @@
|
||||
<term><option>--no-wall</option></term>
|
||||
|
||||
<listitem>
|
||||
<para>Do not send wall message before halt, power-off,
|
||||
reboot.</para>
|
||||
<para>Do not send wall message before halt, power-off and reboot.</para>
|
||||
</listitem>
|
||||
</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> 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
|
||||
succeed even when the system manager hangs or crashed.</para>
|
||||
succeed even when the system manager has crashed.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
@ -533,11 +532,9 @@
|
||||
<term><option>--message=</option></term>
|
||||
|
||||
<listitem>
|
||||
<para>When used with <command>halt</command>,
|
||||
<command>poweroff</command>, <command>reboot</command> or
|
||||
<command>kexec</command>, set a short message explaining the reason
|
||||
for the operation. The message will be logged together with the
|
||||
default shutdown message.</para>
|
||||
<para>When used with <command>halt</command>, <command>poweroff</command> or <command>reboot</command>, set a
|
||||
short message explaining the reason for the operation. The message will be logged together with the default
|
||||
shutdown message.</para>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
<listitem>
|
||||
<para>Enter default mode. This is mostly equivalent to
|
||||
<command>isolate default.target</command>.</para>
|
||||
<para>Enter default mode. This is equivalent to <command>systemctl isolate default.target</command>. This
|
||||
operation is blocking by default, use <option>--no-block</option> to request asynchronous behavior.</para>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
<listitem>
|
||||
<para>Enter rescue mode. This is mostly equivalent to
|
||||
<command>isolate rescue.target</command>, but also prints a
|
||||
wall message to all users.</para>
|
||||
<para>Enter rescue mode. This is equivalent to <command>systemctl isolate rescue.target</command>. This
|
||||
operation is blocking by default, use <option>--no-block</option> to request asynchronous behavior.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>emergency</command></term>
|
||||
|
||||
<listitem>
|
||||
<para>Enter emergency mode. This is mostly equivalent to
|
||||
<command>isolate emergency.target</command>, but also prints
|
||||
a wall message to all users.</para>
|
||||
<para>Enter emergency mode. This is equivalent to <command>systemctl isolate
|
||||
emergency.target</command>. This operation is blocking by default, use <option>--no-block</option> to
|
||||
request asynchronous behavior.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>halt</command></term>
|
||||
|
||||
<listitem>
|
||||
<para>Shut down and halt the system. This is mostly equivalent to <command>start halt.target
|
||||
--job-mode=replace-irreversibly</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 mounted read-only, immediately followed by the 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 hangs or crashed.</para>
|
||||
<para>Shut down and halt the system. This is mostly equivalent to <command>systemctl start halt.target
|
||||
--job-mode=replace-irreversibly --no-block</command>, but also prints a wall message to all users. This command is
|
||||
asynchronous; it will return after the halt operation is enqueued, without waiting for it to complete. Note
|
||||
that this operation will simply halt the OS kernel after shutting down, leaving the hardware powered
|
||||
on. Use <command>systemctl poweroff</command> for powering off the system (see below).</para>
|
||||
|
||||
<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
|
||||
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>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>poweroff</command></term>
|
||||
|
||||
<listitem>
|
||||
<para>Shut down and power-off the system. This is mostly equivalent to <command>start poweroff.target
|
||||
--job-mode=replace-irreversibly</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 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
|
||||
<para>Shut down and power-off the system. This is mostly equivalent to <command>systemctl start
|
||||
poweroff.target --job-mode=replace-irreversibly --no-block</command>, but also prints a wall message to all
|
||||
users. This command is asynchronous; it will return after the power-off operation is enqueued, without
|
||||
waiting for it to complete.</para>
|
||||
|
||||
<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
|
||||
<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>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><command>reboot <optional><replaceable>arg</replaceable></optional></command></term>
|
||||
|
||||
<listitem>
|
||||
<para>Shut down and reboot the system. This is mostly equivalent to <command>start reboot.target
|
||||
--job-mode=replace-irreversibly</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 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
|
||||
<para>Shut down and reboot the system. This is mostly equivalent to <command>systemctl start reboot.target
|
||||
--job-mode=replace-irreversibly --no-block</command>, but also prints a wall message to all users. This
|
||||
command is asynchronous; it will return after the reboot operation is enqueued, without waiting for it to
|
||||
complete.</para>
|
||||
|
||||
<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
|
||||
<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
|
||||
<replaceable>arg</replaceable> is given, it will be passed
|
||||
as the optional argument to the
|
||||
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
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
|
||||
<para>If the optional argument <replaceable>arg</replaceable> is given, it will be passed as the optional
|
||||
argument to the <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
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>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
<listitem>
|
||||
<para>Shut down and reboot the system via kexec. This is
|
||||
mostly equivalent to <command>start kexec.target --job-mode=replace-irreversibly</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 mounted read-only,
|
||||
immediately followed by the reboot.</para>
|
||||
<para>Shut down and reboot the system via <command>kexec</command>. This is equivalent to
|
||||
<command>systemctl start kexec.target --job-mode=replace-irreversibly --no-block</command>. This command is
|
||||
asynchronous; it will return after the reboot operation is enqueued, without waiting for it to
|
||||
complete.</para>
|
||||
|
||||
<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.</para>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
<listitem>
|
||||
<para>Ask the systemd manager to quit. This is only
|
||||
supported for user service managers (i.e. in conjunction
|
||||
with the <option>--user</option> option) or in containers
|
||||
and is equivalent to <command>poweroff</command> otherwise.</para>
|
||||
<para>Ask the service manager to quit. This is only supported for user service managers (i.e. in
|
||||
conjunction with the <option>--user</option> option) or in containers and is equivalent to
|
||||
<command>poweroff</command> otherwise. This command is asynchronous; it will return after the exit
|
||||
operation is enqueued, without waiting for it to complete.</para>
|
||||
|
||||
<para>The systemd manager can exit with a non-zero exit
|
||||
code if the optional argument
|
||||
<replaceable>EXIT_CODE</replaceable> is given.</para>
|
||||
<para>The service manager will exit with the the specified exit code, if
|
||||
<replaceable>EXIT_CODE</replaceable> is passed.</para>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
<listitem>
|
||||
<para>Suspend the system. This will trigger activation of
|
||||
the special <filename>suspend.target</filename> target.
|
||||
</para>
|
||||
<para>Suspend the system. This will trigger activation of the special target unit
|
||||
<filename>suspend.target</filename>. This command is asynchronous, and will return after the suspend
|
||||
operation is successfully enqueued. It will not wait for the suspend/resume cycle to complete.</para>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
<listitem>
|
||||
<para>Hibernate the system. This will trigger activation of
|
||||
the special <filename>hibernate.target</filename> target.
|
||||
</para>
|
||||
<para>Hibernate the system. This will trigger activation of the special target unit
|
||||
<filename>hibernate.target</filename>. This command is asynchronous, and will return after the hibernation
|
||||
operation is successfully enqueued. It will not wait for the hibernate/thaw cycle to complete.</para>
|
||||
</listitem>
|
||||
</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>
|
||||
|
||||
<listitem>
|
||||
<para>Hibernate and suspend the system. This will trigger
|
||||
activation of the special
|
||||
<filename>hybrid-sleep.target</filename> target.</para>
|
||||
<para>Hibernate and suspend the system. This will trigger activation of the special target unit
|
||||
<filename>hybrid-sleep.target</filename>. This command is asynchronous, and will return after the hybrid
|
||||
sleep operation is successfully enqueued. It will not wait for the sleep/wake-up cycle to complete.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
@ -1409,12 +1409,12 @@ static int bus_manager_log_shutdown(
|
||||
if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
|
||||
p = "MESSAGE=System is powering down";
|
||||
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)) {
|
||||
p = "MESSAGE=System is rebooting";
|
||||
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)) {
|
||||
p = "MESSAGE=System is rebooting with kexec";
|
||||
q = "SHUTDOWN=kexec";
|
||||
@ -1822,6 +1822,20 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_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) {
|
||||
Manager *m = userdata;
|
||||
|
||||
@ -1836,6 +1850,34 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_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(
|
||||
sd_event_source *s,
|
||||
uint64_t usec,
|
||||
@ -1911,9 +1953,12 @@ fail:
|
||||
}
|
||||
|
||||
static void reset_scheduled_shutdown(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
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->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
|
||||
|
||||
m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
|
||||
m->scheduled_shutdown_timeout = 0;
|
||||
m->shutdown_dry_run = false;
|
||||
@ -1922,6 +1967,7 @@ static void reset_scheduled_shutdown(Manager *m) {
|
||||
(void) unlink("/run/nologin");
|
||||
m->unlink_nologin = false;
|
||||
}
|
||||
|
||||
(void) unlink("/run/systemd/shutdown/scheduled");
|
||||
}
|
||||
|
||||
@ -1940,12 +1986,14 @@ static int manager_scheduled_shutdown_handler(
|
||||
if (isempty(m->scheduled_shutdown_type))
|
||||
return 0;
|
||||
|
||||
if (streq(m->scheduled_shutdown_type, "halt"))
|
||||
target = SPECIAL_HALT_TARGET;
|
||||
else if (streq(m->scheduled_shutdown_type, "poweroff"))
|
||||
if (streq(m->scheduled_shutdown_type, "poweroff"))
|
||||
target = SPECIAL_POWEROFF_TARGET;
|
||||
else
|
||||
else if (streq(m->scheduled_shutdown_type, "reboot"))
|
||||
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 */
|
||||
if (m->action_what) {
|
||||
@ -1989,6 +2037,7 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
|
||||
uint64_t elapse;
|
||||
char *type;
|
||||
int r;
|
||||
bool dry_run = false;
|
||||
|
||||
assert(m);
|
||||
assert(message);
|
||||
@ -1999,10 +2048,14 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
|
||||
|
||||
if (startswith(type, "dry-")) {
|
||||
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_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions";
|
||||
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_multiple_sessions = "org.freedesktop.login1.halt-multiple-sessions";
|
||||
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
|
||||
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();
|
||||
}
|
||||
|
||||
m->shutdown_dry_run = dry_run;
|
||||
|
||||
if (m->nologin_timeout_source) {
|
||||
r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
|
||||
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);
|
||||
}
|
||||
|
||||
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(
|
||||
Manager *m,
|
||||
sd_bus_message *message,
|
||||
@ -2260,6 +2283,19 @@ static int method_can_reboot(sd_bus_message *message, void *userdata, sd_bus_err
|
||||
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) {
|
||||
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("PowerOff", "b", NULL, method_poweroff, 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("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("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("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("CanHibernate", NULL, "s", method_can_hibernate, 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_member="Reboot"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.login1"
|
||||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="Halt"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.login1"
|
||||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="Suspend"/>
|
||||
@ -152,6 +156,10 @@
|
||||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="CanReboot"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.login1"
|
||||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="CanHalt"/>
|
||||
|
||||
<allow send_destination="org.freedesktop.login1"
|
||||
send_interface="org.freedesktop.login1.Manager"
|
||||
send_member="CanSuspend"/>
|
||||
|
@ -218,6 +218,39 @@
|
||||
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
|
||||
</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">
|
||||
<_description>Suspend the system</_description>
|
||||
<_message>Authentication is required for suspending the system.</_message>
|
||||
|
@ -3267,14 +3267,19 @@ static int logind_reboot(enum action a) {
|
||||
|
||||
switch (a) {
|
||||
|
||||
case ACTION_POWEROFF:
|
||||
method = "PowerOff";
|
||||
description = "power off system";
|
||||
break;
|
||||
|
||||
case ACTION_REBOOT:
|
||||
method = "Reboot";
|
||||
description = "reboot system";
|
||||
break;
|
||||
|
||||
case ACTION_POWEROFF:
|
||||
method = "PowerOff";
|
||||
description = "power off system";
|
||||
case ACTION_HALT:
|
||||
method = "Halt";
|
||||
description = "halt system";
|
||||
break;
|
||||
|
||||
case ACTION_SUSPEND:
|
||||
@ -3568,6 +3573,7 @@ static int start_special(int argc, char *argv[], void *userdata) {
|
||||
if (IN_SET(a,
|
||||
ACTION_POWEROFF,
|
||||
ACTION_REBOOT,
|
||||
ACTION_HALT,
|
||||
ACTION_SUSPEND,
|
||||
ACTION_HIBERNATE,
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
@ -8503,7 +8517,7 @@ static int halt_main(void) {
|
||||
/* Try logind if we are a normal user and no special
|
||||
* mode applies. Maybe PolicyKit allows us to shutdown
|
||||
* 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);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user