chiark / gitweb /
udevd: print error if worker dies unexpectedly
[elogind.git] / udev / udevd.c
index c0852022e246dae89f7bcc21aa728ffd1f1cb543..e7a0c9840aba4b23e71b0e36877c78bcf3bbdb6b 100644 (file)
@@ -159,6 +159,7 @@ static void event_queue_delete(struct event *event)
        else
                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);
        free(event);
 }
@@ -195,6 +196,7 @@ static void worker_new(struct event *event)
        /* allow the main daemon netlink address to send devices to the worker */
        udev_monitor_allow_unicast_sender(worker_monitor, monitor);
        udev_monitor_enable_receiving(worker_monitor);
+       util_set_fd_cloexec(udev_monitor_get_fd(worker_monitor));
 
        worker = calloc(1, sizeof(struct worker));
        if (worker == NULL)
@@ -207,6 +209,7 @@ static void worker_new(struct event *event)
                struct udev_device *dev;
 
                udev_queue_export_unref(udev_queue_export);
+               udev_monitor_unref(monitor);
                udev_ctrl_unref(udev_ctrl);
                close(pfd[FD_SIGNAL].fd);
                close(worker_watch[READ_END]);
@@ -269,7 +272,7 @@ static void worker_new(struct event *event)
                        /* send processed event back to libudev listeners */
                        udev_monitor_send_device(worker_monitor, NULL, dev);
 
-                       info(event->udev, "seq %llu finished with %i\n", udev_device_get_seqnum(dev), err);
+                       info(event->udev, "seq %llu processed with %i\n", udev_device_get_seqnum(dev), err);
                        udev_device_unref(dev);
                        udev_event_unref(udev_event);
 
@@ -615,7 +618,7 @@ static int handle_inotify(struct udev *udev)
 
        buf = malloc(nbytes);
        if (buf == NULL) {
-               err(udev, "error getting buffer for inotify, disable watching\n");
+               err(udev, "error getting buffer for inotify\n");
                return -1;
        }
 
@@ -657,7 +660,7 @@ static int handle_inotify(struct udev *udev)
        return 0;
 }
 
-static void handle_signal(int signo)
+static void handle_signal(struct udev *udev, int signo)
 {
        switch (signo) {
        case SIGINT:
@@ -667,9 +670,10 @@ static void handle_signal(int signo)
        case SIGCHLD:
                while (1) {
                        pid_t pid;
+                       int status;
                        struct udev_list_node *loop, *tmp;
 
-                       pid = waitpid(-1, NULL, WNOHANG);
+                       pid = waitpid(-1, &status, WNOHANG);
                        if (pid <= 0)
                                break;
 
@@ -681,7 +685,16 @@ static void handle_signal(int signo)
 
                                /* fail event, if worker died unexpectedly */
                                if (worker->event != NULL) {
-                                       worker->event->exitcode = 127;
+                                       int exitcode;
+
+                                       if (WIFEXITED(status))
+                                               exitcode = WEXITSTATUS(status);
+                                       else if (WIFSIGNALED(status))
+                                               exitcode = WTERMSIG(status) + 128;
+                                       else
+                                               exitcode = 0;
+                                       worker->event->exitcode = exitcode;
+                                       err(udev, "worker [%u] unexpectedly returned with %i\n", pid, exitcode);
                                        event_queue_delete(worker->event);
                                }
 
@@ -885,6 +898,7 @@ int main(int argc, char *argv[])
                goto exit;
        }
        pfd[FD_WORKER].fd = worker_watch[READ_END];
+       util_set_fd_cloexec(worker_watch[WRITE_END]);
 
        rules = udev_rules_new(udev, resolve_names);
        if (rules == NULL) {
@@ -935,9 +949,9 @@ int main(int argc, char *argv[])
 
        /* OOM_DISABLE == -17 */
        fd = open("/proc/self/oom_adj", O_RDWR);
-       if (fd < 0)
+       if (fd < 0) {
                err(udev, "error disabling OOM: %m\n");
-       else {
+       else {
                write(fd, "-17", 3);
                close(fd);
        }
@@ -1007,7 +1021,7 @@ int main(int argc, char *argv[])
 
                        size = read(pfd[FD_SIGNAL].fd, &fdsi, sizeof(struct signalfd_siginfo));
                        if (size == sizeof(struct signalfd_siginfo))
-                               handle_signal(fdsi.ssi_signo);
+                               handle_signal(udev, fdsi.ssi_signo);
                }
 
                /* device node and rules directory inotify watch */