Openwrt/package/hotplug2/patches/120-throttling.patch

136 lines
3.3 KiB
Diff
Raw Normal View History

--- 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 {