[systemd-commits] 7 commits - src/udev

Tom Gundersen tomegun at kemper.freedesktop.org
Mon May 18 14:53:53 PDT 2015


 src/udev/udevd.c |  467 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 241 insertions(+), 226 deletions(-)

New commits:
commit f53d1fcdb355125a1347acf0d2d1ffa7264d6bfe
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon May 18 17:21:03 2015 +0200

    udevd: main - use _exit() when daemonizing
    
    Makes it a bit clearer what is going on, rather than jumping to the end of main().
    
    No functional change.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 4f43a6f..19640cb 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1507,7 +1507,9 @@ int main(int argc, char *argv[]) {
                         r = log_error_errno(errno, "fork of daemon failed: %m");
                         goto exit;
                 default:
-                        goto exit_daemonize;
+                        mac_selinux_finish();
+                        log_close();
+                        _exit(EXIT_SUCCESS);
                 }
 
                 setsid();
@@ -1697,7 +1699,6 @@ int main(int argc, char *argv[]) {
 exit:
         if (manager)
                 udev_ctrl_cleanup(manager->ctrl);
-exit_daemonize:
         mac_selinux_finish();
         log_close();
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;

commit 712cebf146b65136f02b49eb0f64a14f4628aec9
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon May 18 17:19:38 2015 +0200

    udevd: main - reshuffle
    
    First parse config, then sanitize environment before donig any further setup.
    
    No functional change.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 933b60c..4f43a6f 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1434,57 +1434,57 @@ int main(int argc, char *argv[]) {
                 goto exit;
         }
 
-        r = mac_selinux_init("/dev");
-        if (r < 0) {
-                log_error_errno(r, "could not initialize labelling: %m");
-                goto exit;
-        }
+        if (arg_children_max == 0) {
+                cpu_set_t cpu_set;
 
-        /* set umask before creating any file/directory */
-        r = chdir("/");
-        if (r < 0) {
-                r = log_error_errno(errno, "could not change dir to /: %m");
-                goto exit;
-        }
+                arg_children_max = 8;
 
-        umask(022);
+                if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
+                        arg_children_max +=  CPU_COUNT(&cpu_set) * 2;
+                }
 
-        r = mkdir("/run/udev", 0755);
-        if (r < 0 && errno != EEXIST) {
-                r = log_error_errno(errno, "could not create /run/udev: %m");
-                goto exit;
+                log_debug("set children_max to %u", arg_children_max);
         }
 
-        dev_setup(NULL);
-
         /* before opening new files, make sure std{in,out,err} fds are in a sane state */
         if (arg_daemonize) {
                 int fd;
 
                 fd = open("/dev/null", O_RDWR);
-                if (fd >= 0) {
+                if (fd < 0)
+                        log_error("cannot open /dev/null");
+                else {
                         if (write(STDOUT_FILENO, 0, 0) < 0)
                                 dup2(fd, STDOUT_FILENO);
                         if (write(STDERR_FILENO, 0, 0) < 0)
                                 dup2(fd, STDERR_FILENO);
                         if (fd > STDERR_FILENO)
                                 close(fd);
-                } else {
-                        log_error("cannot open /dev/null");
                 }
         }
 
-        if (arg_children_max == 0) {
-                cpu_set_t cpu_set;
+        /* set umask before creating any file/directory */
+        r = chdir("/");
+        if (r < 0) {
+                r = log_error_errno(errno, "could not change dir to /: %m");
+                goto exit;
+        }
 
-                arg_children_max = 8;
+        umask(022);
 
-                if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
-                        arg_children_max +=  CPU_COUNT(&cpu_set) * 2;
-                }
+        r = mac_selinux_init("/dev");
+        if (r < 0) {
+                log_error_errno(r, "could not initialize labelling: %m");
+                goto exit;
         }
 
-        log_debug("set children_max to %u", arg_children_max);
+        r = mkdir("/run/udev", 0755);
+        if (r < 0 && errno != EEXIST) {
+                r = log_error_errno(errno, "could not create /run/udev: %m");
+                goto exit;
+        }
+
+        dev_setup(NULL);
 
         r = manager_new(&manager);
         if (r < 0)

commit 0561329d1f4e6634b3b20682b036c4f22e4b5b21
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon May 18 17:18:46 2015 +0200

    udevd: rename on_reque_{exit,reload} to on_sig{term,chld}
    
    No functional change.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index a641b16..933b60c 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1035,7 +1035,7 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda
         return 1;
 }
 
-static int on_request_exit(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
+static int on_sigterm(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
         Manager *manager = userdata;
 
         assert(manager);
@@ -1045,7 +1045,7 @@ static int on_request_exit(sd_event_source *s, const struct signalfd_siginfo *si
         return 1;
 }
 
-static int on_request_reload(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
+static int on_sighup(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
         Manager *manager = userdata;
 
         assert(manager);
@@ -1665,10 +1665,10 @@ int main(int argc, char *argv[]) {
                                 switch (fdsi.ssi_signo) {
                                 case SIGINT:
                                 case SIGTERM:
-                                        on_request_exit(NULL, &fdsi, manager);
+                                        on_sigterm(NULL, &fdsi, manager);
                                         break;
                                 case SIGHUP:
-                                        on_request_reload(NULL, &fdsi, manager);
+                                        on_sighup(NULL, &fdsi, manager);
                                         break;
                                 case SIGCHLD:
                                         on_sigchld(NULL, &fdsi, manager);

commit 4fa4d885556af16fb945f9a9402e71077d5a4e4a
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon May 18 17:17:07 2015 +0200

    udevd: introduce on_event_timeout{,_warning}
    
    This uses kill_and_sigcont() instead of kill(), otherwise no functional change.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index a9e82de..a641b16 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -43,6 +43,7 @@
 #include "sd-daemon.h"
 #include "rtnl-util.h"
 #include "cgroup-util.h"
+#include "process-util.h"
 #include "dev-setup.h"
 #include "fileio.h"
 #include "selinux-util.h"
@@ -226,6 +227,30 @@ static int worker_new(struct worker **ret, Manager *manager, struct udev_monitor
         return 0;
 }
 
+static int on_event_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
+        struct event *event = userdata;
+
+        assert(event);
+        assert(event->worker);
+
+        kill_and_sigcont(event->worker->pid, SIGKILL);
+        event->worker->state = WORKER_KILLED;
+
+        log_error("seq %llu '%s' killed", udev_device_get_seqnum(event->dev), event->devpath);
+
+        return 1;
+}
+
+static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) {
+        struct event *event = userdata;
+
+        assert(event);
+
+        log_warning("seq %llu '%s' is taking a long time", udev_device_get_seqnum(event->dev), event->devpath);
+
+        return 1;
+}
+
 static void worker_attach_event(struct worker *worker, struct event *event) {
         assert(worker);
         assert(event);
@@ -1571,14 +1596,10 @@ int main(int argc, char *argv[]) {
                                 ts = now(CLOCK_MONOTONIC);
 
                                 if ((ts - event->start_usec) > arg_event_timeout_warn_usec) {
-                                        if ((ts - event->start_usec) > arg_event_timeout_usec) {
-                                                log_error("worker ["PID_FMT"] %s timeout; kill it", worker->pid, event->devpath);
-                                                kill(worker->pid, SIGKILL);
-                                                worker->state = WORKER_KILLED;
-
-                                                log_error("seq %llu '%s' killed", udev_device_get_seqnum(event->dev), event->devpath);
-                                        } else if (!event->warned) {
-                                                log_warning("worker ["PID_FMT"] %s is taking a long time", worker->pid, event->devpath);
+                                        if ((ts - event->start_usec) > arg_event_timeout_usec)
+                                                on_event_timeout(NULL, 0, event);
+                                        else if (!event->warned) {
+                                                on_event_timeout_warning(NULL, 0, event);
                                                 event->warned = true;
                                         }
                                 }

commit f29328d6557f1ebb3df5c0b491fb3dd3d970d356
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon May 18 17:07:04 2015 +0200

    udevd: process all SIGCHLD events every time the handler is invoked
    
    We were returning rather than continuing in some cases. The intention
    was always to fully process all pending events before returning
    from the SIGCHLD handler. Restore this behaviour.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 892637f..a9e82de 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1042,12 +1042,12 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
 
                 pid = waitpid(-1, &status, WNOHANG);
                 if (pid <= 0)
-                        return 1;
+                        break;
 
                 worker = hashmap_get(manager->workers, UINT_TO_PTR(pid));
                 if (!worker) {
                         log_warning("worker ["PID_FMT"] is unknown, ignoring", pid);
-                        return 1;
+                        continue;
                 }
 
                 if (WIFEXITED(status)) {
@@ -1059,10 +1059,10 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
                         log_warning("worker ["PID_FMT"] terminated by signal %i (%s)", pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
                 } else if (WIFSTOPPED(status)) {
                         log_info("worker ["PID_FMT"] stopped", pid);
-                        return 1;
+                        continue;
                 } else if (WIFCONTINUED(status)) {
                         log_info("worker ["PID_FMT"] continued", pid);
-                        return 1;
+                        continue;
                 } else
                         log_warning("worker ["PID_FMT"] exit with status 0x%04x", pid, status);
 

commit b2d21d9318497517519956ab9994f2303aa0223e
Author: Tom Gundersen <teg at jklm.no>
Date:   Wed May 13 11:39:45 2015 +0200

    udevd: init/exit the builtins in manager_new/free
    
    No functional change.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index a555026..892637f 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -244,6 +244,8 @@ static void manager_free(Manager *manager) {
         if (!manager)
                 return;
 
+        udev_builtin_exit(manager->udev);
+
         udev_unref(manager->udev);
         manager_workers_free(manager);
         event_queue_cleanup(manager, EVENT_UNDEF);
@@ -471,7 +473,6 @@ skip:
 out:
                 udev_device_unref(dev);
                 manager_free(manager);
-                udev_builtin_exit(udev);
                 log_close();
                 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
         }
@@ -1288,6 +1289,8 @@ static int manager_new(Manager **ret) {
         if (!manager->udev)
                 return log_error_errno(errno, "could not allocate udev context: %m");
 
+        udev_builtin_init(manager->udev);
+
         manager->rules = udev_rules_new(manager->udev, arg_resolve_names);
         if (!manager->rules)
                 return log_error_errno(ENOMEM, "error reading rules");
@@ -1464,8 +1467,6 @@ int main(int argc, char *argv[]) {
 
         log_info("starting version " VERSION);
 
-        udev_builtin_init(manager->udev);
-
         r = udev_rules_apply_static_dev_perms(manager->rules);
         if (r < 0)
                 log_error_errno(r, "failed to apply permissions on static device nodes: %m");
@@ -1676,8 +1677,6 @@ exit:
         if (manager)
                 udev_ctrl_cleanup(manager->ctrl);
 exit_daemonize:
-        if (manager)
-                udev_builtin_exit(manager->udev);
         mac_selinux_finish();
         log_close();
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;

commit e237d8cb0e5488eef311ca1eafe48e8a2248b04c
Author: Tom Gundersen <teg at jklm.no>
Date:   Tue May 12 21:16:47 2015 +0200

    udevd: move file descriptors to Manager
    
    No functional change.

diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 37cf0de..a555026 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -51,10 +51,6 @@
 #include "formats-util.h"
 #include "hashmap.h"
 
-static int worker_watch[2] = { -1, -1 };
-static int fd_signal = -1;
-static int fd_ep = -1;
-static int fd_inotify = -1;
 static bool arg_debug = false;
 static int arg_daemonize = false;
 static int arg_resolve_names = 1;
@@ -62,7 +58,6 @@ static unsigned arg_children_max;
 static int arg_exec_delay;
 static usec_t arg_event_timeout_usec = 180 * USEC_PER_SEC;
 static usec_t arg_event_timeout_warn_usec = 180 * USEC_PER_SEC / 3;
-static sigset_t sigmask_orig;
 
 typedef struct Manager {
         struct udev *udev;
@@ -70,6 +65,7 @@ typedef struct Manager {
         struct udev_list_node events;
         char *cgroup;
         pid_t pid; /* the process that originally allocated the manager object */
+        sigset_t sigmask_orig;
 
         struct udev_rules *rules;
         struct udev_list properties;
@@ -78,6 +74,14 @@ typedef struct Manager {
         struct udev_ctrl *ctrl;
         struct udev_ctrl_connection *ctrl_conn_blocking;
 
+        int fd_ep;
+        int fd_ctrl;
+        int fd_uevent;
+        int fd_signal;
+        int fd_inotify;
+        int fd_worker;
+        int worker_watch[2];
+
         bool stop_exec_queue:1;
         bool reload:1;
         bool exit:1;
@@ -236,6 +240,32 @@ static void worker_attach_event(struct worker *worker, struct event *event) {
         event->worker = worker;
 }
 
+static void manager_free(Manager *manager) {
+        if (!manager)
+                return;
+
+        udev_unref(manager->udev);
+        manager_workers_free(manager);
+        event_queue_cleanup(manager, EVENT_UNDEF);
+
+        udev_monitor_unref(manager->monitor);
+        udev_ctrl_unref(manager->ctrl);
+        udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
+
+        udev_list_cleanup(&manager->properties);
+        udev_rules_unref(manager->rules);
+        free(manager->cgroup);
+
+        safe_close(manager->fd_ep);
+        safe_close(manager->fd_signal);
+        safe_close(manager->fd_inotify);
+        safe_close_pair(manager->worker_watch);
+
+        free(manager);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
+
 static int worker_send_message(int fd) {
         struct worker_message message = {};
 
@@ -260,6 +290,7 @@ static void worker_spawn(Manager *manager, struct event *event) {
         case 0: {
                 struct udev_device *dev = NULL;
                 int fd_monitor;
+                _cleanup_close_ int fd_signal = -1, fd_ep = -1;
                 _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
                 struct epoll_event ep_signal, ep_monitor;
                 sigset_t mask;
@@ -271,11 +302,11 @@ static void worker_spawn(Manager *manager, struct event *event) {
 
                 manager_workers_free(manager);
                 event_queue_cleanup(manager, EVENT_UNDEF);
-                udev_monitor_unref(manager->monitor);
-                udev_ctrl_unref(manager->ctrl);
-                close(fd_signal);
-                close(fd_ep);
-                close(worker_watch[READ_END]);
+                manager->monitor = udev_monitor_unref(manager->monitor);
+                manager->ctrl = udev_ctrl_unref(manager->ctrl);
+                manager->fd_signal = safe_close(manager->fd_signal);
+                manager->worker_watch[READ_END] = safe_close(manager->worker_watch[READ_END]);
+                manager->fd_ep = safe_close(manager->fd_ep);
 
                 sigfillset(&mask);
                 fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
@@ -364,11 +395,11 @@ static void worker_spawn(Manager *manager, struct event *event) {
                                                  arg_event_timeout_usec, arg_event_timeout_warn_usec,
                                                  &manager->properties,
                                                  manager->rules,
-                                                 &sigmask_orig);
+                                                 &manager->sigmask_orig);
 
                         udev_event_execute_run(udev_event,
                                                arg_event_timeout_usec, arg_event_timeout_warn_usec,
-                                               &sigmask_orig);
+                                               &manager->sigmask_orig);
 
                         if (udev_event->rtnl)
                                 /* in case rtnl was initialized */
@@ -389,7 +420,7 @@ skip:
                         log_debug("seq %llu processed", udev_device_get_seqnum(dev));
 
                         /* send udevd the result of the event execution */
-                        r = worker_send_message(worker_watch[WRITE_END]);
+                        r = worker_send_message(manager->worker_watch[WRITE_END]);
                         if (r < 0)
                                 log_error_errno(r, "failed to send result of seq %llu to main daemon: %m",
                                                 udev_device_get_seqnum(dev));
@@ -439,13 +470,8 @@ skip:
                 }
 out:
                 udev_device_unref(dev);
-                safe_close(fd_signal);
-                safe_close(fd_ep);
-                close(fd_inotify);
-                close(worker_watch[WRITE_END]);
-                udev_rules_unref(manager->rules);
+                manager_free(manager);
                 udev_builtin_exit(udev);
-                udev_unref(udev);
                 log_close();
                 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
         }
@@ -1232,29 +1258,15 @@ static int parse_argv(int argc, char *argv[]) {
         return 1;
 }
 
-static void manager_free(Manager *manager) {
-        if (!manager)
-                return;
-
-        udev_unref(manager->udev);
-        manager_workers_free(manager);
-        event_queue_cleanup(manager, EVENT_UNDEF);
-
-        udev_monitor_unref(manager->monitor);
-        udev_ctrl_unref(manager->ctrl);
-        udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
-
-        udev_list_cleanup(&manager->properties);
-        udev_rules_unref(manager->rules);
-        free(manager->cgroup);
-
-        free(manager);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
-
 static int manager_new(Manager **ret) {
         _cleanup_(manager_freep) Manager *manager = NULL;
+        struct epoll_event ep_ctrl = { .events = EPOLLIN };
+        struct epoll_event ep_inotify = { .events = EPOLLIN };
+        struct epoll_event ep_signal = { .events = EPOLLIN };
+        struct epoll_event ep_netlink = { .events = EPOLLIN };
+        struct epoll_event ep_worker = { .events = EPOLLIN };
+        sigset_t mask;
+        int r, one = 1;
 
         assert(ret);
 
@@ -1264,6 +1276,14 @@ static int manager_new(Manager **ret) {
 
         manager->pid = getpid();
 
+        manager->fd_ep = -1;
+        manager->fd_ctrl = -1;
+        manager->fd_uevent = -1;
+        manager->fd_signal = -1;
+        manager->fd_inotify = -1;
+        manager->worker_watch[WRITE_END] = -1;
+        manager->worker_watch[READ_END] = -1;
+
         manager->udev = udev_new();
         if (!manager->udev)
                 return log_error_errno(errno, "could not allocate udev context: %m");
@@ -1275,6 +1295,87 @@ static int manager_new(Manager **ret) {
         udev_list_node_init(&manager->events);
         udev_list_init(manager->udev, &manager->properties, true);
 
+        r = systemd_fds(&manager->fd_ctrl, &manager->fd_uevent);
+        if (r >= 0) {
+                /* get control and netlink socket from systemd */
+                manager->ctrl = udev_ctrl_new_from_fd(manager->udev, manager->fd_ctrl);
+                if (!manager->ctrl)
+                        return log_error_errno(EINVAL, "error taking over udev control socket");
+
+                manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", manager->fd_uevent);
+                if (!manager->monitor)
+                        return log_error_errno(EINVAL, "error taking over netlink socket");
+
+                /* get our own cgroup, we regularly kill everything udev has left behind */
+                r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &manager->cgroup);
+                if (r < 0)
+                        log_warning_errno(r, "failed to get cgroup: %m");
+        } else {
+                /* open control and netlink socket */
+                manager->ctrl = udev_ctrl_new(manager->udev);
+                if (!manager->ctrl)
+                        return log_error_errno(EINVAL, "error initializing udev control socket");
+
+                manager->fd_ctrl = udev_ctrl_get_fd(manager->ctrl);
+
+                manager->monitor = udev_monitor_new_from_netlink(manager->udev, "kernel");
+                if (!manager->monitor)
+                        return log_error_errno(EINVAL, "error initializing netlink socket");
+
+                manager->fd_uevent = udev_monitor_get_fd(manager->monitor);
+
+                (void) udev_monitor_set_receive_buffer_size(manager->monitor, 128 * 1024 * 1024);
+        }
+
+        r = udev_monitor_enable_receiving(manager->monitor);
+        if (r < 0)
+                return log_error_errno(EINVAL, "error binding netlink socket");
+
+        r = udev_ctrl_enable_receiving(manager->ctrl);
+        if (r < 0)
+                return log_error_errno(EINVAL, "error binding udev control socket");
+
+        /* unnamed socket from workers to the main daemon */
+        r = socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
+        if (r < 0)
+                return log_error_errno(errno, "error creating socketpair: %m");
+
+        manager->fd_worker = manager->worker_watch[READ_END];
+
+        r = setsockopt(manager->fd_worker, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
+        if (r < 0)
+                return log_error_errno(errno, "could not enable SO_PASSCRED: %m");
+
+        manager->fd_inotify = udev_watch_init(manager->udev);
+        if (manager->fd_inotify < 0)
+                return log_error_errno(ENOMEM, "error initializing inotify");
+
+        udev_watch_restore(manager->udev);
+
+        /* block and listen to all signals on signalfd */
+        sigfillset(&mask);
+        sigprocmask(SIG_SETMASK, &mask, &manager->sigmask_orig);
+        manager->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
+        if (manager->fd_signal < 0)
+                return log_error_errno(errno, "error creating signalfd");
+
+        ep_ctrl.data.fd = manager->fd_ctrl;
+        ep_inotify.data.fd = manager->fd_inotify;
+        ep_signal.data.fd = manager->fd_signal;
+        ep_netlink.data.fd = manager->fd_uevent;
+        ep_worker.data.fd = manager->fd_worker;
+
+        manager->fd_ep = epoll_create1(EPOLL_CLOEXEC);
+        if (manager->fd_ep < 0)
+                return log_error_errno(errno, "error creating epoll fd: %m");
+
+        if (epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_ctrl, &ep_ctrl) < 0 ||
+            epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_inotify, &ep_inotify) < 0 ||
+            epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_signal, &ep_signal) < 0 ||
+            epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_uevent, &ep_netlink) < 0 ||
+            epoll_ctl(manager->fd_ep, EPOLL_CTL_ADD, manager->fd_worker, &ep_worker) < 0)
+                return log_error_errno(errno, "fail to add fds to epoll: %m");
+
         *ret = manager;
         manager = NULL;
 
@@ -1283,16 +1384,7 @@ static int manager_new(Manager **ret) {
 
 int main(int argc, char *argv[]) {
         _cleanup_(manager_freep) Manager *manager = NULL;
-        sigset_t mask;
-        int fd_ctrl = -1;
-        int fd_netlink = -1;
-        int fd_worker = -1;
-        struct epoll_event ep_ctrl = { .events = EPOLLIN };
-        struct epoll_event ep_inotify = { .events = EPOLLIN };
-        struct epoll_event ep_signal = { .events = EPOLLIN };
-        struct epoll_event ep_netlink = { .events = EPOLLIN };
-        struct epoll_event ep_worker = { .events = EPOLLIN };
-        int r = 0, one = 1;
+        int r;
 
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
@@ -1337,10 +1429,6 @@ int main(int argc, char *argv[]) {
 
         dev_setup(NULL);
 
-        r = manager_new(&manager);
-        if (r < 0)
-                goto exit;
-
         /* before opening new files, make sure std{in,out,err} fds are in a sane state */
         if (arg_daemonize) {
                 int fd;
@@ -1358,51 +1446,21 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        if (systemd_fds(&fd_ctrl, &fd_netlink) >= 0) {
-                /* get control and netlink socket from systemd */
-                manager->ctrl = udev_ctrl_new_from_fd(manager->udev, fd_ctrl);
-                if (!manager->ctrl) {
-                        r = log_error_errno(EINVAL, "error taking over udev control socket");
-                        goto exit;
-                }
-
-                manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", fd_netlink);
-                if (!manager->monitor) {
-                        r = log_error_errno(EINVAL, "error taking over netlink socket");
-                        goto exit;
-                }
+        if (arg_children_max == 0) {
+                cpu_set_t cpu_set;
 
-                /* get our own cgroup, we regularly kill everything udev has left behind */
-                if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &manager->cgroup) < 0)
-                        manager->cgroup = NULL;
-        } else {
-                /* open control and netlink socket */
-                manager->ctrl = udev_ctrl_new(manager->udev);
-                if (!manager->ctrl) {
-                        r = log_error_errno(EINVAL, "error initializing udev control socket");
-                        goto exit;
-                }
-                fd_ctrl = udev_ctrl_get_fd(manager->ctrl);
+                arg_children_max = 8;
 
-                manager->monitor = udev_monitor_new_from_netlink(manager->udev, "kernel");
-                if (!manager->monitor) {
-                        r = log_error_errno(EINVAL, "error initializing netlink socket");
-                        goto exit;
+                if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
+                        arg_children_max +=  CPU_COUNT(&cpu_set) * 2;
                 }
-                fd_netlink = udev_monitor_get_fd(manager->monitor);
-
-                udev_monitor_set_receive_buffer_size(manager->monitor, 128 * 1024 * 1024);
         }
 
-        if (udev_monitor_enable_receiving(manager->monitor) < 0) {
-                r = log_error_errno(EINVAL, "error binding netlink socket");
-                goto exit;
-        }
+        log_debug("set children_max to %u", arg_children_max);
 
-        if (udev_ctrl_enable_receiving(manager->ctrl) < 0) {
-                r = log_error_errno(EINVAL, "error binding udev control socket");
+        r = manager_new(&manager);
+        if (r < 0)
                 goto exit;
-        }
 
         log_info("starting version " VERSION);
 
@@ -1429,90 +1487,32 @@ int main(int argc, char *argv[]) {
                 setsid();
 
                 write_string_file("/proc/self/oom_score_adj", "-1000");
-        } else {
+        } else
                 sd_notify(1, "READY=1");
-        }
-
-        if (arg_children_max == 0) {
-                cpu_set_t cpu_set;
-
-                arg_children_max = 8;
-
-                if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
-                        arg_children_max +=  CPU_COUNT(&cpu_set) * 2;
-                }
-        }
-        log_debug("set children_max to %u", arg_children_max);
-
-        fd_inotify = udev_watch_init(manager->udev);
-        if (fd_inotify < 0) {
-                r = log_error_errno(ENOMEM, "error initializing inotify");
-                goto exit;
-        }
-        udev_watch_restore(manager->udev);
-
-        /* block and listen to all signals on signalfd */
-        sigfillset(&mask);
-        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
-        fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
-        if (fd_signal < 0) {
-                r = log_error_errno(errno, "error creating signalfd");
-                goto exit;
-        }
-
-        /* unnamed socket from workers to the main daemon */
-        if (socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, worker_watch) < 0) {
-                r = log_error_errno(errno, "error creating socketpair");
-                goto exit;
-        }
-        fd_worker = worker_watch[READ_END];
-
-        r = setsockopt(fd_worker, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
-        if (r < 0)
-                return log_error_errno(errno, "could not enable SO_PASSCRED: %m");
-
-        ep_ctrl.data.fd = fd_ctrl;
-        ep_inotify.data.fd = fd_inotify;
-        ep_signal.data.fd = fd_signal;
-        ep_netlink.data.fd = fd_netlink;
-        ep_worker.data.fd = fd_worker;
-
-        fd_ep = epoll_create1(EPOLL_CLOEXEC);
-        if (fd_ep < 0) {
-                log_error_errno(errno, "error creating epoll fd: %m");
-                goto exit;
-        }
-        if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_inotify, &ep_inotify) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 ||
-            epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) {
-                log_error_errno(errno, "fail to add fds to epoll: %m");
-                goto exit;
-        }
 
         for (;;) {
                 static usec_t last_usec;
                 struct epoll_event ev[8];
                 int fdcount;
                 int timeout;
-                bool is_worker, is_signal, is_inotify, is_netlink, is_ctrl;
+                bool is_worker, is_signal, is_inotify, is_uevent, is_ctrl;
                 int i;
 
                 if (manager->exit) {
                         /* close sources of new events and discard buffered events */
-                        if (fd_ctrl >= 0) {
-                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_ctrl, NULL);
-                                fd_ctrl = -1;
+                        if (manager->fd_ctrl >= 0) {
+                                epoll_ctl(manager->fd_ep, EPOLL_CTL_DEL, manager->fd_ctrl, NULL);
+                                manager->fd_ctrl = safe_close(manager->fd_ctrl);
                         }
+
                         if (manager->monitor) {
-                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_netlink, NULL);
+                                epoll_ctl(manager->fd_ep, EPOLL_CTL_DEL, manager->fd_uevent, NULL);
                                 manager->monitor = udev_monitor_unref(manager->monitor);
                         }
-                        if (fd_inotify >= 0) {
-                                epoll_ctl(fd_ep, EPOLL_CTL_DEL, fd_inotify, NULL);
-                                close(fd_inotify);
-                                fd_inotify = -1;
+
+                        if (manager->fd_inotify >= 0) {
+                                epoll_ctl(manager->fd_ep, EPOLL_CTL_DEL, manager->fd_inotify, NULL);
+                                manager->fd_inotify = safe_close(manager->fd_inotify);
                         }
 
                         /* discard queued events and kill workers */
@@ -1537,7 +1537,7 @@ int main(int argc, char *argv[]) {
                         timeout = 3 * MSEC_PER_SEC;
                 }
 
-                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
+                fdcount = epoll_wait(manager->fd_ep, ev, ELEMENTSOF(ev), timeout);
                 if (fdcount < 0)
                         continue;
 
@@ -1585,17 +1585,17 @@ int main(int argc, char *argv[]) {
 
                 }
 
-                is_worker = is_signal = is_inotify = is_netlink = is_ctrl = false;
+                is_worker = is_signal = is_inotify = is_uevent = is_ctrl = false;
                 for (i = 0; i < fdcount; i++) {
-                        if (ev[i].data.fd == fd_worker && ev[i].events & EPOLLIN)
+                        if (ev[i].data.fd == manager->fd_worker && ev[i].events & EPOLLIN)
                                 is_worker = true;
-                        else if (ev[i].data.fd == fd_netlink && ev[i].events & EPOLLIN)
-                                is_netlink = true;
-                        else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN)
+                        else if (ev[i].data.fd == manager->fd_uevent && ev[i].events & EPOLLIN)
+                                is_uevent = true;
+                        else if (ev[i].data.fd == manager->fd_signal && ev[i].events & EPOLLIN)
                                 is_signal = true;
-                        else if (ev[i].data.fd == fd_inotify && ev[i].events & EPOLLIN)
+                        else if (ev[i].data.fd == manager->fd_inotify && ev[i].events & EPOLLIN)
                                 is_inotify = true;
-                        else if (ev[i].data.fd == fd_ctrl && ev[i].events & EPOLLIN)
+                        else if (ev[i].data.fd == manager->fd_ctrl && ev[i].events & EPOLLIN)
                                 is_ctrl = true;
                 }
 
@@ -1619,11 +1619,11 @@ int main(int argc, char *argv[]) {
 
                 /* event has finished */
                 if (is_worker)
-                        on_worker(NULL, fd_worker, 0, manager);
+                        on_worker(NULL, manager->fd_worker, 0, manager);
 
                 /* uevent from kernel */
-                if (is_netlink)
-                        on_uevent(NULL, fd_netlink, 0, manager);
+                if (is_uevent)
+                        on_uevent(NULL, manager->fd_uevent, 0, manager);
 
                 /* start new events */
                 if (!udev_list_node_is_empty(&manager->events) && !manager->exit && !manager->stop_exec_queue) {
@@ -1638,7 +1638,7 @@ int main(int argc, char *argv[]) {
                         struct signalfd_siginfo fdsi;
                         ssize_t size;
 
-                        size = read(fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
+                        size = read(manager->fd_signal, &fdsi, sizeof(struct signalfd_siginfo));
                         if (size == sizeof(struct signalfd_siginfo)) {
                                 switch (fdsi.ssi_signo) {
                                 case SIGINT:
@@ -1661,7 +1661,7 @@ int main(int argc, char *argv[]) {
 
                 /* device node watch */
                 if (is_inotify)
-                        on_inotify(NULL, fd_inotify, 0, manager);
+                        on_inotify(NULL, manager->fd_inotify, 0, manager);
 
                 /*
                  * This needs to be after the inotify handling, to make sure,
@@ -1669,21 +1669,15 @@ int main(int argc, char *argv[]) {
                  * "change" events by the inotify device node watch.
                  */
                 if (is_ctrl)
-                        on_ctrl_msg(NULL, fd_ctrl, 0, manager);
+                        on_ctrl_msg(NULL, manager->fd_ctrl, 0, manager);
         }
 
 exit:
-        udev_ctrl_cleanup(manager->ctrl);
+        if (manager)
+                udev_ctrl_cleanup(manager->ctrl);
 exit_daemonize:
-        if (fd_ep >= 0)
-                close(fd_ep);
-        udev_builtin_exit(manager->udev);
-        if (fd_signal >= 0)
-                close(fd_signal);
-        if (worker_watch[READ_END] >= 0)
-                close(worker_watch[READ_END]);
-        if (worker_watch[WRITE_END] >= 0)
-                close(worker_watch[WRITE_END]);
+        if (manager)
+                udev_builtin_exit(manager->udev);
         mac_selinux_finish();
         log_close();
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;



More information about the systemd-commits mailing list