From: Morgan Date: Sun, 7 Dec 2025 00:48:49 +0000 (+0900) Subject: logind: fix initial button state is not fetched when device is registered late (... X-Git-Tag: v259-rc3~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=97887d09a82f82f9afd20f4ed32c725e48f0efca;p=thirdparty%2Fsystemd.git logind: fix initial button state is not fetched when device is registered late (#39978) If buttons that are not initialized from manager_startup() due to still being processed by udev, the initial state is not checked. (commit 405be62f05d76f1845f347737b5972158c79dd3e) This caused a problem which initial "close" state being not recognized if lid switch of some system getting initialized later. --- diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 1d88ec96613..4962aa03087 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -244,11 +244,14 @@ int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret) { int manager_add_button(Manager *m, const char *name, Button **ret_button) { Button *b; + bool is_new; assert(m); assert(name); b = hashmap_get(m->buttons, name); + is_new = !b; + if (!b) { b = button_new(m, name); if (!b) @@ -258,7 +261,7 @@ int manager_add_button(Manager *m, const char *name, Button **ret_button) { if (ret_button) *ret_button = b; - return 0; + return is_new; } int manager_process_seat_device(Manager *m, sd_device *d) { @@ -328,7 +331,7 @@ int manager_process_seat_device(Manager *m, sd_device *d) { return 0; } -int manager_process_button_device(Manager *m, sd_device *d) { +int manager_process_button_device(Manager *m, sd_device *d, Button **ret_button) { const char *sysname; Button *b; int r; @@ -340,28 +343,39 @@ int manager_process_button_device(Manager *m, sd_device *d) { return r; if (device_for_action(d, SD_DEVICE_REMOVE) || - sd_device_has_current_tag(d, "power-switch") <= 0) + sd_device_has_current_tag(d, "power-switch") <= 0) { - button_free(hashmap_get(m->buttons, sysname)); + b = hashmap_get(m->buttons, sysname); + goto unwatch; + } - else { - const char *sn; + r = manager_add_button(m, sysname, &b); + if (r < 0) + return r; + bool is_new = r > 0; - r = manager_add_button(m, sysname, &b); - if (r < 0) - return r; + const char *sn; + r = device_get_seat(d, &sn); + if (r < 0) + return r; - r = device_get_seat(d, &sn); - if (r < 0) - return r; + button_set_seat(b, sn); - button_set_seat(b, sn); + r = button_open(b); + if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error + * opening the device?) let's close the button again. */ + goto unwatch; - r = button_open(b); - if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error - * opening the device?) let's close the button again. */ - button_free(b); - } + if (ret_button) + *ret_button = b; + + return is_new; + +unwatch: + button_free(b); + + if (ret_button) + *ret_button = NULL; return 0; } diff --git a/src/login/logind.c b/src/login/logind.c index 5cdfc2a00dc..65bc854f4ed 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -236,7 +236,7 @@ static int manager_enumerate_buttons(Manager *m) { FOREACH_DEVICE(e, d) { if (device_is_processed(d) <= 0) continue; - RET_GATHER(r, manager_process_button_device(m, d)); + RET_GATHER(r, manager_process_button_device(m, d, /* ret_button= */ NULL)); } return r; @@ -739,10 +739,13 @@ static int manager_dispatch_vcsa_udev(sd_device_monitor *monitor, sd_device *dev static int manager_dispatch_button_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) { Manager *m = ASSERT_PTR(userdata); + Button *b; assert(device); - manager_process_button_device(m, device); + if (manager_process_button_device(m, device, &b) > 0) + (void) button_check_switches(b); + return 0; } diff --git a/src/login/logind.h b/src/login/logind.h index 332a59f6da6..4e3c15de521 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -153,7 +153,7 @@ int manager_add_user_by_uid(Manager *m, uid_t uid, User **ret_user); int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret_inhibitor); int manager_process_seat_device(Manager *m, sd_device *d); -int manager_process_button_device(Manager *m, sd_device *d); +int manager_process_button_device(Manager *m, sd_device *d, Button **ret_button); int manager_spawn_autovt(Manager *m, unsigned vtnr);