chiark / gitweb /
do not remove static nodes on module unload
[elogind.git] / udev / udevd.c
index be4b071ebb0fcd8bce27652f61917d08c3abdb26..f1a31e7afbb4c767e250cf6f0dd120bf33a28c58 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);
@@ -365,9 +364,6 @@ static void worker_new(struct event *event)
                                                switch (fdsi.ssi_signo) {
                                                case SIGTERM:
                                                        goto out;
-                                               case SIGALRM:
-                                                       rc = EXIT_FAILURE;
-                                                       goto out;
                                                }
                                        }
                                }
@@ -893,10 +889,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;
 
@@ -1408,6 +1405,13 @@ int main(int argc, char *argv[])
 
        udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024);
 
+       /* create queue file before signalling 'ready', to make sure we block 'settle' */
+       udev_queue_export = udev_queue_export_new(udev);
+       if (udev_queue_export == NULL) {
+               err(udev, "error creating queue file\n");
+               goto exit;
+       }
+
        if (daemonize) {
                pid_t pid;
                int fd;
@@ -1421,8 +1425,8 @@ int main(int argc, char *argv[])
                        rc = 4;
                        goto exit;
                default:
-                       rc = 0;
-                       goto exit;
+                       rc = EXIT_SUCCESS;
+                       goto exit_keep_queue;
                }
 
                setsid();
@@ -1521,12 +1525,6 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
-       udev_queue_export = udev_queue_export_new(udev);
-       if (udev_queue_export == NULL) {
-               err(udev, "error creating queue file\n");
-               goto exit;
-       }
-
        memset(&ep_ctrl, 0, sizeof(struct epoll_event));
        ep_ctrl.events = EPOLLIN;
        ep_ctrl.data.fd = fd_ctrl;
@@ -1577,8 +1575,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];
@@ -1609,12 +1607,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 {
@@ -1662,7 +1660,7 @@ int main(int argc, char *argv[])
                }
 
                /* 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) {
@@ -1708,9 +1706,10 @@ int main(int argc, char *argv[])
                }
        }
 
-       udev_queue_export_cleanup(udev_queue_export);
-       rc = 0;
+       rc = EXIT_SUCCESS;
 exit:
+       udev_queue_export_cleanup(udev_queue_export);
+exit_keep_queue:
        if (fd_ep >= 0)
                close(fd_ep);
        worker_list_cleanup(udev);