Merge pull request #6944 from poettering/suspend-fix

systemctl reboot/suspend tweaks
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2017-10-05 11:26:44 +02:00 committed by GitHub
commit c9905d4dd2
6 changed files with 227 additions and 118 deletions

16
NEWS
View File

@ -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:

View File

@ -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>

View File

@ -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),

View File

@ -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"/>

View File

@ -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>

View File

@ -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;