From ce06fad9c54fca5f05521d6393f15eebfcffa772 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 30 Jun 2025 13:06:46 +0200 Subject: [PATCH] udev: Fix initializing varlink server from listen fd manager_listen_fds() instructs sd_listen_fds_with_names() to unset the environment which means that when sd_varlink_server_listen_auto() is called from manager_start_varlink_server(), when it eventually calls sd_listen_fds_with_names() it will return zero because the environment has already been unset in manager_listen_fds(). Fix the issue by not using sd_varlink_server_listen_auto() but instead keeping track of the varlink socket in manager_listen_fds() and returning it and passing it to manager_start_varlink_server(). --- src/udev/udev-manager.c | 18 ++++++++++++------ src/udev/udev-varlink.c | 18 ++++++++++-------- src/udev/udev-varlink.h | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index 280626da9e7..34032184c6c 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -1405,11 +1405,13 @@ static int manager_setup_event(Manager *manager) { return 0; } -static int manager_listen_fds(Manager *manager) { +static int manager_listen_fds(Manager *manager, int *ret_varlink_fd) { _cleanup_strv_free_ char **names = NULL; + int varlink_fd = -EBADF; int r; assert(manager); + assert(ret_varlink_fd); int n = sd_listen_fds_with_names(/* unset_environment = */ true, &names); if (n < 0) @@ -1418,9 +1420,10 @@ static int manager_listen_fds(Manager *manager) { for (int i = 0; i < n; i++) { int fd = SD_LISTEN_FDS_START + i; - if (streq(names[i], "varlink")) - r = 0; /* The fd will be handled by sd_varlink_server_listen_auto(). */ - else if (streq(names[i], "systemd-udevd-control.socket")) + if (streq(names[i], "varlink")) { + varlink_fd = fd; + r = 0; + } else if (streq(names[i], "systemd-udevd-control.socket")) r = manager_init_ctrl(manager, fd); else if (streq(names[i], "systemd-udevd-kernel.socket")) r = manager_init_device_monitor(manager, fd); @@ -1437,10 +1440,13 @@ static int manager_listen_fds(Manager *manager) { close_and_notify_warn(fd, names[i]); } + *ret_varlink_fd = varlink_fd; + return 0; } int manager_main(Manager *manager) { + _cleanup_close_ int varlink_fd = -EBADF; int r; assert(manager); @@ -1458,7 +1464,7 @@ int manager_main(Manager *manager) { if (r < 0) return r; - r = manager_listen_fds(manager); + r = manager_listen_fds(manager, &varlink_fd); if (r < 0) return r; @@ -1466,7 +1472,7 @@ int manager_main(Manager *manager) { if (r < 0) return r; - r = manager_start_varlink_server(manager); + r = manager_start_varlink_server(manager, TAKE_FD(varlink_fd)); if (r < 0) return r; diff --git a/src/udev/udev-varlink.c b/src/udev/udev-varlink.c index 5228d3512c9..9a887d9c7f2 100644 --- a/src/udev/udev-varlink.c +++ b/src/udev/udev-varlink.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "fd-util.h" #include "json-util.h" #include "log.h" #include "string-util.h" @@ -165,8 +166,9 @@ static int vl_method_exit(sd_varlink *link, sd_json_variant *parameters, sd_varl return sd_varlink_reply(link, NULL); } -int manager_start_varlink_server(Manager *manager) { +int manager_start_varlink_server(Manager *manager, int fd) { _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *v = NULL; + _cleanup_close_ int fd_close = fd; int r; assert(manager); @@ -183,14 +185,14 @@ int manager_start_varlink_server(Manager *manager) { if (r < 0) return log_error_errno(r, "Failed to attach Varlink connection to event loop: %m"); - r = sd_varlink_server_listen_auto(v); - if (r < 0) - return log_error_errno(r, "Failed to bind to passed Varlink socket: %m"); - if (r == 0) { + if (fd < 0) r = sd_varlink_server_listen_address(v, UDEV_VARLINK_ADDRESS, 0600); - if (r < 0) - return log_error_errno(r, "Failed to bind to Varlink socket: %m"); - } + else + r = sd_varlink_server_listen_fd(v, fd); + if (r < 0) + return log_error_errno(r, "Failed to bind to Varlink socket: %m"); + + TAKE_FD(fd_close); r = sd_varlink_server_add_interface_many( v, diff --git a/src/udev/udev-varlink.h b/src/udev/udev-varlink.h index 080f7c95a75..fb14ac711dd 100644 --- a/src/udev/udev-varlink.h +++ b/src/udev/udev-varlink.h @@ -3,5 +3,5 @@ #include "udev-forward.h" -int manager_start_varlink_server(Manager *manager); +int manager_start_varlink_server(Manager *manager, int fd); int udev_varlink_connect(sd_varlink **ret, usec_t timeout); -- 2.47.3