login: receive synthetic events for devices with 'uaccess' tag (#37654)
Fixes #37579.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user