Skip to content

Commit

Permalink
login: make hold-off timeout configurable
Browse files Browse the repository at this point in the history
This introduces 'HoldoffTimeoutSec' to logind.conf to make
IGNORE_LID_SWITCH_{SUSPEND,STARTUP}_USEC configurable.

Background: If an external monitor is connected, or if the system is
docked, we want to ignore LID events. This is required to support setups
where a laptop is used with external peripherals while the LID is closed.
However, this requires us to probe all hot-plugged devices before reacting
to LID events. But with modern buses like USB, the standards do not impose
any timeout on the slots, so we have no chance to know whether a given
slot is used or not. Hence, after resume and startup, we have to wait a
fixed timeout to give the kernel a chance to probe devices. Our timeout
has always been generous enough to support even the slowest devices.
However, a lot of people didn't use these features and wanted to disable
the hold-off timer. Now we provide a knob to do that.
  • Loading branch information
David Herrmann committed Mar 6, 2015
1 parent 9638ee9 commit 9d10cbe
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 5 deletions.
15 changes: 15 additions & 0 deletions man/logind.conf.xml
Expand Up @@ -250,6 +250,21 @@
sleep keys do. </para></listitem>
</varlistentry>

<varlistentry>
<term><varname>HoldoffTimeoutSec=</varname></term>

<listitem><para>Specifies the timeout after system startup or
system resume in which systemd will hold off on reacting to
LID events. This is required for the system to properly
detect any hotplugged devices so systemd can ignore LID events
if external monitors, or docks, are connected. If set to 0,
systemd will always react immediately, possibly before the
kernel fully probed all hotplugged devices. This is safe, as
long as you do not care for systemd to account for devices
that have been plugged or unplugged while the system was off.
Defaults to 30s.</para></listitem>
</varlistentry>

<varlistentry>
<term><varname>RuntimeDirectorySize=</varname></term>

Expand Down
3 changes: 2 additions & 1 deletion src/login/logind-dbus.c
Expand Up @@ -1448,7 +1448,7 @@ static int execute_shutdown_or_sleep(
m->action_what = w;

/* Make sure the lid switch is ignored for a while */
manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + IGNORE_LID_SWITCH_SUSPEND_USEC);
manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);

return 0;
}
Expand Down Expand Up @@ -1979,6 +1979,7 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitch", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleLidSwitchDocked", "s", property_get_handle_action, offsetof(Manager, handle_lid_switch_docked), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HoldoffTimeoutUSec", "t", NULL, offsetof(Manager, holdoff_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IdleAction", "s", property_get_handle_action, offsetof(Manager, idle_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IdleActionUSec", "t", NULL, offsetof(Manager, idle_action_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PreparingForShutdown", "b", property_get_preparing, 0, 0),
Expand Down
1 change: 1 addition & 0 deletions src/login/logind-gperf.gperf
Expand Up @@ -29,6 +29,7 @@ Login.PowerKeyIgnoreInhibited, config_parse_bool, 0, offsetof(Manag
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.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)
Login.RuntimeDirectorySize, config_parse_tmpfs_size, 0, offsetof(Manager, runtime_dir_size)
Expand Down
3 changes: 2 additions & 1 deletion src/login/logind.c
Expand Up @@ -54,6 +54,7 @@ Manager *manager_new(void) {
m->handle_lid_switch = HANDLE_SUSPEND;
m->handle_lid_switch_docked = HANDLE_IGNORE;
m->lid_switch_ignore_inhibited = true;
m->holdoff_timeout_usec = 30 * USEC_PER_SEC;

m->idle_action_usec = 30 * USEC_PER_MINUTE;
m->idle_action = HANDLE_IGNORE;
Expand Down Expand Up @@ -1029,7 +1030,7 @@ int manager_startup(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to add seat0: %m");

r = manager_set_lid_switch_ignore(m, 0 + IGNORE_LID_SWITCH_STARTUP_USEC);
r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
if (r < 0)
log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");

Expand Down
1 change: 1 addition & 0 deletions src/login/logind.conf
Expand Up @@ -27,6 +27,7 @@
#SuspendKeyIgnoreInhibited=no
#HibernateKeyIgnoreInhibited=no
#LidSwitchIgnoreInhibited=yes
#HoldoffTimeoutSec=30s
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
Expand Down
4 changes: 1 addition & 3 deletions src/login/logind.h
Expand Up @@ -37,9 +37,6 @@ typedef struct Manager Manager;
#include "logind-button.h"
#include "logind-action.h"

#define IGNORE_LID_SWITCH_STARTUP_USEC (3 * USEC_PER_MINUTE)
#define IGNORE_LID_SWITCH_SUSPEND_USEC (30 * USEC_PER_SEC)

struct Manager {
sd_event *event;
sd_bus *bus;
Expand Down Expand Up @@ -120,6 +117,7 @@ struct Manager {

Hashmap *polkit_registry;

usec_t holdoff_timeout_usec;
sd_event_source *lid_switch_ignore_event_source;

size_t runtime_dir_size;
Expand Down

0 comments on commit 9d10cbe

Please sign in to comment.