login: receive synthetic events for devices with 'uaccess' tag (#37654)

Fixes #37579.
This commit is contained in:
Luca Boccassi
2025-05-29 15:11:14 +01:00
committed by GitHub
3 changed files with 61 additions and 2 deletions
+7 -1
View File
@@ -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;
+49
View File
@@ -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);
+5 -1
View File
@@ -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;