chiark / gitweb /
never queue events with TIMEOUT set
authorKay Sievers <kay.sievers@suse.de>
Mon, 7 Nov 2005 13:10:09 +0000 (14:10 +0100)
committerKay Sievers <kay.sievers@suse.de>
Mon, 7 Nov 2005 13:10:09 +0000 (14:10 +0100)
With removing the event reorder queue, we can fix the TIMEOUT events
like firmware loading proper, and never delay any of these events.

Signed-off-by: Kay Sievers <kay.sievers@suse.de>
udevd.c
udevd.h

diff --git a/udevd.c b/udevd.c
index dcf5781..ddf7273 100644 (file)
--- a/udevd.c
+++ b/udevd.c
@@ -50,7 +50,6 @@
 #include "udevd.h"
 #include "logging.h"
 
-/* global variables*/
 struct udev_rules rules;
 static int udevd_sock;
 static int uevent_netlink_sock;
@@ -85,19 +84,6 @@ void log_message(int priority, const char *format, ...)
 }
 #endif
 
-static void msg_queue_insert(struct uevent_msg *msg)
-{
-       list_add(&msg->node, &exec_list);
-       msg->queue_time = time(NULL);
-       run_exec_q = 1;
-}
-
-static void msg_queue_delete(struct uevent_msg *msg)
-{
-       list_del(&msg->node);
-       free(msg);
-}
-
 static void asmlinkage udev_event_sig_handler(int signum)
 {
        if (signum == SIGALRM)
@@ -144,7 +130,12 @@ static int udev_event_process(struct uevent_msg *msg)
        return 0;
 }
 
-/* runs event and removes event from run queue when finished */
+static void msg_queue_delete(struct uevent_msg *msg)
+{
+       list_del(&msg->node);
+       free(msg);
+}
+
 static void udev_event_run(struct uevent_msg *msg)
 {
        pid_t pid;
@@ -180,6 +171,22 @@ static void udev_event_run(struct uevent_msg *msg)
        }
 }
 
+static void msg_queue_insert(struct uevent_msg *msg)
+{
+       msg->queue_time = time(NULL);
+
+       /* run all events with a timeout set immediately */
+       if (msg->timeout != 0) {
+               list_add_tail(&msg->node, &running_list);
+               udev_event_run(msg);
+               return;
+       }
+
+       list_add_tail(&msg->node, &exec_list);
+       run_exec_q = 1;
+}
+
+/* runs event and removes event from run queue when finished */
 static int running_processes(void)
 {
        int f;
@@ -308,10 +315,6 @@ static int running_with_devpath(struct uevent_msg *msg, int limit)
        if (msg->devpath == NULL)
                return 0;
 
-       /* skip any events with a timeout set */
-       if (msg->timeout != 0)
-               return 0;
-
        list_for_each_entry(loop_msg, &running_list, node) {
                if (limit && childs_count++ > limit) {
                        dbg("%llu, maximum number (%i) of child reached", msg->seqnum, childs_count);
@@ -340,7 +343,7 @@ static int running_with_devpath(struct uevent_msg *msg, int limit)
 }
 
 /* exec queue management routine executes the events and serializes events in the same sequence */
-static void exec_queue_manager(void)
+static void msg_queue_manager(void)
 {
        struct uevent_msg *loop_msg;
        struct uevent_msg *tmp_msg;
@@ -360,20 +363,22 @@ static void exec_queue_manager(void)
                        running = running_processes_in_session(sid, max_childs_running+10);
                        dbg("at least %d processes running in session", running);
                        if (running >= max_childs_running) {
-                               dbg("delay seq %llu, cause too many processes already running",
-                                   loop_msg->seqnum);
+                               dbg("delay seq %llu, too many processes already running", loop_msg->seqnum);
                                return;
                        }
                }
 
-               if (running_with_devpath(loop_msg, max_childs) == 0) {
-                       /* move event to run list */
-                       list_move_tail(&loop_msg->node, &running_list);
-                       udev_event_run(loop_msg);
-                       running++;
-                       dbg("moved seq %llu to running list", loop_msg->seqnum);
-               } else
+               /* don't run two processes for the same devpath and wait for the parent*/
+               if (running_with_devpath(loop_msg, max_childs)) {
                        dbg("delay seq %llu (%s)", loop_msg->seqnum, loop_msg->devpath);
+                       continue;
+               }
+
+               /* move event to run list */
+               list_move_tail(&loop_msg->node, &running_list);
+               udev_event_run(loop_msg);
+               running++;
+               dbg("moved seq %llu to running list", loop_msg->seqnum);
        }
 }
 
@@ -494,7 +499,7 @@ static struct uevent_msg *get_udevd_msg(void)
        case UDEVD_START_EXEC_QUEUE:
                info("udevd message (START_EXEC_QUEUE) received");
                stop_exec_q = 0;
-               exec_queue_manager();
+               msg_queue_manager();
                break;
        case UDEVD_SET_LOG_LEVEL:
                intval = (int *) usend_msg.envbuf;
@@ -597,16 +602,10 @@ static void udev_done(int pid)
 
        list_for_each_entry(msg, &running_list, node) {
                if (msg->pid == pid) {
-                       if (msg->queue_time)
-                               info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, time(NULL) - msg->queue_time);
-                       else
-                               info("seq 0, pid [%d] exit", msg->pid);
+                       info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, time(NULL) - msg->queue_time);
                        msg_queue_delete(msg);
 
-                       /* we want to run the exec queue manager since there may
-                        * be events waiting with the devpath of the one that
-                        * just finished
-                        */
+                       /* there may be events waiting with the same devpath */
                        run_exec_q = 1;
                        return;
                }
@@ -939,7 +938,7 @@ int main(int argc, char *argv[], char *envp[])
                if (run_exec_q) {
                        run_exec_q = 0;
                        if (!stop_exec_q)
-                               exec_queue_manager();
+                               msg_queue_manager();
                }
        }
 
diff --git a/udevd.h b/udevd.h
index 884c4b0..91c8e65 100644 (file)
--- a/udevd.h
+++ b/udevd.h
@@ -32,7 +32,7 @@
 /* maximum limit of runnig childs */
 #define UDEVD_MAX_CHILDS               64
 /* start to throttle forking if maximum number of running childs in our session is reached */
-#define UDEVD_MAX_CHILDS_RUNNING       8
+#define UDEVD_MAX_CHILDS_RUNNING       16
 
 /* environment buffer, should match the kernel's size in lib/kobject_uevent.h */
 #define UEVENT_BUFFER_SIZE             1024