chiark / gitweb /
login: make hold-off timeout configurable
authorDavid Herrmann <dh.herrmann@gmail.com>
Fri, 6 Mar 2015 13:37:09 +0000 (14:37 +0100)
committerDavid Herrmann <dh.herrmann@gmail.com>
Fri, 6 Mar 2015 13:37:09 +0000 (14:37 +0100)
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.

man/logind.conf.xml
src/login/logind-dbus.c
src/login/logind-gperf.gperf
src/login/logind.c
src/login/logind.conf
src/login/logind.h

index ca2b18783c61f55224354cbfe26900900c09f054..6cfdee83adfe9eaa272e30237e6b97b721910d7d 100644 (file)
         sleep keys do. </para></listitem>
       </varlistentry>
 
         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>
 
       <varlistentry>
         <term><varname>RuntimeDirectorySize=</varname></term>
 
index 3322d66aa9e889ad0f41d50cc437609b3e6fdf4b..b28d28093934877feb38c602b0306cbf62be813c 100644 (file)
@@ -1448,7 +1448,7 @@ static int execute_shutdown_or_sleep(
         m->action_what = w;
 
         /* Make sure the lid switch is ignored for a while */
         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;
 }
 
         return 0;
 }
@@ -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("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),
         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),
index 62460673b9bd4e78eb5098f899f26c85af766699..9218d098e024aa9f87b5fa1750247fd5ea229209 100644 (file)
@@ -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.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)
 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)
index 08a7cbc08a2afe7f18a0985aff7fde31fe96f187..e7880743a0657566c5ceea18cbb56c31ee627ff3 100644 (file)
@@ -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->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;
 
         m->idle_action_usec = 30 * USEC_PER_MINUTE;
         m->idle_action = HANDLE_IGNORE;
@@ -1029,7 +1030,7 @@ int manager_startup(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to add seat0: %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");
 
         if (r < 0)
                 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
 
index 834c4c2ebf988c09b43a0831e7bc659900ccb5fe..6df6f04c775b125b0e9f02198a842e0374c3b5d9 100644 (file)
@@ -27,6 +27,7 @@
 #SuspendKeyIgnoreInhibited=no
 #HibernateKeyIgnoreInhibited=no
 #LidSwitchIgnoreInhibited=yes
 #SuspendKeyIgnoreInhibited=no
 #HibernateKeyIgnoreInhibited=no
 #LidSwitchIgnoreInhibited=yes
+#HoldoffTimeoutSec=30s
 #IdleAction=ignore
 #IdleActionSec=30min
 #RuntimeDirectorySize=10%
 #IdleAction=ignore
 #IdleActionSec=30min
 #RuntimeDirectorySize=10%
index 48e647ae821ad0e9627012687d7fe5dad9afc923..4781688f0a0430702d53a9a6a4d0ca279befa680 100644 (file)
@@ -37,9 +37,6 @@ typedef struct Manager Manager;
 #include "logind-button.h"
 #include "logind-action.h"
 
 #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;
 struct Manager {
         sd_event *event;
         sd_bus *bus;
@@ -120,6 +117,7 @@ struct Manager {
 
         Hashmap *polkit_registry;
 
 
         Hashmap *polkit_registry;
 
+        usec_t holdoff_timeout_usec;
         sd_event_source *lid_switch_ignore_event_source;
 
         size_t runtime_dir_size;
         sd_event_source *lid_switch_ignore_event_source;
 
         size_t runtime_dir_size;