From: kay.sievers@vrfy.org Date: Wed, 28 Jan 2004 02:57:36 +0000 (-0800) Subject: [PATCH] udevd - next round of fixes X-Git-Tag: 016~19 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=35b7d88c0dab4c1104c127ddd644db22307949c9;hp=34ee4dd4553160b082b6bc44a6e5be74787cd085 [PATCH] udevd - next round of fixes Here is the next round. We have three queues now. All incoming messages are queued in msg_list and if nothing is missing we move it to the running_list and exec in the background. If the exec comes back, it removes the message from the running_list and frees the message. Before we exec, we check the running_list if there is a udev running on the same device path. If yes, we move the message to the delay_list. If the former exec comes back, we move the message to the running_list and exec it. The very first event is delayed now to catch possible earlier sequences, every following event is executed without delay if no sequence is missing. The daemon doesn't exit by itself any longer, cause we don't want to delay every first exec. I've put a $(PWD) for now in the Makefile for testing this beast. Only the local binaries are executed, not the /sbin/udev. We can change it if we are ready for real testing. And SIGKILL can't be cought, so I removed it from the handler :) 06:58:36 sig_handler: caught signal 15 06:58:36 main: using ipc queue 0x2d548 06:58:37 message is still in the ipc queue, starting daemon... 06:58:37 work: received sequence 3, expected sequence 0 06:58:37 msg_dump_queue: sequence 3 in queue 06:58:37 set_timeout: set timeout in 1 seconds 06:58:37 main: using ipc queue 0x2d548 06:58:37 main: using ipc queue 0x2d548 06:58:37 work: received sequence 1, expected sequence 1 06:58:37 msg_dump_queue: sequence 1 in queue 06:58:37 msg_dump_queue: sequence 3 in queue 06:58:37 msg_dump: sequence 1, 'add', '/block/sda', 'block' 06:58:37 msg_exec: child [8038] created 06:58:37 running_moveto_queue: move sequence 1 [8038] to running queue '/block/sda' 06:58:37 set_timeout: set timeout in 5 seconds 06:58:37 work: received sequence 2, expected sequence 2 06:58:37 msg_dump_queue: sequence 2 in queue 06:58:37 msg_dump_queue: sequence 3 in queue 06:58:37 msg_dump: sequence 2, 'add', '/block/sdb', 'block' 06:58:37 msg_exec: child [8039] created 06:58:37 running_moveto_queue: move sequence 2 [8039] to running queue '/block/sdb' 06:58:37 msg_dump: sequence 3, 'add', '/block/sdc', 'block' 06:58:37 msg_exec: child [8040] created 06:58:37 running_moveto_queue: move sequence 3 [8040] to running queue '/block/sdc' 06:58:37 main: using ipc queue 0x2d548 06:58:37 main: using ipc queue 0x2d548 06:58:37 work: received sequence 4, expected sequence 4 06:58:37 msg_dump_queue: sequence 4 in queue 06:58:37 msg_dump: sequence 4, 'remove', '/block/sdc', 'block' 06:58:37 msg_exec: delay exec of sequence 4, [8040] already working on '/block/sdc' 06:58:37 delayed_moveto_queue: move event to delayed queue '/block/sdc' 06:58:37 msg_exec: child [8043] created 06:58:37 running_moveto_queue: move sequence 4 [8043] to running queue '/block/sdc' 06:58:37 work: received sequence 5, expected sequence 5 06:58:37 msg_dump_queue: sequence 5 in queue 06:58:37 msg_dump: sequence 5, 'remove', '/block/sdb', 'block' 06:58:37 msg_exec: delay exec of sequence 5, [8039] already working on '/block/sdb' 06:58:37 delayed_moveto_queue: move event to delayed queue '/block/sdb' 06:58:37 msg_exec: child [8044] created 06:58:37 running_moveto_queue: move sequence 5 [8044] to running queue '/block/sdb' 06:58:37 main: using ipc queue 0x2d548 06:58:37 main: using ipc queue 0x2d548 06:58:37 work: received sequence 8, expected sequence 6 06:58:37 msg_dump_queue: sequence 8 in queue 06:58:37 set_timeout: set timeout in 5 seconds 06:58:37 work: received sequence 6, expected sequence 6 06:58:37 msg_dump_queue: sequence 6 in queue 06:58:37 msg_dump_queue: sequence 8 in queue 06:58:37 msg_dump: sequence 6, 'remove', '/block/sda', 'block' 06:58:37 msg_exec: delay exec of sequence 6, [8038] already working on '/block/sda' 06:58:37 delayed_moveto_queue: move event to delayed queue '/block/sda' 06:58:37 msg_exec: child [8047] created 06:58:37 running_moveto_queue: move sequence 6 [8047] to running queue '/block/sda' 06:58:37 set_timeout: set timeout in 5 seconds 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8038 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8039 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8040 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8043 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8044 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8047 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:39 main: using ipc queue 0x2d548 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 9, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 work: received sequence 11, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 10, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 13, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 msg_dump_queue: sequence 13 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 14, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 msg_dump_queue: sequence 13 in queue 06:58:39 msg_dump_queue: sequence 14 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 15, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 msg_dump_queue: sequence 13 in queue 06:58:39 msg_dump_queue: sequence 14 in queue 06:58:39 msg_dump_queue: sequence 15 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:41 main: using ipc queue 0x2d548 06:58:41 work: received sequence 12, expected sequence 7 06:58:41 msg_dump_queue: sequence 8 in queue 06:58:41 msg_dump_queue: sequence 9 in queue 06:58:41 msg_dump_queue: sequence 10 in queue 06:58:41 msg_dump_queue: sequence 11 in queue 06:58:41 msg_dump_queue: sequence 12 in queue 06:58:41 msg_dump_queue: sequence 13 in queue 06:58:41 msg_dump_queue: sequence 14 in queue 06:58:41 msg_dump_queue: sequence 15 in queue 06:58:41 set_timeout: set timeout in 1 seconds 06:58:42 sig_handler: caught signal 14 06:58:42 sig_handler: event timeout reached 06:58:42 event 8, age 5 seconds, skip event 7-7 06:58:42 msg_dump: sequence 8, 'add', '/block/sdb', 'block' 06:58:42 msg_exec: child [8057] created 06:58:42 running_moveto_queue: move sequence 8 [8057] to running queue '/block/sdb' 06:58:42 msg_dump: sequence 9, 'add', '/block/sdc', 'block' 06:58:42 msg_exec: child [8058] created 06:58:42 running_moveto_queue: move sequence 9 [8058] to running queue '/block/sdc' 06:58:42 msg_dump: sequence 10, 'remove', '/block/sdc', 'block' 06:58:42 msg_exec: delay exec of sequence 10, [8058] already working on '/block/sdc' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdc' 06:58:42 msg_exec: child [8059] created 06:58:42 running_moveto_queue: move sequence 10 [8059] to running queue '/block/sdc' 06:58:42 msg_dump: sequence 11, 'remove', '/block/sdb', 'block' 06:58:42 msg_exec: delay exec of sequence 11, [8057] already working on '/block/sdb' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdb' 06:58:42 msg_exec: child [8060] created 06:58:42 running_moveto_queue: move sequence 11 [8060] to running queue '/block/sdb' 06:58:42 msg_dump: sequence 12, 'remove', '/block/sda', 'block' 06:58:42 msg_exec: child [8061] created 06:58:42 running_moveto_queue: move sequence 12 [8061] to running queue '/block/sda' 06:58:42 msg_dump: sequence 13, 'add', '/block/sda', 'block' 06:58:42 msg_exec: delay exec of sequence 13, [8061] already working on '/block/sda' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sda' 06:58:42 msg_exec: child [8062] created 06:58:42 running_moveto_queue: move sequence 13 [8062] to running queue '/block/sda' 06:58:42 msg_dump: sequence 14, 'add', '/block/sdb', 'block' 06:58:42 msg_exec: delay exec of sequence 14, [8057] already working on '/block/sdb' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdb' 06:58:42 msg_exec: child [8063] created 06:58:42 running_moveto_queue: move sequence 14 [8063] to running queue '/block/sdb' 06:58:42 msg_dump: sequence 15, 'add', '/block/sdc', 'block' 06:58:42 msg_exec: delay exec of sequence 15, [8058] already working on '/block/sdc' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdc' 06:58:42 msg_exec: child [8064] created 06:58:42 running_moveto_queue: move sequence 15 [8064] to running queue '/block/sdc' 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8057 06:58:43 sig_handler: exec finished, pid 8058 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8059 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8060 06:58:43 sig_handler: exec finished, pid 8061 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8062 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8063 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8064 --- diff --git a/Makefile b/Makefile index c68fd3731..8af6ecf63 100644 --- a/Makefile +++ b/Makefile @@ -232,6 +232,8 @@ udev_version.h: @echo \#define UDEV_CONFIG_FILE \"$(configdir)\udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ + @echo \#define UDEV_BIN \"$(PWD)/udev\" >> $@ + @echo \#define UDEVD_BIN \"$(PWD)/udevd\" >> $@ # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf diff --git a/test/udevd_test.sh b/test/udevd_test.sh index 0c7bd431b..94698085c 100644 --- a/test/udevd_test.sh +++ b/test/udevd_test.sh @@ -3,7 +3,12 @@ # kill daemon, first event will start it again killall udevd -# connect(123) - disconnect(456) - connect(789) sequence of sda/sdb/sdc +# 3 x connect/disconnect sequence of sda/sdb/sdc + +export SEQNUM=3 +export ACTION=add +export DEVPATH=/block/sdc +./udevsend block export SEQNUM=1 export ACTION=add @@ -17,36 +22,64 @@ export DEVPATH=/block/sdb export SEQNUM=4 export ACTION=remove -export DEVPATH=/block/sda -./udevsend block - -export SEQNUM=3 -export ACTION=add export DEVPATH=/block/sdc ./udevsend block -export SEQNUM=6 +export SEQNUM=5 export ACTION=remove -export DEVPATH=/block/sdc +export DEVPATH=/block/sdb ./udevsend block -export SEQNUM=5 -export ACTION=remove +export SEQNUM=8 +export ACTION=add export DEVPATH=/block/sdb ./udevsend block +export SEQNUM=6 +export ACTION=remove +export DEVPATH=/block/sda +./udevsend block + export SEQNUM=7 export ACTION=add export DEVPATH=/block/sda #./udevsend block +sleep 2 + export SEQNUM=9 export ACTION=add export DEVPATH=/block/sdc ./udevsend block -export SEQNUM=8 +export SEQNUM=11 +export ACTION=remove +export DEVPATH=/block/sdb +./udevsend block + +export SEQNUM=10 +export ACTION=remove +export DEVPATH=/block/sdc +./udevsend block + +export SEQNUM=13 +export ACTION=add +export DEVPATH=/block/sda +./udevsend block + +export SEQNUM=14 export ACTION=add export DEVPATH=/block/sdb ./udevsend block +export SEQNUM=15 +export ACTION=add +export DEVPATH=/block/sdc +./udevsend block + +sleep 2 + +export SEQNUM=12 +export ACTION=remove +export DEVPATH=/block/sda +./udevsend block diff --git a/udev.c b/udev.c index 4c67477c2..38b26916c 100644 --- a/udev.c +++ b/udev.c @@ -45,7 +45,6 @@ static void sig_handler(int signum) switch (signum) { case SIGINT: case SIGTERM: - case SIGKILL: sysbus_disconnect(); udevdb_exit(); exit(20 + signum); @@ -143,7 +142,6 @@ static int udev_hotplug(int argc, char **argv) /* set up a default signal handler for now */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - signal(SIGKILL, sig_handler); /* initialize the naming deamon */ namedev_init(); diff --git a/udevd.c b/udevd.c index 26e6b2348..a80da5b0d 100644 --- a/udevd.c +++ b/udevd.c @@ -38,27 +38,42 @@ #include "list.h" #include "udev.h" +#include "udev_version.h" #include "udevd.h" #include "logging.h" + #define BUFFER_SIZE 1024 +static int running_remove_queue(pid_t pid); +static int msg_exec(struct hotplug_msg *msg); + static int expect_seqnum = 0; static int lock_file = -1; static char *lock_filename = ".udevd_lock"; LIST_HEAD(msg_list); +LIST_HEAD(running_list); +LIST_HEAD(delayed_list); static void sig_handler(int signum) { + pid_t pid; + dbg("caught signal %d", signum); switch (signum) { case SIGALRM: dbg("event timeout reached"); break; + case SIGCHLD: + /* catch signals from exiting childs */ + while ( (pid = waitpid(-1, NULL, WNOHANG)) > 0) { + dbg("exec finished, pid %d", pid); + running_remove_queue(pid); + } + break; case SIGINT: case SIGTERM: - case SIGKILL: if (lock_file >= 0) { close(lock_file); unlink(lock_filename); @@ -70,34 +85,104 @@ static void sig_handler(int signum) } } -static void dump_queue(void) +static void set_timeout(int seconds) { - struct hotplug_msg *msg; + alarm(seconds); + dbg("set timeout in %d seconds", seconds); +} - list_for_each_entry(msg, &msg_list, list) - dbg("sequence %d in queue", msg->seqnum); +static int running_moveto_queue(struct hotplug_msg *msg) +{ + dbg("move sequence %d [%d] to running queue '%s'", + msg->seqnum, msg->pid, msg->devpath); + list_move_tail(&msg->list, &running_list); + return 0; +} + +static int running_remove_queue(pid_t pid) +{ + struct hotplug_msg *child; + struct hotplug_msg *tmp_child; + + list_for_each_entry_safe(child, tmp_child, &running_list, list) + if (child->pid == pid) { + list_del_init(&child->list); + free(child); + return 0; + } + return -EINVAL; +} + +static pid_t running_getpid_by_devpath(struct hotplug_msg *msg) +{ + struct hotplug_msg *child; + struct hotplug_msg *tmp_child; + + list_for_each_entry_safe(child, tmp_child, &running_list, list) + if (strncmp(child->devpath, msg->devpath, sizeof(child->devpath)) == 0) + return child->pid; + return 0; +} + +static void delayed_dump_queue(void) +{ + struct hotplug_msg *child; + + list_for_each_entry(child, &delayed_list, list) + dbg("event for '%s' in queue", child->devpath); +} + +static int delayed_moveto_queue(struct hotplug_msg *msg) +{ + dbg("move event to delayed queue '%s'", msg->devpath); + list_move_tail(&msg->list, &delayed_list); + return 0; +} + +static void delayed_check_queue(void) +{ + struct hotplug_msg *delayed_child; + struct hotplug_msg *running_child; + struct hotplug_msg *tmp_child; + + /* see if we have delayed exec's that can run now */ + list_for_each_entry_safe(delayed_child, tmp_child, &delayed_list, list) + list_for_each_entry_safe(running_child, tmp_child, &running_list, list) + if (strncmp(delayed_child->devpath, running_child->devpath, + sizeof(running_child->devpath)) == 0) { + dbg("delayed exec for '%s' can run now", delayed_child->devpath); + msg_exec(delayed_child); + } } -static void dump_msg(struct hotplug_msg *msg) +static void msg_dump(struct hotplug_msg *msg) { dbg("sequence %d, '%s', '%s', '%s'", msg->seqnum, msg->action, msg->devpath, msg->subsystem); } -static int dispatch_msg(struct hotplug_msg *msg) +static int msg_exec(struct hotplug_msg *msg) { pid_t pid; - dump_msg(msg); + msg_dump(msg); setenv("ACTION", msg->action, 1); setenv("DEVPATH", msg->devpath, 1); + /* delay exec, if we already have a udev working on the same devpath */ + pid = running_getpid_by_devpath(msg); + if (pid != 0) { + dbg("delay exec of sequence %d, [%d] already working on '%s'", + msg->seqnum, pid, msg->devpath); + delayed_moveto_queue(msg); + } + pid = fork(); switch (pid) { case 0: /* child */ - execl(UDEV_EXEC, "udev", msg->subsystem, NULL); + execl(UDEV_BIN, "udev", msg->subsystem, NULL); dbg("exec of child failed"); exit(1); break; @@ -105,18 +190,23 @@ static int dispatch_msg(struct hotplug_msg *msg) dbg("fork of child failed"); return -1; default: - wait(NULL); + /* exec in background, get the SIGCHLD with the sig handler */ + msg->pid = pid; + running_moveto_queue(msg); + break; } return 0; } -static void set_timeout(int seconds) +static void msg_dump_queue(void) { - alarm(seconds); - dbg("set timeout in %d seconds", seconds); + struct hotplug_msg *msg; + + list_for_each_entry(msg, &msg_list, list) + dbg("sequence %d in queue", msg->seqnum); } -static void check_queue(void) +static void msg_check_queue(void) { struct hotplug_msg *msg; struct hotplug_msg *tmp_msg; @@ -127,30 +217,32 @@ recheck: list_for_each_entry_safe(msg, tmp_msg, &msg_list, list) { if (msg->seqnum != expect_seqnum) break; - dispatch_msg(msg); + msg_exec(msg); expect_seqnum++; - list_del_init(&msg->list); - free(msg); } - /* recalculate timeout */ + /* recalculate next timeout */ if (list_empty(&msg_list) == 0) { msg_age = time(NULL) - msg->queue_time; - if (msg_age > EVENT_TIMEOUT_SECONDS-1) { + if (msg_age > EVENT_TIMEOUT_SEC-1) { info("event %d, age %li seconds, skip event %d-%d", msg->seqnum, msg_age, expect_seqnum, msg->seqnum-1); expect_seqnum = msg->seqnum; goto recheck; } - set_timeout(EVENT_TIMEOUT_SECONDS - msg_age); + + /* the first sequence gets its own timeout */ + if (expect_seqnum == 0) { + msg_age = EVENT_TIMEOUT_SEC - FIRST_EVENT_TIMEOUT_SEC; + expect_seqnum = 1; + } + + set_timeout(EVENT_TIMEOUT_SEC - msg_age); return; } - - /* queue is empty */ - set_timeout(UDEVD_TIMEOUT_SECONDS); } -static int queue_msg(struct hotplug_msg *msg) +static int msg_add_queue(struct hotplug_msg *msg) { struct hotplug_msg *new_msg; struct hotplug_msg *tmp_msg; @@ -182,7 +274,7 @@ static void work(void) char buf[BUFFER_SIZE]; int ret; - key = ftok(UDEVD_EXEC, IPC_KEY_ID); + key = ftok(UDEVD_BIN, IPC_KEY_ID); msg = (struct hotplug_msg *) buf; msgid = msgget(key, IPC_CREAT); if (msgid == -1) { @@ -192,41 +284,20 @@ static void work(void) while (1) { ret = msgrcv(msgid, (struct msgbuf *) buf, BUFFER_SIZE-4, HOTPLUGMSGTYPE, 0); if (ret != -1) { - /* init the expected sequence with value from first call */ - if (expect_seqnum == 0) { - expect_seqnum = msg->seqnum; - dbg("init next expected sequence number to %d", expect_seqnum); - } - dbg("current sequence %d, expected sequence %d", msg->seqnum, expect_seqnum); - if (msg->seqnum == expect_seqnum) { - /* execute expected event */ - dispatch_msg(msg); - expect_seqnum++; - check_queue(); - dump_queue(); + dbg("received sequence %d, expected sequence %d", msg->seqnum, expect_seqnum); + if (msg->seqnum >= expect_seqnum) { + msg_add_queue(msg); + msg_dump_queue(); + msg_check_queue(); continue; } - if (msg->seqnum > expect_seqnum) { - /* something missing, queue event*/ - queue_msg(msg); - check_queue(); - dump_queue(); - continue; - } - dbg("too late for event with sequence %d, even skipped ", msg->seqnum); + dbg("too late for event with sequence %d, event skipped ", msg->seqnum); } else { if (errno == EINTR) { - /* timeout */ - if (list_empty(&msg_list)) { - info("we have nothing to do, so daemon exits..."); - if (lock_file >= 0) { - close(lock_file); - unlink(lock_filename); - } - exit(0); - } - check_queue(); - dump_queue(); + msg_check_queue(); + msg_dump_queue(); + delayed_check_queue(); + delayed_dump_queue(); continue; } dbg("ipc message receive error '%s'", strerror(errno)); @@ -266,11 +337,8 @@ int main(int argc, char *argv[]) /* set up signal handler */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - signal(SIGKILL, sig_handler); signal(SIGALRM, sig_handler); - - /* we exit if we have nothing to do, next event will start us again */ - set_timeout(UDEVD_TIMEOUT_SECONDS); + signal(SIGCHLD, sig_handler); work(); exit(0); diff --git a/udevd.h b/udevd.h index c9b69bbc3..4bccd4b81 100644 --- a/udevd.h +++ b/udevd.h @@ -23,18 +23,18 @@ #include "list.h" -#define UDEV_EXEC "./udev" -#define UDEVD_EXEC "./udevd" -#define UDEVD_TIMEOUT_SECONDS 60 -#define EVENT_TIMEOUT_SECONDS 5 +#define FIRST_EVENT_TIMEOUT_SEC 1 +#define EVENT_TIMEOUT_SEC 5 +#define UDEVSEND_RETRY_COUNT 50 /* x 10 millisec */ -#define IPC_KEY_ID 0 +#define IPC_KEY_ID 1 #define HOTPLUGMSGTYPE 44 struct hotplug_msg { long mtype; struct list_head list; + pid_t pid; int seqnum; time_t queue_time; char action[8]; diff --git a/udevsend.c b/udevsend.c index 0a305e50c..f92ee2b5d 100644 --- a/udevsend.c +++ b/udevsend.c @@ -34,6 +34,7 @@ #include #include "udev.h" +#include "udev_version.h" #include "udevd.h" #include "logging.h" @@ -64,7 +65,7 @@ static inline char *get_seqnum(void) static int build_hotplugmsg(struct hotplug_msg *msg, char *action, char *devpath, char *subsystem, int seqnum) { - memset(msg, 0x00, sizeof(msg)); + memset(msg, 0x00, sizeof(*msg)); msg->mtype = HOTPLUGMSGTYPE; msg->seqnum = seqnum; strncpy(msg->action, action, 8); @@ -88,7 +89,7 @@ static int start_daemon(void) /* daemon */ setsid(); chdir("/"); - execl(UDEVD_EXEC, "udevd", NULL); + execl(UDEVD_BIN, "udevd", NULL); dbg("exec of daemon failed"); exit(1); case -1: @@ -150,7 +151,8 @@ int main(int argc, char* argv[]) seq = atoi(seqnum); /* create ipc message queue or get id of our existing one */ - key = ftok(UDEVD_EXEC, IPC_KEY_ID); + key = ftok(UDEVD_BIN, IPC_KEY_ID); + dbg("using ipc queue 0x%0x", key); size = build_hotplugmsg(&message, action, devpath, subsystem, seq); msgid = msgget(key, IPC_CREAT); if (msgid == -1) { @@ -168,7 +170,7 @@ int main(int argc, char* argv[]) /* get state of ipc queue */ tspec.tv_sec = 0; tspec.tv_nsec = 10000000; /* 10 millisec */ - loop = 30; + loop = UDEVSEND_RETRY_COUNT; while (loop--) { retval = msgctl(msgid, IPC_STAT, &msg_queue); if (retval == -1) {