diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index cfc3dd1bf1..db476af251 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -30,6 +30,7 @@ #include "string-util.h" #include "terminal-util.h" #include "tmpfile-util.h" +#include "udev-util.h" #include "user-record.h" int seat_new(Manager *m, const char *id, Seat **ret) { @@ -205,8 +206,10 @@ int seat_preallocate_vts(Seat *s) { static void seat_triggered_uevents_done(Seat *s) { assert(s); - if (!set_isempty(s->uevents)) + if (!set_isempty(s->uevents)) { + log_debug("%s: waiting for %u events being processed by udevd.", s->id, set_size(s->uevents)); return; + } Session *session = s->active; @@ -244,6 +247,7 @@ int manager_process_device_triggered_by_seat(Manager *m, sd_device *dev) { if (!s) return 0; + log_device_uevent(dev, "Received event processed by udevd"); free(ASSERT_PTR(set_remove(s->uevents, &uuid))); seat_triggered_uevents_done(s); @@ -306,6 +310,8 @@ static int seat_trigger_devices(Seat *s) { continue; } + log_device_debug(d, "Triggered synthetic event (ACTION=change, UUID=%s).", SD_ID128_TO_UUID_STRING(uuid)); + _cleanup_free_ sd_id128_t *copy = newdup(sd_id128_t, &uuid, 1); if (!copy) return -ENOMEM; diff --git a/src/login/logind.c b/src/login/logind.c index 65c8d9913d..93a1b66c3c 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -152,6 +152,7 @@ static Manager* manager_free(Manager *m) { sd_device_monitor_unref(m->device_monitor); sd_device_monitor_unref(m->device_vcsa_monitor); sd_device_monitor_unref(m->device_button_monitor); + sd_device_monitor_unref(m->device_uaccess_monitor); if (m->unlink_nologin) (void) unlink_or_warn("/run/nologin"); @@ -655,6 +656,35 @@ static int manager_dispatch_device_udev(sd_device_monitor *monitor, sd_device *d return 0; } +static int manager_dispatch_uaccess_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) { + Manager *m = ASSERT_PTR(userdata); + int r; + + assert(device); + + /* If the device currently has "master-of-seat" tag, then it has been or will be processed by + * manager_dispatch_seat_udev(). */ + r = sd_device_has_current_tag(device, "master-of-seat"); + if (r < 0) + log_device_warning_errno(device, r, "Failed to check if the device currently has master-of-seat tag, ignoring: %m"); + if (r != 0) + return 0; + + /* If the device is in input, graphics, or drm, then the event has been or will be processed by + * manager_dispatch_device_udev(). */ + r = device_in_subsystem(device, "input", "graphics", "drm"); + if (r < 0) + log_device_warning_errno(device, r, "Failed to check device subsystem, ignoring: %m"); + if (r != 0) + return 0; + + r = manager_process_device_triggered_by_seat(m, device); + if (r < 0) + log_device_warning_errno(device, r, "Failed to process seat device event triggered by us, ignoring: %m"); + + return 0; +} + static int manager_dispatch_vcsa_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) { Manager *m = ASSERT_PTR(userdata); int r; @@ -893,6 +923,7 @@ static int manager_connect_udev(Manager *m) { assert(m); assert(!m->device_seat_monitor); assert(!m->device_monitor); + assert(!m->device_uaccess_monitor); assert(!m->device_vcsa_monitor); assert(!m->device_button_monitor); @@ -934,6 +965,24 @@ static int manager_connect_udev(Manager *m) { (void) sd_device_monitor_set_description(m->device_monitor, "input,graphics,drm"); + r = sd_device_monitor_new(&m->device_uaccess_monitor); + if (r < 0) + return r; + + r = sd_device_monitor_filter_add_match_tag(m->device_uaccess_monitor, "uaccess"); + if (r < 0) + return r; + + r = sd_device_monitor_attach_event(m->device_uaccess_monitor, m->event); + if (r < 0) + return r; + + r = sd_device_monitor_start(m->device_uaccess_monitor, manager_dispatch_uaccess_udev, m); + if (r < 0) + return r; + + (void) sd_device_monitor_set_description(m->device_uaccess_monitor, "uaccess"); + /* Don't watch keys if nobody cares */ if (!manager_all_buttons_ignored(m)) { r = sd_device_monitor_new(&m->device_button_monitor); diff --git a/src/login/logind.h b/src/login/logind.h index d7b5b24854..6a46374e8a 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -25,7 +25,11 @@ typedef struct Manager { LIST_HEAD(Session, session_gc_queue); LIST_HEAD(User, user_gc_queue); - sd_device_monitor *device_seat_monitor, *device_monitor, *device_vcsa_monitor, *device_button_monitor; + sd_device_monitor *device_seat_monitor; + sd_device_monitor *device_monitor; + sd_device_monitor *device_vcsa_monitor; + sd_device_monitor *device_button_monitor; + sd_device_monitor *device_uaccess_monitor; sd_event_source *console_active_event_source;