From: Yu Watanabe Date: Sun, 22 Feb 2026 16:01:45 +0000 (+0900) Subject: udev: drop home-grown udev-ctrl socket X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17e911ffc853c54f44edd11ead8b6edab72c1217;p=thirdparty%2Fsystemd.git udev: drop home-grown udev-ctrl socket Nowadays, varlink is used to control systemd-udevd. Let's drop the legacy socket. Note, the existence of /run/udev/control socket is widely used in both our code and external projects. Also, the dependency to systemd-udevd-control.socket is widely used in many projects. Hence, we need to create a symlink to the socket file and .socket unit file. --- diff --git a/man/rules/meson.build b/man/rules/meson.build index eac4465769b..d3cb5e42929 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -1319,7 +1319,6 @@ manpages = [ ['systemd-udevd.service', '8', ['systemd-udevd', - 'systemd-udevd-control.socket', 'systemd-udevd-kernel.socket', 'systemd-udevd-varlink.socket'], ''], diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml index ab50fb65a25..f367288bbec 100644 --- a/man/systemd-udevd.service.xml +++ b/man/systemd-udevd.service.xml @@ -18,7 +18,6 @@ systemd-udevd.service - systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udevd-varlink.socket systemd-udevd @@ -27,7 +26,6 @@ systemd-udevd.service - systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udevd-varlink.socket diff --git a/man/udevadm.xml b/man/udevadm.xml index 2a9963cd140..e13ff9842be 100644 --- a/man/udevadm.xml +++ b/man/udevadm.xml @@ -713,7 +713,7 @@ Note that systemd-udevd.service contains and so as a result, this option restarts systemd-udevd. If you want to stop systemd-udevd.service, please use the following: - systemctl stop systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udevd-varlink.socket systemd-udevd.service + systemctl stop systemd-udevd-kernel.socket systemd-udevd-varlink.socket systemd-udevd.service diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index c218e015fae..4621d899ae1 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -996,7 +996,6 @@ TEST(unit_name_from_dbus_path) { test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dsetup_2ddev_2eservice", 0, "systemd-tmpfiles-setup-dev.service"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dsetup_2eservice", 0, "systemd-tmpfiles-setup.service"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudev_2dtrigger_2eservice", 0, "systemd-udev-trigger.service"); - test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudevd_2dcontrol_2esocket", 0, "systemd-udevd-control.socket"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudevd_2dkernel_2esocket", 0, "systemd-udevd-kernel.socket"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudevd_2eservice", 0, "systemd-udevd.service"); test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dupdate_2ddone_2eservice", 0, "systemd-update-done.service"); diff --git a/src/udev/meson.build b/src/udev/meson.build index 893241db0fe..15d140398b4 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -32,13 +32,11 @@ udevadm_export_sources = files( 'udev-builtin-path_id.c', 'udev-builtin-usb_id.c', 'udev-config.c', - 'udev-ctrl.c', 'udev-dump.c', 'udev-error.c', 'udev-event.c', 'udev-format.c', 'udev-manager.c', - 'udev-manager-ctrl.c', 'udev-node.c', 'udev-rules.c', 'udev-spawn.c', diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c deleted file mode 100644 index fbd0834d168..00000000000 --- a/src/udev/udev-ctrl.c +++ /dev/null @@ -1,362 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include -#include -#include - -#include "sd-event.h" - -#include "alloc-util.h" -#include "errno-util.h" -#include "fd-util.h" -#include "format-util.h" -#include "iovec-util.h" -#include "log.h" -#include "socket-util.h" -#include "strxcpyx.h" -#include "udev-ctrl.h" - -/* wire protocol magic must match */ -#define UDEV_CTRL_MAGIC 0xdead1dea - -typedef struct UdevCtrlMessageWire { - char version[16]; - unsigned magic; - UdevCtrlMessageType type; - UdevCtrlMessageValue value; -} UdevCtrlMessageWire; - -struct UdevCtrl { - unsigned n_ref; - int sock; - int sock_connect; - union sockaddr_union saddr; - socklen_t addrlen; - bool bound; - bool connected; - sd_event *event; - sd_event_source *event_source; - sd_event_source *event_source_connect; - udev_ctrl_handler_t callback; - void *userdata; -}; - -int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd) { - _cleanup_close_ int sock = -EBADF; - UdevCtrl *uctrl; - int r; - - assert(ret); - - if (fd < 0) { - sock = socket(AF_UNIX, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0); - if (sock < 0) - return log_error_errno(errno, "Failed to create socket: %m"); - } - - /* enable receiving of the sender credentials in the messages */ - r = setsockopt_int(fd >= 0 ? fd : sock, SOL_SOCKET, SO_PASSCRED, true); - if (r < 0) - log_warning_errno(r, "Failed to set SO_PASSCRED, ignoring: %m"); - - r = setsockopt_int(fd >= 0 ? fd : sock, SOL_SOCKET, SO_PASSRIGHTS, false); - if (r < 0) - log_debug_errno(r, "Failed to turn off SO_PASSRIGHTS, ignoring: %m"); - - uctrl = new(UdevCtrl, 1); - if (!uctrl) - return -ENOMEM; - - *uctrl = (UdevCtrl) { - .n_ref = 1, - .sock = fd >= 0 ? fd : TAKE_FD(sock), - .sock_connect = -EBADF, - .bound = fd >= 0, - }; - - uctrl->saddr.un = (struct sockaddr_un) { - .sun_family = AF_UNIX, - .sun_path = "/run/udev/control", - }; - - uctrl->addrlen = sockaddr_un_len(&uctrl->saddr.un); - - *ret = TAKE_PTR(uctrl); - return 0; -} - -int udev_ctrl_enable_receiving(UdevCtrl *uctrl) { - assert(uctrl); - - if (uctrl->bound) - return 0; - - (void) sockaddr_un_unlink(&uctrl->saddr.un); - if (bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen) < 0) - return log_error_errno(errno, "Failed to bind udev control socket: %m"); - - if (listen(uctrl->sock, 0) < 0) - return log_error_errno(errno, "Failed to listen udev control socket: %m"); - - uctrl->bound = true; - return 0; -} - -static void udev_ctrl_disconnect(UdevCtrl *uctrl) { - if (!uctrl) - return; - - uctrl->event_source_connect = sd_event_source_unref(uctrl->event_source_connect); - uctrl->sock_connect = safe_close(uctrl->sock_connect); -} - -static UdevCtrl *udev_ctrl_free(UdevCtrl *uctrl) { - assert(uctrl); - - udev_ctrl_disconnect(uctrl); - - sd_event_source_unref(uctrl->event_source); - safe_close(uctrl->sock); - - sd_event_unref(uctrl->event); - return mfree(uctrl); -} - -DEFINE_TRIVIAL_REF_UNREF_FUNC(UdevCtrl, udev_ctrl, udev_ctrl_free); - -int udev_ctrl_attach_event(UdevCtrl *uctrl, sd_event *event) { - int r; - - assert_return(uctrl, -EINVAL); - assert_return(!uctrl->event, -EBUSY); - - if (event) - uctrl->event = sd_event_ref(event); - else { - r = sd_event_default(&uctrl->event); - if (r < 0) - return r; - } - - return 0; -} - -sd_event_source *udev_ctrl_get_event_source(UdevCtrl *uctrl) { - assert(uctrl); - - return uctrl->event_source; -} - -static void udev_ctrl_disconnect_and_listen_again(UdevCtrl *uctrl) { - udev_ctrl_disconnect(uctrl); - udev_ctrl_unref(uctrl); - (void) sd_event_source_set_enabled(uctrl->event_source, SD_EVENT_ON); - /* We don't return NULL here because uctrl is not freed */ -} - -DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(UdevCtrl*, udev_ctrl_disconnect_and_listen_again, NULL); - -static int udev_ctrl_connection_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - _cleanup_(udev_ctrl_disconnect_and_listen_againp) UdevCtrl *uctrl = NULL; - UdevCtrlMessageWire msg_wire; - struct iovec iov = IOVEC_MAKE(&msg_wire, sizeof(UdevCtrlMessageWire)); - CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; - struct msghdr smsg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = &control, - .msg_controllen = sizeof(control), - }; - struct ucred *cred; - ssize_t size; - - assert(userdata); - - /* When UDEV_CTRL_EXIT is received, manager unref udev_ctrl object. - * To avoid the object freed, let's increment the refcount. */ - uctrl = udev_ctrl_ref(userdata); - - size = recvmsg_safe(fd, &smsg, 0); - if (ERRNO_IS_NEG_TRANSIENT(size)) - return 0; - if (size == -ECHRNG) { - log_warning_errno(size, "Got message with truncated control data (unexpected fds sent?), ignoring."); - return 0; - } - if (size == -EXFULL) { - log_warning_errno(size, "Got message with truncated payload data, ignoring."); - return 0; - } - if (size < 0) - return log_error_errno(size, "Failed to receive ctrl message: %m"); - - cmsg_close_all(&smsg); - - if (size != sizeof(msg_wire)) { - log_warning("Received message with invalid length, ignoring"); - return 0; - } - - cred = CMSG_FIND_DATA(&smsg, SOL_SOCKET, SCM_CREDENTIALS, struct ucred); - if (!cred) { - log_warning("No sender credentials received, ignoring message"); - return 0; - } - - if (cred->uid != 0) { - log_warning("Invalid sender uid "UID_FMT", ignoring message", cred->uid); - return 0; - } - - if (msg_wire.magic != UDEV_CTRL_MAGIC) { - log_warning("Message magic 0x%08x doesn't match, ignoring message", msg_wire.magic); - return 0; - } - - if (msg_wire.type == _UDEV_CTRL_END_MESSAGES) - return 0; - - if (uctrl->callback) - (void) uctrl->callback(uctrl, msg_wire.type, &msg_wire.value, uctrl->userdata); - - /* Do not disconnect and wait for next message. */ - uctrl = udev_ctrl_unref(uctrl); - return 0; -} - -static int udev_ctrl_event_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - UdevCtrl *uctrl = ASSERT_PTR(userdata); - _cleanup_close_ int sock = -EBADF; - struct ucred ucred; - int r; - - sock = accept4(fd, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK); - if (sock < 0) { - if (ERRNO_IS_ACCEPT_AGAIN(errno)) - return 0; - - return log_error_errno(errno, "Failed to accept ctrl connection: %m"); - } - - /* check peer credential of connection */ - r = getpeercred(sock, &ucred); - if (r < 0) { - log_error_errno(r, "Failed to receive credentials of ctrl connection: %m"); - return 0; - } - - if (ucred.uid > 0) { - log_error("Invalid sender uid "UID_FMT", closing connection", ucred.uid); - return 0; - } - - r = sd_event_add_io(uctrl->event, &uctrl->event_source_connect, sock, EPOLLIN, udev_ctrl_connection_event_handler, uctrl); - if (r < 0) { - log_error_errno(r, "Failed to create event source for udev control connection: %m"); - return 0; - } - - (void) sd_event_source_set_description(uctrl->event_source_connect, "udev-ctrl-connection"); - - /* Do not accept multiple connection. */ - (void) sd_event_source_set_enabled(uctrl->event_source, SD_EVENT_OFF); - - uctrl->sock_connect = TAKE_FD(sock); - return 0; -} - -int udev_ctrl_start(UdevCtrl *uctrl, udev_ctrl_handler_t callback, void *userdata) { - int r; - - assert(uctrl); - - if (!uctrl->event) { - r = udev_ctrl_attach_event(uctrl, NULL); - if (r < 0) - return r; - } - - r = udev_ctrl_enable_receiving(uctrl); - if (r < 0) - return r; - - uctrl->callback = callback; - uctrl->userdata = userdata; - - r = sd_event_add_io(uctrl->event, &uctrl->event_source, uctrl->sock, EPOLLIN, udev_ctrl_event_handler, uctrl); - if (r < 0) - return r; - - (void) sd_event_source_set_description(uctrl->event_source, "udev-ctrl"); - - return 0; -} - -int udev_ctrl_send(UdevCtrl *uctrl, UdevCtrlMessageType type, const void *data) { - UdevCtrlMessageWire ctrl_msg_wire = { - .version = "udev-" PROJECT_VERSION_STR, - .magic = UDEV_CTRL_MAGIC, - .type = type, - }; - - if (type == UDEV_CTRL_SET_ENV) { - assert(data); - strscpy(ctrl_msg_wire.value.buf, sizeof(ctrl_msg_wire.value.buf), data); - } else if (IN_SET(type, UDEV_CTRL_SET_LOG_LEVEL, UDEV_CTRL_SET_CHILDREN_MAX)) - ctrl_msg_wire.value.intval = PTR_TO_INT(data); - - if (!uctrl->connected) { - if (connect(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen) < 0) - return -errno; - uctrl->connected = true; - } - - if (send(uctrl->sock, &ctrl_msg_wire, sizeof(ctrl_msg_wire), 0) < 0) - return -errno; - - return 0; -} - -int udev_ctrl_wait(UdevCtrl *uctrl, usec_t timeout) { - _cleanup_(sd_event_source_disable_unrefp) sd_event_source *source_io = NULL, *source_timeout = NULL; - int r; - - assert(uctrl); - - if (uctrl->sock < 0) - return 0; - if (!uctrl->connected) - return 0; - - r = udev_ctrl_send(uctrl, _UDEV_CTRL_END_MESSAGES, NULL); - if (r < 0) - return r; - - if (timeout == 0) - return 0; - - if (!uctrl->event) { - r = udev_ctrl_attach_event(uctrl, NULL); - if (r < 0) - return r; - } - - r = sd_event_add_io(uctrl->event, &source_io, uctrl->sock, EPOLLIN, NULL, INT_TO_PTR(0)); - if (r < 0) - return r; - - (void) sd_event_source_set_description(source_io, "udev-ctrl-wait-io"); - - if (timeout != USEC_INFINITY) { - r = sd_event_add_time_relative( - uctrl->event, &source_timeout, CLOCK_BOOTTIME, - timeout, - 0, NULL, INT_TO_PTR(-ETIMEDOUT)); - if (r < 0) - return r; - - (void) sd_event_source_set_description(source_timeout, "udev-ctrl-wait-timeout"); - } - - return sd_event_loop(uctrl->event); -} diff --git a/src/udev/udev-ctrl.h b/src/udev/udev-ctrl.h deleted file mode 100644 index 83c66239d06..00000000000 --- a/src/udev/udev-ctrl.h +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#pragma once - -#include "udev-forward.h" - -typedef enum UdevCtrlMessageType { - _UDEV_CTRL_END_MESSAGES, - UDEV_CTRL_SET_LOG_LEVEL, - UDEV_CTRL_STOP_EXEC_QUEUE, - UDEV_CTRL_START_EXEC_QUEUE, - UDEV_CTRL_RELOAD, - UDEV_CTRL_SET_ENV, - UDEV_CTRL_SET_CHILDREN_MAX, - UDEV_CTRL_PING, - UDEV_CTRL_EXIT, -} UdevCtrlMessageType; - -typedef union UdevCtrlMessageValue { - int intval; - char buf[256]; -} UdevCtrlMessageValue; - -typedef int (*udev_ctrl_handler_t)(UdevCtrl *udev_ctrl, UdevCtrlMessageType type, - const UdevCtrlMessageValue *value, void *userdata); - -int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd); -static inline int udev_ctrl_new(UdevCtrl **ret) { - return udev_ctrl_new_from_fd(ret, -EBADF); -} - -int udev_ctrl_enable_receiving(UdevCtrl *uctrl); -DECLARE_TRIVIAL_REF_UNREF_FUNC(UdevCtrl, udev_ctrl); -int udev_ctrl_attach_event(UdevCtrl *uctrl, sd_event *event); -int udev_ctrl_start(UdevCtrl *uctrl, udev_ctrl_handler_t callback, void *userdata); -sd_event_source *udev_ctrl_get_event_source(UdevCtrl *uctrl); - -int udev_ctrl_wait(UdevCtrl *uctrl, usec_t timeout); - -int udev_ctrl_send(UdevCtrl *uctrl, UdevCtrlMessageType type, const void *data); -static inline int udev_ctrl_send_set_log_level(UdevCtrl *uctrl, int priority) { - return udev_ctrl_send(uctrl, UDEV_CTRL_SET_LOG_LEVEL, INT_TO_PTR(priority)); -} - -static inline int udev_ctrl_send_stop_exec_queue(UdevCtrl *uctrl) { - return udev_ctrl_send(uctrl, UDEV_CTRL_STOP_EXEC_QUEUE, NULL); -} - -static inline int udev_ctrl_send_start_exec_queue(UdevCtrl *uctrl) { - return udev_ctrl_send(uctrl, UDEV_CTRL_START_EXEC_QUEUE, NULL); -} - -static inline int udev_ctrl_send_reload(UdevCtrl *uctrl) { - return udev_ctrl_send(uctrl, UDEV_CTRL_RELOAD, NULL); -} - -static inline int udev_ctrl_send_set_env(UdevCtrl *uctrl, const char *key) { - return udev_ctrl_send(uctrl, UDEV_CTRL_SET_ENV, key); -} - -static inline int udev_ctrl_send_set_children_max(UdevCtrl *uctrl, int count) { - return udev_ctrl_send(uctrl, UDEV_CTRL_SET_CHILDREN_MAX, INT_TO_PTR(count)); -} - -static inline int udev_ctrl_send_ping(UdevCtrl *uctrl) { - return udev_ctrl_send(uctrl, UDEV_CTRL_PING, NULL); -} - -static inline int udev_ctrl_send_exit(UdevCtrl *uctrl) { - return udev_ctrl_send(uctrl, UDEV_CTRL_EXIT, NULL); -} - -DEFINE_TRIVIAL_CLEANUP_FUNC(UdevCtrl*, udev_ctrl_unref); diff --git a/src/udev/udev-forward.h b/src/udev/udev-forward.h index d4526ad8e54..cc322bc4c63 100644 --- a/src/udev/udev-forward.h +++ b/src/udev/udev-forward.h @@ -5,7 +5,6 @@ #include "forward.h" /* IWYU pragma: export */ -typedef struct UdevCtrl UdevCtrl; typedef struct UdevEvent UdevEvent; typedef struct Manager Manager; typedef struct Event Event; diff --git a/src/udev/udev-manager-ctrl.c b/src/udev/udev-manager-ctrl.c deleted file mode 100644 index c395993a243..00000000000 --- a/src/udev/udev-manager-ctrl.c +++ /dev/null @@ -1,134 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "sd-daemon.h" -#include "sd-event.h" - -#include "log.h" -#include "syslog-util.h" -#include "udev-ctrl.h" -#include "udev-manager.h" -#include "udev-manager-ctrl.h" - -/* receive the udevd message from userspace */ -static int on_ctrl_msg(UdevCtrl *uctrl, UdevCtrlMessageType type, const UdevCtrlMessageValue *value, void *userdata) { - Manager *manager = ASSERT_PTR(userdata); - - assert(value); - - switch (type) { - case UDEV_CTRL_SET_LOG_LEVEL: - if (!log_level_is_valid(value->intval)) { - log_debug("Received invalid udev control message (SET_LOG_LEVEL, %i), ignoring.", value->intval); - break; - } - - log_debug("Received udev control message (SET_LOG_LEVEL), setting log_level=%i", value->intval); - - manager_set_log_level(manager, value->intval); - break; - case UDEV_CTRL_STOP_EXEC_QUEUE: - log_debug("Received udev control message (STOP_EXEC_QUEUE)"); - manager->stop_exec_queue = true; - (void) manager_reset_kill_workers_timer(manager); - break; - case UDEV_CTRL_START_EXEC_QUEUE: - log_debug("Received udev control message (START_EXEC_QUEUE)"); - manager->stop_exec_queue = false; - /* It is not necessary to call event_queue_start() here, as it will be called in on_post() if necessary. */ - break; - case UDEV_CTRL_RELOAD: - log_debug("Received udev control message (RELOAD)"); - manager_reload(manager, /* force= */ true); - break; - case UDEV_CTRL_SET_ENV: - if (!udev_property_assignment_is_valid(value->buf)) { - log_debug("Received invalid udev control message(SET_ENV, %s), ignoring.", value->buf); - break; - } - - log_debug("Received udev control message(SET_ENV, %s)", value->buf); - manager_set_environment(manager, STRV_MAKE(value->buf)); - break; - case UDEV_CTRL_SET_CHILDREN_MAX: - if (value->intval < 0) { - log_debug("Received invalid udev control message (SET_MAX_CHILDREN, %i), ignoring.", value->intval); - return 0; - } - - log_debug("Received udev control message (SET_MAX_CHILDREN), setting children_max=%i", value->intval); - - manager_set_children_max(manager, value->intval); - break; - case UDEV_CTRL_PING: - log_debug("Received udev control message (PING)"); - break; - case UDEV_CTRL_EXIT: - log_debug("Received udev control message (EXIT)"); - manager_exit(manager); - break; - default: - log_debug("Received unknown udev control message, ignoring"); - } - - return 1; -} - -int manager_init_ctrl(Manager *manager, int fd) { - int r; - - assert(manager); - - /* This takes passed file descriptor on success. */ - - if (fd >= 0) { - if (manager->ctrl) - return log_warning_errno(SYNTHETIC_ERRNO(EALREADY), "Received multiple control socket (%i), ignoring.", fd); - - r = sd_is_socket(fd, AF_UNIX, SOCK_SEQPACKET, -1); - if (r < 0) - return log_warning_errno(r, "Failed to verify socket type of %i, ignoring: %m", fd); - if (r == 0) - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Received invalid control socket (%i), ignoring.", fd); - } else { - if (manager->ctrl) - return 0; - } - - r = udev_ctrl_new_from_fd(&manager->ctrl, fd); - if (r < 0) - return log_error_errno(r, "Failed to initialize udev control socket: %m"); - - return 0; -} - -int manager_start_ctrl(Manager *manager) { - int r; - - assert(manager); - assert(manager->event); - - r = manager_init_ctrl(manager, -EBADF); - if (r < 0) - return r; - - r = udev_ctrl_enable_receiving(manager->ctrl); - if (r < 0) - return log_error_errno(r, "Failed to bind udev control socket: %m"); - - r = udev_ctrl_attach_event(manager->ctrl, manager->event); - if (r < 0) - return log_error_errno(r, "Failed to attach event to udev control: %m"); - - r = udev_ctrl_start(manager->ctrl, on_ctrl_msg, manager); - if (r < 0) - return log_error_errno(r, "Failed to start udev control: %m"); - - /* This needs to be after the inotify and uevent handling, to make sure that the ping is send back - * after fully processing the pending uevents (including the synthetic ones we may create due to - * inotify events). */ - r = sd_event_source_set_priority(udev_ctrl_get_event_source(manager->ctrl), EVENT_PRIORITY_CONTROL); - if (r < 0) - return log_error_errno(r, "Failed to set IDLE event priority for udev control event source: %m"); - - return 0; -} diff --git a/src/udev/udev-manager-ctrl.h b/src/udev/udev-manager-ctrl.h deleted file mode 100644 index 270a63e861b..00000000000 --- a/src/udev/udev-manager-ctrl.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#pragma once - -#include "udev-forward.h" - -int manager_init_ctrl(Manager *manager, int fd); -int manager_start_ctrl(Manager *manager); diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index fabbdbb88c9..2c43d9ccc59 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -35,10 +35,8 @@ #include "time-util.h" #include "udev-builtin.h" #include "udev-config.h" -#include "udev-ctrl.h" #include "udev-error.h" #include "udev-manager.h" -#include "udev-manager-ctrl.h" #include "udev-rules.h" #include "udev-spawn.h" #include "udev-trace.h" @@ -166,7 +164,6 @@ Manager* manager_free(Manager *manager) { sd_device_monitor_unref(manager->monitor); - udev_ctrl_unref(manager->ctrl); sd_varlink_server_unref(manager->varlink_server); sd_event_source_unref(manager->inotify_event); @@ -255,7 +252,6 @@ void manager_exit(Manager *manager) { (void) sd_notify(/* unset_environment= */ false, NOTIFY_STOPPING_MESSAGE); /* close sources of new events and discard buffered events */ - manager->ctrl = udev_ctrl_unref(manager->ctrl); manager->varlink_server = sd_varlink_server_unref(manager->varlink_server); (void) manager_serialize_config(manager); @@ -1410,9 +1406,7 @@ static int manager_listen_fds(Manager *manager, int *ret_varlink_fd) { 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")) + } else if (streq(names[i], "systemd-udevd-kernel.socket")) r = manager_init_device_monitor(manager, fd); else if (streq(names[i], "inotify")) r = manager_init_inotify(manager, fd); @@ -1473,10 +1467,6 @@ int manager_main(Manager *manager) { if (r < 0) return r; - r = manager_start_ctrl(manager); - if (r < 0) - return r; - r = manager_start_varlink_server(manager, TAKE_FD(varlink_fd)); if (r < 0) return r; diff --git a/src/udev/udev-manager.h b/src/udev/udev-manager.h index 4e18dd54047..1b5db6e3b61 100644 --- a/src/udev/udev-manager.h +++ b/src/udev/udev-manager.h @@ -33,7 +33,6 @@ #define EVENT_PRIORITY_SIGHUP (SD_EVENT_PRIORITY_NORMAL + 1) /* Let's not interrupt the service by any user process, even that requires privileges. */ #define EVENT_PRIORITY_VARLINK (SD_EVENT_PRIORITY_NORMAL + 2) -#define EVENT_PRIORITY_CONTROL (SD_EVENT_PRIORITY_NORMAL + 2) /* The event is intended to trigger the post-event source, hence can be the lowest priority. */ #define EVENT_PRIORITY_REQUEUE_EVENT (SD_EVENT_PRIORITY_NORMAL + 3) @@ -48,7 +47,6 @@ typedef struct Manager { Hashmap *properties; sd_device_monitor *monitor; - UdevCtrl *ctrl; sd_varlink_server *varlink_server; char *worker_notify_socket_path; diff --git a/src/udev/udev-varlink.c b/src/udev/udev-varlink.c index 183265fc535..70567dc58ab 100644 --- a/src/udev/udev-varlink.c +++ b/src/udev/udev-varlink.c @@ -2,6 +2,7 @@ #include "bus-polkit.h" #include "fd-util.h" +#include "fs-util.h" #include "json-util.h" #include "log.h" #include "string-util.h" @@ -197,6 +198,14 @@ int manager_start_varlink_server(Manager *manager, int fd) { TAKE_FD(fd_close); + /* For backward compatibility. The existence of the file is used by udevadm settle, sd-device, + * libudev, and many external projects for checking if udevd is running. Note, it may be already + * created by PID1 through systemd-udevd-varlink.socket. But, we need to explicitly create it here, + * to make it created even in systemd-less systems or systemd-less initrd. */ + r = symlink_idempotent(UDEV_VARLINK_ADDRESS, "/run/udev/control", /* make_relative= */ false); + if (r < 0) + log_warning_errno(r, "Failed to create symlink /run/udev/control to "UDEV_VARLINK_ADDRESS", ignoring: %m"); + r = sd_varlink_server_add_interface_many( v, &vl_interface_io_systemd_service, diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c index cef3ec7fd56..54bf1a003b1 100644 --- a/src/udev/udevadm-control.c +++ b/src/udev/udevadm-control.c @@ -3,7 +3,6 @@ #include #include "creds-util.h" -#include "errno-util.h" #include "format-table.h" #include "help-util.h" #include "log.h" @@ -14,7 +13,6 @@ #include "strv.h" #include "syslog-util.h" #include "time-util.h" -#include "udev-ctrl.h" #include "udev-varlink.h" #include "udevadm.h" #include "varlink-util.h" @@ -170,79 +168,11 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -static int send_control_commands_via_ctrl(void) { - _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL; - int r; - - r = udev_ctrl_new(&uctrl); - if (r < 0) - return log_error_errno(r, "Failed to initialize udev control: %m"); - - if (arg_exit) { - r = udev_ctrl_send_exit(uctrl); - if (r < 0) - return log_error_errno(r, "Failed to send exit request: %m"); - return 0; - } - - if (arg_log_level >= 0) { - r = udev_ctrl_send_set_log_level(uctrl, arg_log_level); - if (r < 0) - return log_error_errno(r, "Failed to send request to set log level: %m"); - } - - if (arg_start_exec_queue == false) { - r = udev_ctrl_send_stop_exec_queue(uctrl); - if (r < 0) - return log_error_errno(r, "Failed to send request to stop exec queue: %m"); - } - - if (arg_start_exec_queue == true) { - r = udev_ctrl_send_start_exec_queue(uctrl); - if (r < 0) - return log_error_errno(r, "Failed to send request to start exec queue: %m"); - } - - if (arg_reload) { - r = udev_ctrl_send_reload(uctrl); - if (r < 0) - return log_error_errno(r, "Failed to send reload request: %m"); - } - - STRV_FOREACH(env, arg_env) { - r = udev_ctrl_send_set_env(uctrl, *env); - if (r < 0) - return log_error_errno(r, "Failed to send request to update environment: %m"); - } - - if (arg_max_children >= 0) { - r = udev_ctrl_send_set_children_max(uctrl, arg_max_children); - if (r < 0) - return log_error_errno(r, "Failed to send request to set number of children: %m"); - } - - if (arg_ping) { - r = udev_ctrl_send_ping(uctrl); - if (r < 0) - return log_error_errno(r, "Failed to send a ping message: %m"); - } - - r = udev_ctrl_wait(uctrl, arg_timeout); - if (r < 0) - return log_error_errno(r, "Failed to wait for daemon to reply: %m"); - - return 0; -} - static int send_control_commands(void) { _cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *link = NULL; int r; r = udev_varlink_connect(&link, arg_timeout); - if (ERRNO_IS_NEG_DISCONNECT(r) || r == -ENOENT) { - log_debug_errno(r, "Failed to connect to udev via varlink, falling back to use legacy control socket, ignoring: %m"); - return send_control_commands_via_ctrl(); - } if (r < 0) return log_error_errno(r, "Failed to connect to udev via varlink: %m"); diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c index c23e87c9d6c..4398f40e726 100644 --- a/src/udev/udevadm-settle.c +++ b/src/udev/udevadm-settle.c @@ -209,8 +209,8 @@ int verb_settle_main(int argc, char *argv[], uintptr_t _data, void *userdata) { (void) emit_deprecation_warning(); if (getuid() == 0) { - r = udev_ping(MAX(5 * USEC_PER_SEC, arg_timeout_usec), /* ignore_connection_failure= */ true); - if (r <= 0) + r = udev_ping(MAX(5 * USEC_PER_SEC, arg_timeout_usec)); + if (r < 0) return r; } else { /* For non-privileged users, at least check if udevd is running. */ diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c index f1cdbfe1051..5d7752783f2 100644 --- a/src/udev/udevadm-trigger.c +++ b/src/udev/udevadm-trigger.c @@ -521,10 +521,9 @@ int verb_trigger_main(int argc, char *argv[], uintptr_t _data, void *userdata) { return r; if (arg_ping) { - r = udev_ping(arg_ping_timeout_usec, /* ignore_connection_failure= */ false); + r = udev_ping(arg_ping_timeout_usec); if (r < 0) return r; - assert(r > 0); } if (arg_settle) { diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c index 8e90946960c..7c0c9601e0f 100644 --- a/src/udev/udevadm-util.c +++ b/src/udev/udevadm-util.c @@ -8,14 +8,12 @@ #include "conf-files.h" #include "constants.h" #include "device-private.h" -#include "errno-util.h" #include "extract-word.h" #include "log.h" #include "path-util.h" #include "string-table.h" #include "string-util.h" #include "strv.h" -#include "udev-ctrl.h" #include "udev-rules.h" #include "udev-varlink.h" #include "udevadm-util.h" @@ -174,39 +172,11 @@ int parse_key_value_argument(const char *str, bool require_value, char **key, ch return 0; } -static int udev_ping_via_ctrl(usec_t timeout_usec, bool ignore_connection_failure) { - _cleanup_(udev_ctrl_unrefp) UdevCtrl *uctrl = NULL; - int r; - - r = udev_ctrl_new(&uctrl); - if (r < 0) - return log_error_errno(r, "Failed to initialize udev control: %m"); - - r = udev_ctrl_send_ping(uctrl); - if (r < 0) { - bool ignore = ignore_connection_failure && (ERRNO_IS_NEG_DISCONNECT(r) || r == -ENOENT); - log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r, - "Failed to connect to udev daemon%s: %m", - ignore ? ", ignoring" : ""); - return ignore ? 0 : r; - } - - r = udev_ctrl_wait(uctrl, timeout_usec); - if (r < 0) - return log_error_errno(r, "Failed to wait for daemon to reply: %m"); - - return 1; /* received reply */ -} - -int udev_ping(usec_t timeout_usec, bool ignore_connection_failure) { +int udev_ping(usec_t timeout_usec) { _cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *link = NULL; int r; r = udev_varlink_connect(&link, timeout_usec); - if (ERRNO_IS_NEG_DISCONNECT(r) || r == -ENOENT) { - log_debug_errno(r, "Failed to connect to udev via varlink, falling back to use legacy control socket, ignoring: %m"); - return udev_ping_via_ctrl(timeout_usec, ignore_connection_failure); - } if (r < 0) return log_error_errno(r, "Failed to connect to udev via varlink: %m"); @@ -214,7 +184,7 @@ int udev_ping(usec_t timeout_usec, bool ignore_connection_failure) { if (r < 0) return r; - return 1; /* received reply */ + return 0; } static int search_rules_file_in_conf_dirs(const char *s, const char *root, ConfFile ***files, size_t *n_files) { diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h index 906479825ca..dc3d6bb8330 100644 --- a/src/udev/udevadm-util.h +++ b/src/udev/udevadm-util.h @@ -11,5 +11,5 @@ int find_device_with_action(const char *id, sd_device_action_t action, sd_device int parse_device_action(const char *str, sd_device_action_t *ret); int parse_resolve_name_timing(const char *str, ResolveNameTiming *ret); int parse_key_value_argument(const char *str, bool require_value, char **key, char **value); -int udev_ping(usec_t timeout, bool ignore_connection_failure); +int udev_ping(usec_t timeout); int search_rules_files(char * const *a, const char *root, ConfFile ***ret_files, size_t *ret_n_files); diff --git a/units/meson.build b/units/meson.build index a4b0dc61cc9..8e1f3c2aa8e 100644 --- a/units/meson.build +++ b/units/meson.build @@ -985,11 +985,6 @@ units = [ 'symlinks' : ['sysinit.target.wants/'], 'install_tag' : 'udev', }, - { - 'file' : 'systemd-udevd-control.socket', - 'symlinks' : ['sockets.target.wants/'], - 'install_tag' : 'udev', - }, { 'file' : 'systemd-udevd-kernel.socket', 'symlinks' : ['sockets.target.wants/'], @@ -997,7 +992,7 @@ units = [ }, { 'file' : 'systemd-udevd-varlink.socket', - 'symlinks' : ['sockets.target.wants/'], + 'symlinks' : ['sockets.target.wants/', 'systemd-udevd-control.socket'], 'install_tag' : 'udev', }, { diff --git a/units/systemd-udev-trigger.service b/units/systemd-udev-trigger.service index 0ea1a4bd49a..5a93e7375fd 100644 --- a/units/systemd-udev-trigger.service +++ b/units/systemd-udev-trigger.service @@ -12,7 +12,7 @@ Description=Coldplug All udev Devices Documentation=man:udev(7) man:systemd-udevd.service(8) DefaultDependencies=no Wants=systemd-udevd.service -After=systemd-udevd-kernel.socket systemd-udevd-control.socket systemd-udevd-varlink.socket +After=systemd-udevd-kernel.socket systemd-udevd-varlink.socket Before=sysinit.target ConditionPathIsReadWrite=/sys diff --git a/units/systemd-udevd-control.socket b/units/systemd-udevd-control.socket deleted file mode 100644 index 942f6a5e8bd..00000000000 --- a/units/systemd-udevd-control.socket +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later -# -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=udev Control Socket -Documentation=man:systemd-udevd-control.socket(8) man:udev(7) -DefaultDependencies=no -Before=sockets.target -ConditionPathIsReadWrite=/sys - -[Socket] -Service=systemd-udevd.service -ListenSequentialPacket=/run/udev/control -SocketMode=0600 -PassCredentials=yes -RemoveOnStop=yes -DeferTrigger=yes diff --git a/units/systemd-udevd-varlink.socket b/units/systemd-udevd-varlink.socket index b1094b9c9b7..e2cc9594b0b 100644 --- a/units/systemd-udevd-varlink.socket +++ b/units/systemd-udevd-varlink.socket @@ -17,7 +17,7 @@ ConditionPathIsReadWrite=/sys [Socket] Service=systemd-udevd.service ListenStream=/run/udev/io.systemd.Udev -Symlinks=/run/varlink/registry/io.systemd.Udev +Symlinks=/run/varlink/registry/io.systemd.Udev /run/udev/control FileDescriptorName=varlink SocketMode=0644 RemoveOnStop=yes diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in index 658c19b278e..395b912366b 100644 --- a/units/systemd-udevd.service.in +++ b/units/systemd-udevd.service.in @@ -39,7 +39,7 @@ DelegateSubgroup=udev Type=notify-reload # Note that udev will reset the value internally for its workers OOMScoreAdjust=-1000 -Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udevd-varlink.socket +Sockets=systemd-udevd-kernel.socket systemd-udevd-varlink.socket Restart=always RestartSec=0 ExecStart={{LIBEXECDIR}}/systemd-udevd