never queue events with TIMEOUT set
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>
This commit is contained in:
parent
8f528042ca
commit
fc465079ca
77
udevd.c
77
udevd.c
|
@ -50,7 +50,6 @@
|
||||||
#include "udevd.h"
|
#include "udevd.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
/* global variables*/
|
|
||||||
struct udev_rules rules;
|
struct udev_rules rules;
|
||||||
static int udevd_sock;
|
static int udevd_sock;
|
||||||
static int uevent_netlink_sock;
|
static int uevent_netlink_sock;
|
||||||
|
@ -85,19 +84,6 @@ void log_message(int priority, const char *format, ...)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
static void asmlinkage udev_event_sig_handler(int signum)
|
||||||
{
|
{
|
||||||
if (signum == SIGALRM)
|
if (signum == SIGALRM)
|
||||||
|
@ -144,7 +130,12 @@ static int udev_event_process(struct uevent_msg *msg)
|
||||||
return 0;
|
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)
|
static void udev_event_run(struct uevent_msg *msg)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
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)
|
static int running_processes(void)
|
||||||
{
|
{
|
||||||
int f;
|
int f;
|
||||||
|
@ -308,10 +315,6 @@ static int running_with_devpath(struct uevent_msg *msg, int limit)
|
||||||
if (msg->devpath == NULL)
|
if (msg->devpath == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* skip any events with a timeout set */
|
|
||||||
if (msg->timeout != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
list_for_each_entry(loop_msg, &running_list, node) {
|
list_for_each_entry(loop_msg, &running_list, node) {
|
||||||
if (limit && childs_count++ > limit) {
|
if (limit && childs_count++ > limit) {
|
||||||
dbg("%llu, maximum number (%i) of child reached", msg->seqnum, childs_count);
|
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 */
|
/* 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 *loop_msg;
|
||||||
struct uevent_msg *tmp_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);
|
running = running_processes_in_session(sid, max_childs_running+10);
|
||||||
dbg("at least %d processes running in session", running);
|
dbg("at least %d processes running in session", running);
|
||||||
if (running >= max_childs_running) {
|
if (running >= max_childs_running) {
|
||||||
dbg("delay seq %llu, cause too many processes already running",
|
dbg("delay seq %llu, too many processes already running", loop_msg->seqnum);
|
||||||
loop_msg->seqnum);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (running_with_devpath(loop_msg, max_childs) == 0) {
|
/* don't run two processes for the same devpath and wait for the parent*/
|
||||||
/* move event to run list */
|
if (running_with_devpath(loop_msg, max_childs)) {
|
||||||
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
|
|
||||||
dbg("delay seq %llu (%s)", loop_msg->seqnum, loop_msg->devpath);
|
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:
|
case UDEVD_START_EXEC_QUEUE:
|
||||||
info("udevd message (START_EXEC_QUEUE) received");
|
info("udevd message (START_EXEC_QUEUE) received");
|
||||||
stop_exec_q = 0;
|
stop_exec_q = 0;
|
||||||
exec_queue_manager();
|
msg_queue_manager();
|
||||||
break;
|
break;
|
||||||
case UDEVD_SET_LOG_LEVEL:
|
case UDEVD_SET_LOG_LEVEL:
|
||||||
intval = (int *) usend_msg.envbuf;
|
intval = (int *) usend_msg.envbuf;
|
||||||
|
@ -597,16 +602,10 @@ static void udev_done(int pid)
|
||||||
|
|
||||||
list_for_each_entry(msg, &running_list, node) {
|
list_for_each_entry(msg, &running_list, node) {
|
||||||
if (msg->pid == pid) {
|
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);
|
||||||
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);
|
|
||||||
msg_queue_delete(msg);
|
msg_queue_delete(msg);
|
||||||
|
|
||||||
/* we want to run the exec queue manager since there may
|
/* there may be events waiting with the same devpath */
|
||||||
* be events waiting with the devpath of the one that
|
|
||||||
* just finished
|
|
||||||
*/
|
|
||||||
run_exec_q = 1;
|
run_exec_q = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -939,7 +938,7 @@ int main(int argc, char *argv[], char *envp[])
|
||||||
if (run_exec_q) {
|
if (run_exec_q) {
|
||||||
run_exec_q = 0;
|
run_exec_q = 0;
|
||||||
if (!stop_exec_q)
|
if (!stop_exec_q)
|
||||||
exec_queue_manager();
|
msg_queue_manager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
udevd.h
2
udevd.h
|
@ -32,7 +32,7 @@
|
||||||
/* maximum limit of runnig childs */
|
/* maximum limit of runnig childs */
|
||||||
#define UDEVD_MAX_CHILDS 64
|
#define UDEVD_MAX_CHILDS 64
|
||||||
/* start to throttle forking if maximum number of running childs in our session is reached */
|
/* 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 */
|
/* environment buffer, should match the kernel's size in lib/kobject_uevent.h */
|
||||||
#define UEVENT_BUFFER_SIZE 1024
|
#define UEVENT_BUFFER_SIZE 1024
|
||||||
|
|
Loading…
Reference in a new issue