From: Yu Watanabe Date: Thu, 29 May 2025 01:22:21 +0000 (+0900) Subject: login: add device monitor instance to receive events for devices with uaccess tag X-Git-Tag: v258-rc1~449^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=392b9ab6472f279c13f0100ad77f0365284aa8b2;p=thirdparty%2Fsystemd.git login: add device monitor instance to receive events for devices with uaccess tag With c960ca2be1cfd183675df581f049a0c022c1c802, logind triggers uevents for devices with uaccess tag, and waits for the events being processed by udevd. However, logind received not all triggered events, and might lose some events. That causes session and user state file not updated, and many desktop environment application handled the session and user were inactive. This introduces one more device monitor instance which monitor events for devices with 'uaccess' tag. Hence, all triggered events will be recieved by logind, and session and user state file will be updated. Follow-up for c960ca2be1cfd183675df581f049a0c022c1c802. Fixes #37579. --- diff --git a/src/login/logind.c b/src/login/logind.c index 65c8d9913d1..93a1b66c3c4 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 d7b5b248541..6a46374e8ac 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;