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.
This commit is contained in:
Yu Watanabe
2026-07-18 05:29:59 +09:00
parent 14f934df35
commit 17e911ffc8
23 changed files with 21 additions and 735 deletions
-1
View File
@@ -1319,7 +1319,6 @@ manpages = [
['systemd-udevd.service',
'8',
['systemd-udevd',
'systemd-udevd-control.socket',
'systemd-udevd-kernel.socket',
'systemd-udevd-varlink.socket'],
''],
-2
View File
@@ -18,7 +18,6 @@
<refnamediv>
<refname>systemd-udevd.service</refname>
<refname>systemd-udevd-control.socket</refname>
<refname>systemd-udevd-kernel.socket</refname>
<refname>systemd-udevd-varlink.socket</refname>
<refname>systemd-udevd</refname>
@@ -27,7 +26,6 @@
<refsynopsisdiv>
<para><filename>systemd-udevd.service</filename></para>
<para><filename>systemd-udevd-control.socket</filename></para>
<para><filename>systemd-udevd-kernel.socket</filename></para>
<para><filename>systemd-udevd-varlink.socket</filename></para>
+1 -1
View File
@@ -713,7 +713,7 @@
Note that <filename>systemd-udevd.service</filename> contains
<option>Restart=always</option> and so as a result, this option restarts systemd-udevd.
If you want to stop <filename>systemd-udevd.service</filename>, please use the following:
<programlisting>systemctl stop systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udevd-varlink.socket systemd-udevd.service</programlisting>
<programlisting>systemctl stop systemd-udevd-kernel.socket systemd-udevd-varlink.socket systemd-udevd.service</programlisting>
</para>
</listitem>
</varlistentry>
-1
View File
@@ -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");
-2
View File
@@ -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',
-362
View File
@@ -1,362 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <poll.h>
#include <sys/un.h>
#include <unistd.h>
#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);
}
-72
View File
@@ -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);
-1
View File
@@ -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;
-134
View File
@@ -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;
}
-7
View File
@@ -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);
+1 -11
View File
@@ -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;
-2
View File
@@ -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;
+9
View File
@@ -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,
-70
View File
@@ -3,7 +3,6 @@
#include <string.h>
#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");
+2 -2
View File
@@ -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. */
+1 -2
View File
@@ -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) {
+2 -32
View File
@@ -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) {
+1 -1
View File
@@ -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);
+1 -6
View File
@@ -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',
},
{
+1 -1
View File
@@ -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
-23
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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