Index: hotplug2-0.9/hotplug2.c =================================================================== --- hotplug2-0.9.orig/hotplug2.c 2008-08-04 10:02:27.000000000 +0200 +++ hotplug2-0.9/hotplug2.c 2008-08-04 10:03:04.000000000 +0200 @@ -21,6 +21,7 @@ #include <sys/mman.h> #include <linux/types.h> #include <linux/netlink.h> +#include <poll.h> #include "mem_utils.h" #include "filemap_utils.h" @@ -492,6 +493,11 @@ char *coldplug_command = NULL; char *rules_file = HOTPLUG2_RULE_PATH; sigset_t block_mask; + struct pollfd msg_poll; + + struct hotplug2_event_t *backlog = NULL; + struct hotplug2_event_t *backlog_tail = NULL; + int n_backlog = 0; struct rules_t *rules = NULL; struct filemap_t filemap; @@ -602,6 +608,8 @@ * Open netlink socket to read the uevents */ netlink_socket = init_netlink_socket(NETLINK_BIND); + msg_poll.fd = netlink_socket; + msg_poll.events = POLLIN; if (netlink_socket == -1) { ERROR("netlink init","Unable to open netlink socket."); @@ -642,20 +650,44 @@ * Main loop reading uevents */ while (!terminate) { - /* - * Read the uevent packet - */ - size = recv(netlink_socket, &buffer, sizeof(buffer), 0); - recv_errno = errno; + if ((n_backlog > 0) && (child_c < max_child_c)) { + /* dequeue backlog message */ + tmpevent = backlog; + backlog = backlog->next; + n_backlog--; + if (backlog_tail == tmpevent) + backlog_tail = NULL; + } else { + /* + * Read the uevent packet + */ + if (n_backlog >= HOTPLUG2_MSG_BACKLOG) { + usleep(HOTPLUG2_THROTTLE_INTERVAL * 1000); + continue; + } + + if ((n_backlog > 0) && (child_c >= max_child_c)) { + int fds; + msg_poll.revents = 0; + fds = poll(&msg_poll, 1, HOTPLUG2_THROTTLE_INTERVAL); + if (fds < 0) { + continue; + } + if (fds == 0) + continue; + } + size = recv(netlink_socket, &buffer, sizeof(buffer), 0); + recv_errno = errno; - /* - * Parse the event into an event structure - */ - tmpevent = get_hotplug2_event(buffer, size); + /* + * Parse the event into an event structure + */ + tmpevent = get_hotplug2_event(buffer, size); - if (tmpevent == NULL) { - ERROR("reading events", "Malformed event read (missing action prefix)."); - continue; + if (tmpevent == NULL) { + ERROR("reading events", "Malformed event read (missing action prefix)."); + continue; + } } /* @@ -706,13 +738,16 @@ * Unless, of course, we've specified otherwise and no rules that match * need throttling. */ - if (!flags & FLAG_NOTHROTTLE) { - /* - * Okay, throttle away! - */ - while (child_c >= max_child_c) { - usleep(HOTPLUG2_THROTTLE_INTERVAL); - } + if (!(flags & FLAG_NOTHROTTLE) && (child_c >= max_child_c)) { + /* log the packet and process it later */ + if (backlog_tail) + backlog_tail->next = tmpevent; + else + backlog = tmpevent; + tmpevent->next = NULL; + backlog_tail = tmpevent; + n_backlog++; + continue; } sigemptyset(&block_mask); Index: hotplug2-0.9/hotplug2.h =================================================================== --- hotplug2-0.9.orig/hotplug2.h 2008-08-04 10:02:27.000000000 +0200 +++ hotplug2-0.9/hotplug2.h 2008-08-04 10:02:27.000000000 +0200 @@ -45,9 +45,9 @@ #define DBG(action, fmt, arg...) #endif +#define HOTPLUG2_MSG_BACKLOG 64 #define UEVENT_BUFFER_SIZE 2048 -#define HOTPLUG2_POLL_INTERVAL 20000 -#define HOTPLUG2_THROTTLE_INTERVAL 10000 +#define HOTPLUG2_THROTTLE_INTERVAL 50 #define HOTPLUG2_RULE_PATH "/etc/hotplug2.rules" #define ACTION_ADD 0 @@ -76,6 +76,7 @@ int env_vars_c; char *plain; int plain_s; + struct hotplug2_event_t *next; }; struct options_t {