summaryrefslogtreecommitdiff
path: root/udev
diff options
context:
space:
mode:
Diffstat (limited to 'udev')
-rw-r--r--udev/udevd.c98
1 files changed, 81 insertions, 17 deletions
diff --git a/udev/udevd.c b/udev/udevd.c
index dbb1e16004..b30a27bf71 100644
--- a/udev/udevd.c
+++ b/udev/udevd.c
@@ -1099,6 +1099,42 @@ static int convert_db(struct udev *udev)
return 0;
}
+static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink)
+{
+ int ctrl = -1, netlink = -1;
+ int fd, n;
+
+ n = sd_listen_fds(true);
+ if (n <= 0)
+ return -1;
+
+ for (fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) {
+ if (sd_is_socket(fd, AF_LOCAL, SOCK_SEQPACKET, -1)) {
+ if (ctrl >= 0)
+ return -1;
+ ctrl = fd;
+ continue;
+ }
+
+ if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1)) {
+ if (netlink >= 0)
+ return -1;
+ netlink = fd;
+ continue;
+ }
+
+ return -1;
+ }
+
+ if (ctrl < 0 || netlink < 0)
+ return -1;
+
+ info(udev, "ctrl=%i netlink=%i\n", ctrl, netlink);
+ *rctrl = ctrl;
+ *rnetlink = netlink;
+ return 0;
+}
+
int main(int argc, char *argv[])
{
struct udev *udev;
@@ -1277,34 +1313,57 @@ int main(int argc, char *argv[])
}
}
- /* udevadm control socket */
- if (sd_listen_fds(true) == 1 && sd_is_socket(SD_LISTEN_FDS_START, AF_LOCAL, SOCK_SEQPACKET, -1))
- udev_ctrl = udev_ctrl_new_from_fd(udev, SD_LISTEN_FDS_START);
- else
+ if (systemd_fds(udev, &fd_ctrl, &fd_netlink) >= 0) {
+ /* get control and netlink socket from from systemd */
+ udev_ctrl = udev_ctrl_new_from_socket_fd(udev, UDEV_CTRL_SOCK_PATH, fd_ctrl);
+ if (udev_ctrl == NULL) {
+ err(udev, "error taking over udev control socket");
+ rc = 1;
+ goto exit;
+ }
+
+ monitor = udev_monitor_new_from_netlink_fd(udev, "kernel", fd_netlink);
+ if (monitor == NULL) {
+ err(udev, "error taking over netlink socket\n");
+ rc = 3;
+ goto exit;
+ }
+ } else {
+ /* open control and netlink socket */
udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
- if (udev_ctrl == NULL) {
- fprintf(stderr, "error initializing udev control socket");
- err(udev, "error initializing udev control socket");
- rc = 1;
+ if (udev_ctrl == NULL) {
+ fprintf(stderr, "error initializing udev control socket");
+ err(udev, "error initializing udev control socket");
+ rc = 1;
+ goto exit;
+ }
+ fd_ctrl = udev_ctrl_get_fd(udev_ctrl);
+
+ monitor = udev_monitor_new_from_netlink(udev, "kernel");
+ if (monitor == NULL) {
+ fprintf(stderr, "error initializing netlink socket\n");
+ err(udev, "error initializing netlink socket\n");
+ rc = 3;
+ goto exit;
+ }
+ fd_netlink = udev_monitor_get_fd(monitor);
+ }
+
+ if (udev_monitor_enable_receiving(monitor) < 0) {
+ fprintf(stderr, "error binding netlink socket\n");
+ err(udev, "error binding netlink socket\n");
+ rc = 3;
goto exit;
}
+
if (udev_ctrl_enable_receiving(udev_ctrl) < 0) {
fprintf(stderr, "error binding udev control socket\n");
err(udev, "error binding udev control socket\n");
rc = 1;
goto exit;
}
- fd_ctrl = udev_ctrl_get_fd(udev_ctrl);
- monitor = udev_monitor_new_from_netlink(udev, "kernel");
- if (monitor == NULL || udev_monitor_enable_receiving(monitor) < 0) {
- fprintf(stderr, "error initializing netlink socket\n");
- err(udev, "error initializing netlink socket\n");
- rc = 3;
- goto exit;
- }
udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024);
- fd_netlink = udev_monitor_get_fd(monitor);
if (daemonize) {
pid_t pid;
@@ -1428,18 +1487,23 @@ int main(int argc, char *argv[])
memset(&ep_ctrl, 0, sizeof(struct epoll_event));
ep_ctrl.events = EPOLLIN;
ep_ctrl.data.fd = fd_ctrl;
+
memset(&ep_inotify, 0, sizeof(struct epoll_event));
ep_inotify.events = EPOLLIN;
ep_inotify.data.fd = fd_inotify;
+
memset(&ep_signal, 0, sizeof(struct epoll_event));
ep_signal.events = EPOLLIN;
ep_signal.data.fd = fd_signal;
+
memset(&ep_netlink, 0, sizeof(struct epoll_event));
ep_netlink.events = EPOLLIN;
ep_netlink.data.fd = fd_netlink;
+
memset(&ep_worker, 0, sizeof(struct epoll_event));
ep_worker.events = EPOLLIN;
ep_worker.data.fd = fd_worker;
+
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
err(udev, "error creating epoll fd: %m\n");