X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev%2Fudevd.c;h=d9de26ea6cc705e8912bebc897ae3451f8d021fc;hb=116254097ad3c07d9f7ed06042dbec7ba4f0f4fd;hp=cfc091b699067e7d2e47214880b85ef9feb99d2f;hpb=80be8c48c59708c52993ceddeedef8c2ed417016;p=elogind.git diff --git a/udev/udevd.c b/udev/udevd.c index cfc091b69..d9de26ea6 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -1,6 +1,8 @@ /* * Copyright (C) 2004-2008 Kay Sievers * Copyright (C) 2004 Chris Friesen + * Copyright (C) 2009 Canonical Ltd. + * Copyright (C) 2009 Scott James Remnant * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -69,6 +71,7 @@ static volatile int sigchilds_waiting; static volatile int udev_exit; static volatile int reload_config; static volatile int signal_received; +static volatile pid_t settle_pid; static int run_exec_q; static int stop_exec_q; static int max_childs; @@ -192,7 +195,6 @@ static void event_fork(struct udev_event *event) switch (pid) { case 0: /* child */ - udev_monitor_unref(kernel_monitor); udev_ctrl_unref(udev_ctrl); logging_close(); logging_init("udevd-event"); @@ -215,17 +217,6 @@ static void event_fork(struct udev_event *event) /* set timeout to prevent hanging processes */ alarm(UDEV_EVENT_TIMEOUT); - /* clear any existing udev watch on the node */ - if (inotify_fd != -1) { - struct udev_device *dev_old; - - dev_old = udev_device_new_from_syspath(event->udev, udev_device_get_syspath(event->dev)); - if (dev_old != NULL) { - udev_watch_end(event->udev, dev_old); - udev_device_unref(dev_old); - } - } - /* apply rules, create node, symlinks */ err = udev_event_execute_rules(event, rules); @@ -238,9 +229,13 @@ static void event_fork(struct udev_event *event) udev_event_execute_run(event); /* apply/restore inotify watch */ - if (err == 0 && event->inotify_watch && - strcmp(udev_device_get_action(event->dev), "remove") != 0) + if (err == 0 && event->inotify_watch) { udev_watch_begin(event->udev, event->dev); + udev_device_update_db(event->dev); + } + + /* send processed event back to the kernel netlink socket */ + udev_monitor_send_device(kernel_monitor, event->dev); info(event->udev, "seq %llu exit with %i\n", udev_device_get_seqnum(event->dev), err); logging_close(); @@ -523,6 +518,11 @@ static void handle_ctrl_msg(struct udev_ctrl *uctrl) info(udev, "udevd message (SET_MAX_CHILDS) received, max_childs=%i\n", i); max_childs = i; } + + settle_pid = udev_ctrl_get_settle(ctrl_msg); + if (settle_pid > 0) { + info(udev, "udevd message (SETTLE) received\n"); + } udev_ctrl_msg_unref(ctrl_msg); } @@ -813,7 +813,7 @@ int main(int argc, char *argv[]) goto exit; } - kernel_monitor = udev_monitor_new_from_netlink(udev); + kernel_monitor = udev_monitor_new_from_netlink(udev, UDEV_MONITOR_KERNEL); if (kernel_monitor == NULL || udev_monitor_enable_receiving(kernel_monitor) < 0) { fprintf(stderr, "error initializing netlink socket\n"); err(udev, "error initializing netlink socket\n"); @@ -1033,6 +1033,11 @@ handle_signals: if (!stop_exec_q) event_queue_manager(udev); } + + if (settle_pid > 0) { + kill(settle_pid, SIGUSR1); + settle_pid = 0; + } } cleanup_queue_dir(udev); rc = 0;