]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/udev/udevd.c
udev: open control and netlink sockets before daemonization
[thirdparty/systemd.git] / src / udev / udevd.c
index 024fa97ad08d647353888b467d65683d5416eac1..697506feaf55dd5a826a434e42215cf393ac3bb8 100644 (file)
@@ -31,6 +31,7 @@
 #include "sd-event.h"
 
 #include "alloc-util.h"
+#include "build.h"
 #include "cgroup-util.h"
 #include "cpu-set-util.h"
 #include "dev-setup.h"
@@ -81,7 +82,7 @@ typedef struct Manager {
         const char *cgroup;
         pid_t pid; /* the process that originally allocated the manager object */
 
-        struct udev_rules *rules;
+        UdevRules *rules;
         Hashmap *properties;
 
         sd_netlink *rtnl;
@@ -394,7 +395,7 @@ static int worker_lock_block_device(sd_device *dev, int *ret_fd) {
 }
 
 static int worker_process_device(Manager *manager, sd_device *dev) {
-        _cleanup_(udev_event_freep) struct udev_event *udev_event = NULL;
+        _cleanup_(udev_event_freep) UdevEvent *udev_event = NULL;
         _cleanup_close_ int fd_lock = -1;
         const char *seqnum;
         int r;
@@ -464,7 +465,7 @@ static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *
 static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device *first_device) {
         _cleanup_(sd_device_unrefp) sd_device *dev = first_device;
         _cleanup_(manager_freep) Manager *manager = _manager;
-        int r, ret;
+        int r;
 
         assert(manager);
         assert(monitor);
@@ -507,11 +508,7 @@ static int worker_main(Manager *_manager, sd_device_monitor *monitor, sd_device
         if (r < 0)
                 return log_error_errno(r, "Event loop failed: %m");
 
-        r = sd_event_get_exit_code(manager->event, &ret);
-        if (r < 0)
-                return log_error_errno(r, "Failed to get exit code: %m");
-
-        return ret;
+        return 0;
 }
 
 static int worker_spawn(Manager *manager, struct event *event) {
@@ -534,7 +531,7 @@ static int worker_spawn(Manager *manager, struct event *event) {
         if (r < 0)
                 return log_error_errno(r, "Worker: Failed to enable receiving of device: %m");
 
-        r = safe_fork("(worker)", FORK_DEATHSIG, &pid);
+        r = safe_fork(NULL, FORK_DEATHSIG, &pid);
         if (r < 0) {
                 event->state = EVENT_QUEUED;
                 return log_error_errno(r, "Failed to fork() worker: %m");
@@ -890,9 +887,11 @@ static void event_queue_start(Manager *manager) {
         udev_builtin_init();
 
         if (!manager->rules) {
-                manager->rules = udev_rules_new(arg_resolve_name_timing);
-                if (!manager->rules)
+                r = udev_rules_new(&manager->rules, arg_resolve_name_timing);
+                if (r < 0) {
+                        log_warning_errno(r, "Failed to read udev rules: %m");
                         return;
+                }
         }
 
         LIST_FOREACH(event, event, manager->events) {
@@ -1577,7 +1576,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case 'h':
                         return help();
                 case 'V':
-                        printf("%s\n", PACKAGE_VERSION);
+                        printf("%s\n", GIT_VERSION);
                         return 0;
                 case '?':
                         return -EINVAL;
@@ -1592,7 +1591,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cgroup) {
         _cleanup_(manager_freep) Manager *manager = NULL;
-        int r, fd_worker;
+        int r;
 
         assert(ret);
 
@@ -1606,25 +1605,13 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
                 .cgroup = cgroup,
         };
 
-        udev_builtin_init();
-
-        manager->rules = udev_rules_new(arg_resolve_name_timing);
-        if (!manager->rules)
-                return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to read udev rules");
-
         manager->ctrl = udev_ctrl_new_from_fd(fd_ctrl);
         if (!manager->ctrl)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize udev control socket");
 
-        if (fd_ctrl < 0) {
-                r = udev_ctrl_enable_receiving(manager->ctrl);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to bind udev control socket: %m");
-        }
-
-        fd_ctrl = udev_ctrl_get_fd(manager->ctrl);
-        if (fd_ctrl < 0)
-                return log_error_errno(fd_ctrl, "Failed to get udev control socket fd: %m");
+        r = udev_ctrl_enable_receiving(manager->ctrl);
+        if (r < 0)
+                return log_error_errno(r, "Failed to bind udev control socket: %m");
 
         r = device_monitor_new_full(&manager->monitor, MONITOR_GROUP_KERNEL, fd_uevent);
         if (r < 0)
@@ -1632,6 +1619,18 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
 
         (void) sd_device_monitor_set_receive_buffer_size(manager->monitor, 128 * 1024 * 1024);
 
+        r = device_monitor_enable_receiving(manager->monitor);
+        if (r < 0)
+                return log_error_errno(r, "Failed to bind netlink socket: %m");
+
+        *ret = TAKE_PTR(manager);
+
+        return 0;
+}
+
+static int main_loop(Manager *manager) {
+        int fd_worker, fd_ctrl, r;
+
         /* unnamed socket from workers to the main daemon */
         r = socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
         if (r < 0)
@@ -1677,6 +1676,10 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
         if (r < 0)
                 return log_error_errno(r, "Failed to create watchdog event source: %m");
 
+        fd_ctrl = udev_ctrl_get_fd(manager->ctrl);
+        if (fd_ctrl < 0)
+                return log_error_errno(fd_ctrl, "Failed to get udev control socket fd: %m");
+
         r = sd_event_add_io(manager->event, &manager->ctrl_event, fd_ctrl, EPOLLIN, on_ctrl_msg, manager);
         if (r < 0)
                 return log_error_errno(r, "Failed to create udev control event source: %m");
@@ -1711,20 +1714,11 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
         if (r < 0)
                 return log_error_errno(r, "Failed to create post event source: %m");
 
-        *ret = TAKE_PTR(manager);
-
-        return 0;
-}
-
-static int main_loop(int fd_ctrl, int fd_uevent, const char *cgroup) {
-        _cleanup_(manager_freep) Manager *manager = NULL;
-        int r;
+        udev_builtin_init();
 
-        r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup);
-        if (r < 0) {
-                r = log_error_errno(r, "Failed to allocate manager object: %m");
-                goto exit;
-        }
+        r = udev_rules_new(&manager->rules, arg_resolve_name_timing);
+        if (!manager->rules)
+                return log_error_errno(r, "Failed to read udev rules: %m");
 
         r = udev_rules_apply_static_dev_perms(manager->rules);
         if (r < 0)
@@ -1735,24 +1729,18 @@ static int main_loop(int fd_ctrl, int fd_uevent, const char *cgroup) {
                           "STATUS=Processing with %u children at max", arg_children_max);
 
         r = sd_event_loop(manager->event);
-        if (r < 0) {
+        if (r < 0)
                 log_error_errno(r, "Event loop failed: %m");
-                goto exit;
-        }
 
-        sd_event_get_exit_code(manager->event, &r);
-
-exit:
         sd_notify(false,
                   "STOPPING=1\n"
                   "STATUS=Shutting down...");
-        if (manager)
-                udev_ctrl_cleanup(manager->ctrl);
         return r;
 }
 
 static int run(int argc, char *argv[]) {
         _cleanup_free_ char *cgroup = NULL;
+        _cleanup_(manager_freep) Manager *manager = NULL;
         int fd_ctrl = -1, fd_uevent = -1;
         int r;
 
@@ -1829,10 +1817,14 @@ static int run(int argc, char *argv[]) {
         if (r < 0)
                 return log_error_errno(r, "Failed to listen on fds: %m");
 
+        r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup);
+        if (r < 0)
+                return log_error_errno(r, "Failed to create manager: %m");
+
         if (arg_daemonize) {
                 pid_t pid;
 
-                log_info("starting version " PACKAGE_VERSION);
+                log_info("Starting version " GIT_VERSION);
 
                 /* connect /dev/null to stdin, stdout, stderr */
                 if (log_get_max_level() < LOG_DEBUG) {
@@ -1856,7 +1848,10 @@ static int run(int argc, char *argv[]) {
                         log_debug_errno(r, "Failed to adjust OOM score, ignoring: %m");
         }
 
-        return main_loop(fd_ctrl, fd_uevent, cgroup);
+        r = main_loop(manager);
+        /* FIXME: move this into manager_free() */
+        udev_ctrl_cleanup(manager->ctrl);
+        return r;
 }
 
 DEFINE_MAIN_FUNCTION(run);