diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 81b870c46f..97d11da03f 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -199,10 +199,11 @@
HandleLidSwitch=
HandleLidSwitchExternalPower=
HandleLidSwitchDocked=
+ HandleRebootKey=
Controls how logind shall handle the
- system power and sleep keys and the lid switch to trigger
- actions such as system power-off or suspend. Can be one of
+ system power, reboot and sleep keys and the lid switch to trigger
+ actions such as system power-off, reboot or suspend. Can be one of
ignore,
poweroff,
reboot,
@@ -219,7 +220,8 @@
in the respective event. Only input devices with the
power-switch udev tag will be watched for
key/lid switch events. HandlePowerKey=
- defaults to poweroff.
+ defaults to poweroff, HandleRebootKey=
+ defaults to reboot.
HandleSuspendKey= and
HandleLidSwitch= default to
suspend.
@@ -240,7 +242,8 @@
A different application may disable logind's handling of system power and
sleep keys and the lid switch by taking a low-level inhibitor lock
(handle-power-key, handle-suspend-key,
- handle-hibernate-key, handle-lid-switch).
+ handle-hibernate-key, handle-lid-switch,
+ handle-reboot-switch).
This is most commonly used by graphical desktop environments
to take over suspend and hibernation handling, and to use their own configuration
mechanisms. If a low-level inhibitor lock is taken, logind will not take any
@@ -253,20 +256,23 @@
SuspendKeyIgnoreInhibited=
HibernateKeyIgnoreInhibited=
LidSwitchIgnoreInhibited=
+ RebootKeyIgnoreInhibited=
Controls whether actions that systemd-logind
- takes when the power and sleep keys and the lid switch are triggered are subject
- to high-level inhibitor locks ("shutdown", "sleep", "idle"). Low level inhibitor
+ takes when the power, reboot and sleep keys and the lid switch are triggered are subject
+ to high-level inhibitor locks ("shutdown", "reboot", "sleep", "idle"). Low level inhibitor
locks (handle-power-key, handle-suspend-key,
- handle-hibernate-key, handle-lid-switch),
+ handle-hibernate-key, handle-lid-switch,
+ handle-reboot-key),
are always honored, irrespective of this setting.
These settings take boolean arguments. If no, the
inhibitor locks taken by applications are respected. If yes,
- "shutdown", "sleep", and "idle" inhibitor locks are ignored.
+ "shutdown", "reboot" "sleep", and "idle" inhibitor locks are ignored.
PowerKeyIgnoreInhibited=,
- SuspendKeyIgnoreInhibited=, and
- HibernateKeyIgnoreInhibited= default to no.
+ SuspendKeyIgnoreInhibited=,
+ HibernateKeyIgnoreInhibited= and
+ RebootKeyIgnoreInhibited= default to no.
LidSwitchIgnoreInhibited= defaults to yes.
This means that when systemd-logind is handling events by
itself (no low level inhibitor locks are taken by another application), the lid
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index 9ec235a170..096cf70c9a 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -14,7 +14,7 @@
#include "string-util.h"
#include "util.h"
-#define CONST_MAX4(a, b, c, d) CONST_MAX(CONST_MAX(a, b), CONST_MAX(c, d))
+#define CONST_MAX5(a, b, c, d, e) CONST_MAX(CONST_MAX(a, b), CONST_MAX(CONST_MAX(c, d), e))
#define ULONG_BITS (sizeof(unsigned long)*8)
@@ -158,7 +158,20 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
break;
- /* The kernel is a bit confused here:
+ /* The kernel naming is a bit confusing here:
+ KEY_RESTART was probably introduced for media playback purposes, but
+ is now being predominantly used to indicate device reboot.
+ */
+
+ case KEY_RESTART:
+ log_struct(LOG_INFO,
+ LOG_MESSAGE("Reboot key pressed."),
+ "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR);
+
+ manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true);
+ break;
+
+ /* The kernel naming is a bit confusing here:
KEY_SLEEP = suspend-to-ram, which everybody else calls "suspend"
KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate"
@@ -231,7 +244,7 @@ static int button_suitable(int fd) {
return -errno;
if (bitset_get(types, EV_KEY)) {
- unsigned long keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1];
+ unsigned long keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1];
if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof keys), keys) < 0)
return -errno;
@@ -239,7 +252,8 @@ static int button_suitable(int fd) {
if (bitset_get(keys, KEY_POWER) ||
bitset_get(keys, KEY_POWER2) ||
bitset_get(keys, KEY_SLEEP) ||
- bitset_get(keys, KEY_SUSPEND))
+ bitset_get(keys, KEY_SUSPEND) ||
+ bitset_get(keys, KEY_RESTART))
return true;
}
@@ -260,7 +274,7 @@ static int button_suitable(int fd) {
static int button_set_mask(const char *name, int fd) {
unsigned long
types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1] = {},
- keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1] = {},
+ keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1] = {},
switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
struct input_mask mask;
@@ -285,6 +299,7 @@ static int button_set_mask(const char *name, int fd) {
bitset_put(keys, KEY_POWER2);
bitset_put(keys, KEY_SLEEP);
bitset_put(keys, KEY_SUSPEND);
+ bitset_put(keys, KEY_RESTART);
mask = (struct input_mask) {
.type = EV_KEY,
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 3ea6f18aa8..a2b9738fc4 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -43,10 +43,12 @@ void manager_reset_config(Manager *m) {
m->handle_lid_switch = HANDLE_SUSPEND;
m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID;
m->handle_lid_switch_docked = HANDLE_IGNORE;
+ m->handle_reboot_key = HANDLE_REBOOT;
m->power_key_ignore_inhibited = false;
m->suspend_key_ignore_inhibited = false;
m->hibernate_key_ignore_inhibited = false;
m->lid_switch_ignore_inhibited = true;
+ m->reboot_key_ignore_inhibited = false;
m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
@@ -675,6 +677,8 @@ bool manager_all_buttons_ignored(Manager *m) {
return false;
if (m->handle_lid_switch_docked != HANDLE_IGNORE)
return false;
+ if (m->handle_reboot_key != HANDLE_IGNORE)
+ return false;
return true;
}
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 71156e610c..50fb5b8a85 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -3240,6 +3240,7 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
+ w == INHIBIT_HANDLE_REBOOT_KEY ? "org.freedesktop.login1.inhibit-handle-reboot-key" :
w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
"org.freedesktop.login1.inhibit-handle-lid-switch",
NULL,
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
index 73d96ff436..2c152d2ce6 100644
--- a/src/login/logind-gperf.gperf
+++ b/src/login/logind-gperf.gperf
@@ -30,10 +30,12 @@ Login.HandleHibernateKey, config_parse_handle_action, 0, offse
Login.HandleLidSwitch, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch)
Login.HandleLidSwitchExternalPower, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_ep)
Login.HandleLidSwitchDocked, config_parse_handle_action, 0, offsetof(Manager, handle_lid_switch_docked)
+Login.HandleRebootKey, config_parse_handle_action, 0, offsetof(Manager, handle_reboot_key)
Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, power_key_ignore_inhibited)
Login.SuspendKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, suspend_key_ignore_inhibited)
Login.HibernateKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, hibernate_key_ignore_inhibited)
Login.LidSwitchIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, lid_switch_ignore_inhibited)
+Login.RebootKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manager, reboot_key_ignore_inhibited)
Login.HoldoffTimeoutSec, config_parse_sec, 0, offsetof(Manager, holdoff_timeout_usec)
Login.IdleAction, config_parse_handle_action, 0, offsetof(Manager, idle_action)
Login.IdleActionSec, config_parse_sec, 0, offsetof(Manager, idle_action_usec)
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index 7a6fba4d9b..14df9297ba 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -452,7 +452,15 @@ bool manager_is_inhibited(
}
const char *inhibit_what_to_string(InhibitWhat w) {
- static thread_local char buffer[97];
+ static thread_local char buffer[STRLEN(
+ "shutdown:"
+ "sleep:"
+ "idle:"
+ "handle-power-key:"
+ "handle-suspend-key:"
+ "handle-hibernate-key:"
+ "handle-lid-switch:"
+ "handle-reboot-key")+1];
char *p;
if (w < 0 || w >= _INHIBIT_WHAT_MAX)
@@ -473,6 +481,8 @@ const char *inhibit_what_to_string(InhibitWhat w) {
p = stpcpy(p, "handle-hibernate-key:");
if (w & INHIBIT_HANDLE_LID_SWITCH)
p = stpcpy(p, "handle-lid-switch:");
+ if (w & INHIBIT_HANDLE_REBOOT_KEY)
+ p = stpcpy(p, "handle-reboot-key:");
if (p > buffer)
*(p-1) = 0;
@@ -512,6 +522,8 @@ int inhibit_what_from_string(const char *s) {
what |= INHIBIT_HANDLE_HIBERNATE_KEY;
else if (streq(word, "handle-lid-switch"))
what |= INHIBIT_HANDLE_LID_SWITCH;
+ else if (l == 17 && strneq(word, "handle-reboot-key", l))
+ what |= INHIBIT_HANDLE_REBOOT_KEY;
else
return _INHIBIT_WHAT_INVALID;
}
diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h
index 7eaecee0b4..e5d4426191 100644
--- a/src/login/logind-inhibit.h
+++ b/src/login/logind-inhibit.h
@@ -11,7 +11,8 @@ typedef enum InhibitWhat {
INHIBIT_HANDLE_SUSPEND_KEY = 1 << 4,
INHIBIT_HANDLE_HIBERNATE_KEY = 1 << 5,
INHIBIT_HANDLE_LID_SWITCH = 1 << 6,
- _INHIBIT_WHAT_MAX = 1 << 7,
+ INHIBIT_HANDLE_REBOOT_KEY = 1 << 7,
+ _INHIBIT_WHAT_MAX = 1 << 8,
_INHIBIT_WHAT_INVALID = -1
} InhibitWhat;
diff --git a/src/login/logind.conf.in b/src/login/logind.conf.in
index ee698f8cf7..8b220267f3 100644
--- a/src/login/logind.conf.in
+++ b/src/login/logind.conf.in
@@ -25,10 +25,12 @@
#HandleLidSwitch=suspend
#HandleLidSwitchExternalPower=suspend
#HandleLidSwitchDocked=ignore
+#HandleRebootKey=reboot
#PowerKeyIgnoreInhibited=no
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
+#RebootKeyIgnoreInhibited=no
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
diff --git a/src/login/logind.h b/src/login/logind.h
index 272fcfecd4..82d319a9a2 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -107,11 +107,13 @@ struct Manager {
HandleAction handle_lid_switch;
HandleAction handle_lid_switch_ep;
HandleAction handle_lid_switch_docked;
+ HandleAction handle_reboot_key;
bool power_key_ignore_inhibited;
bool suspend_key_ignore_inhibited;
bool hibernate_key_ignore_inhibited;
bool lid_switch_ignore_inhibited;
+ bool reboot_key_ignore_inhibited;
bool remove_ipc;
diff --git a/src/login/org.freedesktop.login1.policy b/src/login/org.freedesktop.login1.policy
index 1b6d85e5f9..1d269c1070 100644
--- a/src/login/org.freedesktop.login1.policy
+++ b/src/login/org.freedesktop.login1.policy
@@ -113,6 +113,17 @@
+
+ Allow applications to inhibit system handling of the reboot key
+ Authentication is required for an application to inhibit system handling of the reboot key.
+
+ no
+ yes
+ yes
+
+ org.freedesktop.login1.inhibit-handle-suspend-key org.freedesktop.login1.inhibit-handle-hibernate-key org.freedesktop.login1.inhibit-handle-lid-switch
+
+
Allow non-logged-in user to run programs
Explicit request is required to run programs as a non-logged-in user.
diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h
index a4e9680dc1..05f00ed577 100644
--- a/src/systemd/sd-messages.h
+++ b/src/systemd/sd-messages.h
@@ -140,6 +140,8 @@ _SD_BEGIN_DECLARATIONS;
#define SD_MESSAGE_SYSTEM_UNDOCKED_STR SD_ID128_MAKE_STR(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53)
#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
#define SD_MESSAGE_POWER_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71)
+#define SD_MESSAGE_REBOOT_KEY SD_ID128_MAKE(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0)
+#define SD_MESSAGE_REBOOT_KEY_STR SD_ID128_MAKE_STR(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0)
#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_SUSPEND_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)