8d67b0cbf8203a53c79265c6d84d0c6182576a1d
[openwrt/openwrt.git] / package / hotplug2 / patches / 120-throttling.patch
1 --- a/hotplug2.c
2 +++ b/hotplug2.c
3 @@ -21,6 +21,7 @@
4 #include <sys/mman.h>
5 #include <linux/types.h>
6 #include <linux/netlink.h>
7 +#include <poll.h>
8
9 #include "mem_utils.h"
10 #include "filemap_utils.h"
11 @@ -492,6 +493,11 @@
12 char *coldplug_command = NULL;
13 char *rules_file = HOTPLUG2_RULE_PATH;
14 sigset_t block_mask;
15 + struct pollfd msg_poll;
16 +
17 + struct hotplug2_event_t *backlog = NULL;
18 + struct hotplug2_event_t *backlog_tail = NULL;
19 + int n_backlog = 0;
20
21 struct rules_t *rules = NULL;
22 struct filemap_t filemap;
23 @@ -602,6 +608,8 @@
24 * Open netlink socket to read the uevents
25 */
26 netlink_socket = init_netlink_socket(NETLINK_BIND);
27 + msg_poll.fd = netlink_socket;
28 + msg_poll.events = POLLIN;
29
30 if (netlink_socket == -1) {
31 ERROR("netlink init","Unable to open netlink socket.");
32 @@ -642,20 +650,45 @@
33 * Main loop reading uevents
34 */
35 while (!terminate) {
36 - /*
37 - * Read the uevent packet
38 - */
39 - size = recv(netlink_socket, &buffer, sizeof(buffer), 0);
40 - recv_errno = errno;
41 + if ((n_backlog > 0) && (child_c < max_child_c)) {
42 + /* dequeue backlog message */
43 + tmpevent = backlog;
44 + backlog = backlog->next;
45 + n_backlog--;
46 + if (backlog_tail == tmpevent)
47 + backlog_tail = NULL;
48 + } else {
49 + /*
50 + * Read the uevent packet
51 + */
52 + if (n_backlog >= HOTPLUG2_MSG_BACKLOG) {
53 + usleep(HOTPLUG2_THROTTLE_INTERVAL * 1000);
54 + continue;
55 + }
56 +
57 + if ((n_backlog > 0) && (child_c >= max_child_c)) {
58 + int fds;
59 + msg_poll.revents = 0;
60 + fds = poll(&msg_poll, 1, HOTPLUG2_THROTTLE_INTERVAL);
61 + if (fds < 0) {
62 + perror("POLL FAILED");
63 + continue;
64 + }
65 + if (fds == 0)
66 + continue;
67 + }
68 + size = recv(netlink_socket, &buffer, sizeof(buffer), 0);
69 + recv_errno = errno;
70
71 - /*
72 - * Parse the event into an event structure
73 - */
74 - tmpevent = get_hotplug2_event(buffer, size);
75 + /*
76 + * Parse the event into an event structure
77 + */
78 + tmpevent = get_hotplug2_event(buffer, size);
79
80 - if (tmpevent == NULL) {
81 - ERROR("reading events", "Malformed event read (missing action prefix).");
82 - continue;
83 + if (tmpevent == NULL) {
84 + ERROR("reading events", "Malformed event read (missing action prefix).");
85 + continue;
86 + }
87 }
88
89 /*
90 @@ -706,13 +739,16 @@
91 * Unless, of course, we've specified otherwise and no rules that match
92 * need throttling.
93 */
94 - if (!flags & FLAG_NOTHROTTLE) {
95 - /*
96 - * Okay, throttle away!
97 - */
98 - while (child_c >= max_child_c) {
99 - usleep(HOTPLUG2_THROTTLE_INTERVAL);
100 - }
101 + if (!(flags & FLAG_NOTHROTTLE) && (child_c >= max_child_c)) {
102 + /* log the packet and process it later */
103 + if (backlog_tail)
104 + backlog_tail->next = tmpevent;
105 + else
106 + backlog = tmpevent;
107 + tmpevent->next = NULL;
108 + backlog_tail = tmpevent;
109 + n_backlog++;
110 + continue;
111 }
112
113 sigemptyset(&block_mask);
114 --- a/hotplug2.h
115 +++ b/hotplug2.h
116 @@ -45,9 +45,9 @@
117 #define DBG(action, fmt, arg...)
118 #endif
119
120 +#define HOTPLUG2_MSG_BACKLOG 64
121 #define UEVENT_BUFFER_SIZE 2048
122 -#define HOTPLUG2_POLL_INTERVAL 20000
123 -#define HOTPLUG2_THROTTLE_INTERVAL 10000
124 +#define HOTPLUG2_THROTTLE_INTERVAL 50
125 #define HOTPLUG2_RULE_PATH "/etc/hotplug2.rules"
126
127 #define ACTION_ADD 0
128 @@ -76,6 +76,7 @@
129 int env_vars_c;
130 char *plain;
131 int plain_s;
132 + struct hotplug2_event_t *next;
133 };
134
135 struct options_t {