]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: open control and netlink sockets before daemonization 11376/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 8 Jan 2019 21:41:16 +0000 (22:41 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 10 Jan 2019 05:09:15 +0000 (14:09 +0900)
c4b69e990f962128cc6975e36e91e9ad838fa2c4 effectively moved the initalization of socket.
Before that commit:
run → listen_fds → udev_ctrl_new → udev_ctrl_new_from_fd → socket()
After:
run → main_loop → manager_new → udev_ctrl_new_from_fd → socket()

The problem is that main_loop was called after daemonization. Move manager_new
out of main_loop and before daemonization.

Fixes #11314 (hopefully ;)).

v2: Yu Watanabe
sd_event is initialized in main_loop().

src/udev/udevd.c

index fe29f5e79a7cabcbe7c0ab63c91feaf1ef064606..697506feaf55dd5a826a434e42215cf393ac3bb8 100644 (file)
@@ -1591,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);
 
@@ -1605,25 +1605,13 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
                 .cgroup = cgroup,
         };
 
-        udev_builtin_init();
-
-        r = udev_rules_new(&manager->rules, arg_resolve_name_timing);
-        if (!manager->rules)
-                return log_error_errno(r, "Failed to read udev rules: %m");
-
         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)
@@ -1631,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)
@@ -1676,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");
@@ -1710,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)
@@ -1740,13 +1735,12 @@ static int main_loop(int fd_ctrl, int fd_uevent, const char *cgroup) {
         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;
 
@@ -1823,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 " GIT_VERSION);
+                log_info("Starting version " GIT_VERSION);
 
                 /* connect /dev/null to stdin, stdout, stderr */
                 if (log_get_max_level() < LOG_DEBUG) {
@@ -1850,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);