136 lines
3.3 KiB
Diff
136 lines
3.3 KiB
Diff
|
--- a/hotplug2.c
|
||
|
+++ b/hotplug2.c
|
||
|
@@ -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,45 @@
|
||
|
* 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) {
|
||
|
+ perror("POLL FAILED");
|
||
|
+ 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 +739,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);
|
||
|
--- a/hotplug2.h
|
||
|
+++ b/hotplug2.h
|
||
|
@@ -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 {
|