chiark / gitweb /
add builtin load/unload initializers
[elogind.git] / udev / udevd.c
index e7384e19a2431b1007680bc10e4290647dfcc9a1..d1f7cd8909f26b782f52e7529dbce4a90b72feff 100644 (file)
@@ -55,13 +55,12 @@ static void log_fn(struct udev *udev, int priority,
 {
        if (debug) {
                char buf[1024];
-               struct timeval tv;
-               struct timezone tz;
+               struct timespec ts;
 
                vsnprintf(buf, sizeof(buf), format, args);
-               gettimeofday(&tv, &tz);
-               fprintf(stderr, "%llu.%06u [%u] %s: %s",
-                       (unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec,
+               clock_gettime(CLOCK_MONOTONIC, &ts);
+               fprintf(stderr, "[%llu.%06u] [%u] %s: %s",
+                       (unsigned long long) ts.tv_sec, (unsigned int) ts.tv_nsec/1000,
                        (int) getpid(), fn, buf);
        } else {
                vsyslog(priority, format, args);
@@ -156,11 +155,7 @@ static void event_queue_delete(struct event *event, bool export)
        udev_list_node_remove(&event->node);
 
        if (export) {
-               /* mark as failed, if "add" event returns non-zero */
-               if (event->exitcode != 0 && strcmp(udev_device_get_action(event->dev), "remove") != 0)
-                       udev_queue_export_device_failed(udev_queue_export, event->dev);
-               else
-                       udev_queue_export_device_finished(udev_queue_export, event->dev);
+               udev_queue_export_device_finished(udev_queue_export, event->dev);
                info(event->udev, "seq %llu done with %i\n", udev_device_get_seqnum(event->dev), event->exitcode);
        }
        udev_device_unref(event->dev);
@@ -285,7 +280,6 @@ static void worker_new(struct event *event)
                for (;;) {
                        struct udev_event *udev_event;
                        struct worker_message msg;
-                       int failed = 0;
                        int err;
 
                        info(udev, "seq %llu running\n", udev_device_get_seqnum(dev));
@@ -305,7 +299,7 @@ static void worker_new(struct event *event)
                        err = udev_event_execute_rules(udev_event, rules, &sigmask_orig);
 
                        if (err == 0)
-                               failed = udev_event_execute_run(udev_event, &sigmask_orig);
+                               udev_event_execute_run(udev_event, &sigmask_orig);
 
                        /* apply/restore inotify watch */
                        if (err == 0 && udev_event->inotify_watch) {
@@ -320,8 +314,6 @@ static void worker_new(struct event *event)
                        memset(&msg, 0, sizeof(struct worker_message));
                        if (err != 0)
                                msg.exitcode = err;
-                       else if (failed != 0)
-                               msg.exitcode = failed;
                        msg.pid = getpid();
                        send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0);
 
@@ -355,6 +347,7 @@ static void worker_new(struct event *event)
                                for (i = 0; i < fdcount; i++) {
                                        if (ev[i].data.fd == fd_monitor && ev[i].events & EPOLLIN) {
                                                dev = udev_monitor_receive_device(worker_monitor);
+                                               break;
                                        } else if (ev[i].data.fd == fd_signal && ev[i].events & EPOLLIN) {
                                                struct signalfd_siginfo fdsi;
                                                ssize_t size;
@@ -890,10 +883,11 @@ static void static_dev_create_from_modules(struct udev *udev)
                if (sscanf(devno, "%c%u:%u", &type, &maj, &min) != 3)
                        continue;
 
+               /* set sticky bit, so we do not remove the node on module unload */
                if (type == 'c')
-                       mode = 0600 | S_IFCHR;
+                       mode = 01600|S_IFCHR;
                else if (type == 'b')
-                       mode = 0600 | S_IFBLK;
+                       mode = 01600|S_IFBLK;
                else
                        continue;
 
@@ -1355,7 +1349,7 @@ int main(int argc, char *argv[])
 
        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);
+               udev_ctrl = udev_ctrl_new_from_fd(udev, fd_ctrl);
                if (udev_ctrl == NULL) {
                        err(udev, "error taking over udev control socket");
                        rc = 1;
@@ -1370,7 +1364,7 @@ int main(int argc, char *argv[])
                }
        } else {
                /* open control and netlink socket */
-               udev_ctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
+               udev_ctrl = udev_ctrl_new(udev);
                if (udev_ctrl == NULL) {
                        fprintf(stderr, "error initializing udev control socket");
                        err(udev, "error initializing udev control socket");
@@ -1426,7 +1420,7 @@ int main(int argc, char *argv[])
                        goto exit;
                default:
                        rc = EXIT_SUCCESS;
-                       goto exit_keep_queue;
+                       goto exit_daemonize;
                }
 
                setsid();
@@ -1519,6 +1513,8 @@ int main(int argc, char *argv[])
        }
        fd_worker = worker_watch[READ_END];
 
+       udev_builtin_load(udev);
+
        rules = udev_rules_new(udev, resolve_names);
        if (rules == NULL) {
                err(udev, "error reading rules\n");
@@ -1575,8 +1571,8 @@ int main(int argc, char *argv[])
 
        udev_rules_apply_static_dev_perms(rules);
 
-       udev_list_init(&event_list);
-       udev_list_init(&worker_list);
+       udev_list_node_init(&event_list);
+       udev_list_node_init(&worker_list);
 
        for (;;) {
                struct epoll_event ev[8];
@@ -1607,12 +1603,12 @@ int main(int argc, char *argv[])
                        worker_kill(udev, 0);
 
                        /* exit after all has cleaned up */
-                       if (udev_list_is_empty(&event_list) && udev_list_is_empty(&worker_list))
+                       if (udev_list_node_is_empty(&event_list) && udev_list_node_is_empty(&worker_list))
                                break;
 
                        /* timeout at exit for workers to finish */
                        timeout = 60 * 1000;
-               } else if (udev_list_is_empty(&event_list) && children > 2) {
+               } else if (udev_list_node_is_empty(&event_list) && children > 2) {
                        /* set timeout to kill idle workers */
                        timeout = 3 * 1000;
                } else {
@@ -1654,13 +1650,15 @@ int main(int argc, char *argv[])
                        struct udev_device *dev;
 
                        dev = udev_monitor_receive_device(monitor);
-                       if (dev != NULL)
+                       if (dev != NULL) {
+                               udev_device_set_usec_initialized(dev, now_usec());
                                if (event_queue_insert(dev) < 0)
                                        udev_device_unref(dev);
+                       }
                }
 
                /* start new events */
-               if (!udev_list_is_empty(&event_list) && !udev_exit && !stop_exec_queue)
+               if (!udev_list_node_is_empty(&event_list) && !udev_exit && !stop_exec_queue)
                        event_queue_start(udev);
 
                if (is_signal) {
@@ -1709,12 +1707,14 @@ int main(int argc, char *argv[])
        rc = EXIT_SUCCESS;
 exit:
        udev_queue_export_cleanup(udev_queue_export);
-exit_keep_queue:
+       udev_ctrl_cleanup(udev_ctrl);
+exit_daemonize:
        if (fd_ep >= 0)
                close(fd_ep);
        worker_list_cleanup(udev);
        event_queue_cleanup(udev, EVENT_UNDEF);
        udev_rules_unref(rules);
+       udev_builtin_unload(udev);
        if (fd_signal >= 0)
                close(fd_signal);
        if (worker_watch[READ_END] >= 0)