]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevd: manager - move a few global variables into the Manager object
authorTom Gundersen <teg@jklm.no>
Tue, 12 May 2015 17:06:33 +0000 (19:06 +0200)
committerTom Gundersen <teg@jklm.no>
Tue, 12 May 2015 17:16:43 +0000 (19:16 +0200)
src/libudev/libudev-private.h
src/udev/udevd.c

index cbe84aa0dd57e0942df62b902c6eb11c2eb2df71..1240ea79ccfa247942eb7493866aa70b0eaef7b5 100644 (file)
@@ -93,7 +93,6 @@ struct udev_list {
         unsigned int entries_max;
         bool unique;
 };
-#define UDEV_LIST(list) struct udev_list_node list = { &(list), &(list) }
 void udev_list_node_init(struct udev_list_node *list);
 int udev_list_node_is_empty(struct udev_list_node *list);
 void udev_list_node_append(struct udev_list_node *new, struct udev_list_node *list);
index a90e4d4bf64fe47d0ead3a35de6b36f9c2e93084..318d769114814ce6d21f90236752993fdc56574b 100644 (file)
@@ -51,7 +51,6 @@
 #include "formats-util.h"
 #include "hashmap.h"
 
-static struct udev_rules *rules;
 static int worker_watch[2] = { -1, -1 };
 static int fd_signal = -1;
 static int fd_ep = -1;
@@ -64,13 +63,14 @@ 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;
-static UDEV_LIST(event_list);
-static char *udev_cgroup;
 
 typedef struct Manager {
         struct udev *udev;
         Hashmap *workers;
+        struct udev_list_node events;
+        char *cgroup;
 
+        struct udev_rules *rules;
         struct udev_list properties;
 
         struct udev_monitor *monitor;
@@ -111,7 +111,7 @@ static inline struct event *node_to_event(struct udev_list_node *node) {
         return container_of(node, struct event, node);
 }
 
-static void event_queue_cleanup(struct udev *udev, enum event_state type);
+static void event_queue_cleanup(Manager *manager, enum event_state type);
 
 enum worker_state {
         WORKER_UNDEF,
@@ -249,7 +249,7 @@ static void worker_spawn(Manager *manager, struct event *event) {
                 event->dev = NULL;
 
                 manager_workers_free(manager);
-                event_queue_cleanup(udev, EVENT_UNDEF);
+                event_queue_cleanup(manager, EVENT_UNDEF);
                 udev_monitor_unref(manager->monitor);
                 udev_ctrl_unref(manager->ctrl);
                 close(fd_signal);
@@ -343,7 +343,7 @@ static void worker_spawn(Manager *manager, struct event *event) {
                         udev_event_execute_rules(udev_event,
                                                  arg_event_timeout_usec, arg_event_timeout_warn_usec,
                                                  &manager->properties,
-                                                 rules,
+                                                 manager->rules,
                                                  &sigmask_orig);
 
                         udev_event_execute_run(udev_event,
@@ -424,7 +424,7 @@ out:
                 safe_close(fd_ep);
                 close(fd_inotify);
                 close(worker_watch[WRITE_END]);
-                udev_rules_unref(rules);
+                udev_rules_unref(manager->rules);
                 udev_builtin_exit(udev);
                 udev_unref(udev);
                 log_close();
@@ -486,9 +486,12 @@ static void event_run(Manager *manager, struct event *event) {
         worker_spawn(manager, event);
 }
 
-static int event_queue_insert(struct udev_device *dev) {
+static int event_queue_insert(Manager *manager, struct udev_device *dev) {
         struct event *event;
 
+        assert(manager);
+        assert(dev);
+
         event = new0(struct event, 1);
         if (event == NULL)
                 return -1;
@@ -509,7 +512,7 @@ static int event_queue_insert(struct udev_device *dev) {
              udev_device_get_action(dev), udev_device_get_subsystem(dev));
 
         event->state = EVENT_QUEUED;
-        udev_list_node_append(&event->node, &event_list);
+        udev_list_node_append(&event->node, &manager->events);
         return 0;
 }
 
@@ -529,12 +532,12 @@ static void manager_kill_workers(Manager *manager) {
 }
 
 /* lookup event for identical, parent, child device */
-static bool is_devpath_busy(struct event *event) {
+static bool is_devpath_busy(Manager *manager, struct event *event) {
         struct udev_list_node *loop;
         size_t common;
 
         /* check if queue contains events we depend on */
-        udev_list_node_foreach(loop, &event_list) {
+        udev_list_node_foreach(loop, &manager->events) {
                 struct event *loop_event = node_to_event(loop);
 
                 /* we already found a later event, earlier can not block us, no need to check again */
@@ -605,24 +608,24 @@ static void event_queue_start(Manager *manager) {
 
         assert(manager);
 
-        udev_list_node_foreach(loop, &event_list) {
+        udev_list_node_foreach(loop, &manager->events) {
                 struct event *event = node_to_event(loop);
 
                 if (event->state != EVENT_QUEUED)
                         continue;
 
                 /* do not start event if parent or child event is still running */
-                if (is_devpath_busy(event))
+                if (is_devpath_busy(manager, event))
                         continue;
 
                 event_run(manager, event);
         }
 }
 
-static void event_queue_cleanup(struct udev *udev, enum event_state match_type) {
+static void event_queue_cleanup(Manager *manager, enum event_state match_type) {
         struct udev_list_node *loop, *tmp;
 
-        udev_list_node_foreach_safe(loop, tmp, &event_list) {
+        udev_list_node_foreach_safe(loop, tmp, &manager->events) {
                 struct event *event = node_to_event(loop);
 
                 if (match_type != EVENT_UNDEF && match_type != event->state)
@@ -708,7 +711,7 @@ static int on_uevent(sd_event_source *s, int fd, uint32_t revents, void *userdat
         dev = udev_monitor_receive_device(manager->monitor);
         if (dev) {
                 udev_device_ensure_usec_initialized(dev, NULL);
-                r = event_queue_insert(dev);
+                r = event_queue_insert(manager, dev);
                 if (r < 0)
                         udev_device_unref(dev);
         }
@@ -716,10 +719,12 @@ static int on_uevent(sd_event_source *s, int fd, uint32_t revents, void *userdat
         return 1;
 }
 
-static void event_queue_update(void) {
+static void event_queue_update(Manager *manager) {
         int r;
 
-        if (!udev_list_node_is_empty(&event_list)) {
+        assert(manager);
+
+        if (!udev_list_node_is_empty(&manager->events)) {
                 r = touch("/run/udev/queue");
                 if (r < 0)
                         log_warning_errno(r, "could not touch /run/udev/queue: %m");
@@ -806,7 +811,7 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd
                 /* tell settle that we are busy or idle, this needs to be before the
                  * PING handling
                  */
-                event_queue_update();
+                event_queue_update(manager);
         }
 
         if (udev_ctrl_get_exit(ctrl_msg) > 0) {
@@ -1219,12 +1224,15 @@ static void manager_free(Manager *manager) {
 
         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);
 }
@@ -1244,6 +1252,13 @@ static int manager_new(Manager **ret) {
         if (!manager->udev)
                 return log_error_errno(errno, "could not allocate udev context: %m");
 
+        manager->rules = udev_rules_new(manager->udev, arg_resolve_names);
+        if (!manager->rules)
+                return log_error_errno(ENOMEM, "error reading rules");
+
+        udev_list_node_init(&manager->events);
+        udev_list_init(manager->udev, &manager->properties, true);
+
         *ret = manager;
         manager = NULL;
 
@@ -1267,10 +1282,6 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
-        r = manager_new(&manager);
-        if (r < 0)
-                goto exit;
-
         r = parse_argv(argc, argv);
         if (r <= 0)
                 goto exit;
@@ -1302,8 +1313,6 @@ int main(int argc, char *argv[]) {
 
         umask(022);
 
-        udev_list_init(manager->udev, &manager->properties, true);
-
         r = mkdir("/run/udev", 0755);
         if (r < 0 && errno != EEXIST) {
                 r = log_error_errno(errno, "could not create /run/udev: %m");
@@ -1312,6 +1321,10 @@ 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;
@@ -1344,8 +1357,8 @@ int main(int argc, char *argv[]) {
                 }
 
                 /* get our own cgroup, we regularly kill everything udev has left behind */
-                if (cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &udev_cgroup) < 0)
-                        udev_cgroup = NULL;
+                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);
@@ -1379,13 +1392,7 @@ int main(int argc, char *argv[]) {
 
         udev_builtin_init(manager->udev);
 
-        rules = udev_rules_new(manager->udev, arg_resolve_names);
-        if (!rules) {
-                r = log_error_errno(ENOMEM, "error reading rules");
-                goto exit;
-        }
-
-        r = udev_rules_apply_static_dev_perms(rules);
+        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");
 
@@ -1421,8 +1428,6 @@ int main(int argc, char *argv[]) {
         }
         log_debug("set children_max to %u", arg_children_max);
 
-        udev_list_node_init(&event_list);
-
         fd_inotify = udev_watch_init(manager->udev);
         if (fd_inotify < 0) {
                 r = log_error_errno(ENOMEM, "error initializing inotify");
@@ -1495,29 +1500,29 @@ int main(int argc, char *argv[]) {
                         }
 
                         /* discard queued events and kill workers */
-                        event_queue_cleanup(manager->udev, EVENT_QUEUED);
+                        event_queue_cleanup(manager, EVENT_QUEUED);
                         manager_kill_workers(manager);
 
                         /* exit after all has cleaned up */
-                        if (udev_list_node_is_empty(&event_list) && hashmap_isempty(manager->workers))
+                        if (udev_list_node_is_empty(&manager->events) && hashmap_isempty(manager->workers))
                                 break;
 
                         /* timeout at exit for workers to finish */
                         timeout = 30 * MSEC_PER_SEC;
-                } else if (udev_list_node_is_empty(&event_list) && hashmap_isempty(manager->workers)) {
+                } else if (udev_list_node_is_empty(&manager->events) && hashmap_isempty(manager->workers)) {
                         /* we are idle */
                         timeout = -1;
 
                         /* cleanup possible left-over processes in our cgroup */
-                        if (udev_cgroup)
-                                cg_kill(SYSTEMD_CGROUP_CONTROLLER, udev_cgroup, SIGKILL, false, true, NULL);
+                        if (manager->cgroup)
+                                cg_kill(SYSTEMD_CGROUP_CONTROLLER, manager->cgroup, SIGKILL, false, true, NULL);
                 } else {
                         /* kill idle or hanging workers */
                         timeout = 3 * MSEC_PER_SEC;
                 }
 
                 /* tell settle that we are busy or idle */
-                event_queue_update();
+                event_queue_update(manager);
 
                 fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
                 if (fdcount < 0)
@@ -1534,7 +1539,7 @@ int main(int argc, char *argv[]) {
                         }
 
                         /* kill idle workers */
-                        if (udev_list_node_is_empty(&event_list)) {
+                        if (udev_list_node_is_empty(&manager->events)) {
                                 log_debug("cleanup idle workers");
                                 manager_kill_workers(manager);
                         }
@@ -1583,7 +1588,7 @@ int main(int argc, char *argv[]) {
 
                 /* check for changed config, every 3 seconds at most */
                 if ((now(CLOCK_MONOTONIC) - last_usec) > 3 * USEC_PER_SEC) {
-                        if (udev_rules_check_timestamp(rules))
+                        if (udev_rules_check_timestamp(manager->rules))
                                 manager->reload = true;
                         if (udev_builtin_validate(manager->udev))
                                 manager->reload = true;
@@ -1594,7 +1599,7 @@ int main(int argc, char *argv[]) {
                 /* reload requested, HUP signal received, rules changed, builtin changed */
                 if (manager->reload) {
                         manager_kill_workers(manager);
-                        rules = udev_rules_unref(rules);
+                        manager->rules = udev_rules_unref(manager->rules);
                         udev_builtin_exit(manager->udev);
                         manager->reload = false;
                 }
@@ -1608,11 +1613,11 @@ int main(int argc, char *argv[]) {
                         on_uevent(NULL, fd_netlink, 0, manager);
 
                 /* start new events */
-                if (!udev_list_node_is_empty(&event_list) && !manager->exit && !manager->stop_exec_queue) {
+                if (!udev_list_node_is_empty(&manager->events) && !manager->exit && !manager->stop_exec_queue) {
                         udev_builtin_init(manager->udev);
-                        if (rules == NULL)
-                                rules = udev_rules_new(manager->udev, arg_resolve_names);
-                        if (rules != NULL)
+                        if (!manager->rules)
+                                manager->rules = udev_rules_new(manager->udev, arg_resolve_names);
+                        if (manager->rules)
                                 event_queue_start(manager);
                 }
 
@@ -1660,8 +1665,6 @@ exit:
 exit_daemonize:
         if (fd_ep >= 0)
                 close(fd_ep);
-        event_queue_cleanup(manager->udev, EVENT_UNDEF);
-        udev_rules_unref(rules);
         udev_builtin_exit(manager->udev);
         if (fd_signal >= 0)
                 close(fd_signal);