From: Kay Sievers <kay.sievers@vrfy.org>
To: linux-hotplug@vger.kernel.org
Subject: Re: [patch] udevd - cleanup and better timeout handling
Date: Tue, 27 Jan 2004 06:56:04 +0000 [thread overview]
Message-ID: <20040127065604.GA12206@vrfy.org> (raw)
In-Reply-To: <20040125200314.GA8376@vrfy.org>
[-- Attachment #1: Type: text/plain, Size: 11813 bytes --]
On Mon, Jan 26, 2004 at 11:28:19AM -0800, Greg KH wrote:
> On Mon, Jan 26, 2004 at 08:11:10PM +0100, Kay Sievers wrote:
> > On Mon, Jan 26, 2004 at 10:22:34AM -0800, Greg KH wrote:
> > > On Sun, Jan 25, 2004 at 09:03:14PM +0100, Kay Sievers wrote:
> > > > 1. We are much too slow.
> > > > We want to exec the real udev in the background, but a 'remove'
> > > > is much much faster than a 'add', so we have a problem.
> > > > Question: is it neccessary to order events for different devpath's?
> > > > If no, we may wait_pid() for the exec only if we have another udev
> > > > working on the same devpath.
> > >
> > > But how will we keep track of that? It's probably easier just to wait
> > > for each one to finish, right?
> >
> > We leave the message in the queue until we reach the SIGCHLD for this
> > pid. So we can search the queue if we are already working on this devpath,
> > and delay the new exec until the former exec comes back.
>
> Ok, if that isn't too much trouble.
>
> > Is it feasible to run in parallel for different paths, or can you think
> > of any problem?
>
> I can't think of any problem with that.
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 :)
thanks,
Kay
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
[-- Attachment #2: 01-udevd-execqueue.patch --]
[-- Type: text/plain, Size: 12631 bytes --]
diff -Nru a/Makefile b/Makefile
--- a/Makefile Tue Jan 27 07:29:28 2004
+++ b/Makefile Tue Jan 27 07:29:28 2004
@@ -232,6 +232,8 @@
@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 -Nru a/test/udevd_test.sh b/test/udevd_test.sh
--- a/test/udevd_test.sh Tue Jan 27 07:29:28 2004
+++ b/test/udevd_test.sh Tue Jan 27 07:29:28 2004
@@ -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 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 -Nru a/udev.c b/udev.c
--- a/udev.c Tue Jan 27 07:29:28 2004
+++ b/udev.c Tue Jan 27 07:29:28 2004
@@ -45,7 +45,6 @@
switch (signum) {
case SIGINT:
case SIGTERM:
- case SIGKILL:
sysbus_disconnect();
udevdb_exit();
exit(20 + signum);
@@ -143,7 +142,6 @@
/* 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 -Nru a/udevd.c b/udevd.c
--- a/udevd.c Tue Jan 27 07:29:28 2004
+++ b/udevd.c Tue Jan 27 07:29:28 2004
@@ -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 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 dump_msg(struct hotplug_msg *msg)
+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 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 @@
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 @@
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 @@
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 @@
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 @@
/* 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 -Nru a/udevd.h b/udevd.h
--- a/udevd.h Tue Jan 27 07:29:28 2004
+++ b/udevd.h Tue Jan 27 07:29:28 2004
@@ -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 -Nru a/udevsend.c b/udevsend.c
--- a/udevsend.c Tue Jan 27 07:29:28 2004
+++ b/udevsend.c Tue Jan 27 07:29:28 2004
@@ -34,6 +34,7 @@
#include <wait.h>
#include "udev.h"
+#include "udev_version.h"
#include "udevd.h"
#include "logging.h"
@@ -64,7 +65,7 @@
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 @@
/* 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 @@
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 @@
/* 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) {
next prev parent reply other threads:[~2004-01-27 6:56 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-01-25 20:03 [patch] udevd - cleanup and better timeout handling Kay Sievers
2004-01-26 18:22 ` Greg KH
2004-01-26 19:11 ` Kay Sievers
2004-01-26 19:28 ` Greg KH
2004-01-26 19:42 ` Kay Sievers
2004-01-26 22:26 ` Greg KH
2004-01-26 22:56 ` Kay Sievers
2004-01-27 6:56 ` Kay Sievers [this message]
2004-01-27 18:55 ` Greg KH
2004-01-27 19:08 ` Kay Sievers
2004-01-27 19:13 ` Greg KH
2004-01-28 21:47 ` Kay Sievers
2004-01-29 1:52 ` Kay Sievers
2004-01-29 1:56 ` Kay Sievers
2004-01-29 15:55 ` Kay Sievers
2004-01-31 2:42 ` Kay Sievers
2004-02-01 9:08 ` Greg KH
2004-02-01 18:16 ` Kay Sievers
2004-02-02 2:19 ` Kay Sievers
2004-02-02 8:21 ` Greg KH
2004-02-02 11:50 ` Kay Sievers
2004-02-02 18:45 ` Greg KH
2004-02-02 21:36 ` Kay Sievers
2004-02-03 1:26 ` Greg KH
2004-02-03 6:43 ` Ling, Xiaofeng
2004-02-03 20:12 ` Kay Sievers
2004-02-04 0:56 ` Greg KH
2004-02-08 9:43 ` Olaf Hering
2004-02-08 15:22 ` Kay Sievers
2004-02-08 15:40 ` Olaf Hering
2004-02-08 15:57 ` Kay Sievers
2004-02-08 16:09 ` Olaf Hering
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040127065604.GA12206@vrfy.org \
--to=kay.sievers@vrfy.org \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).