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().
This commit is contained in:
Daan De Meyer
2025-07-03 11:22:34 +02:00
committed by DaanDeMeyer
parent 0470754f9d
commit ce06fad9c5
3 changed files with 23 additions and 15 deletions
+12 -6
View File
@@ -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;
+10 -8
View File
@@ -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,
+1 -1
View File
@@ -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);