mac80211: fix a minstrel_ht off-by-one bug (patch by Christian Lamparter)
[openwrt.git] / package / hotplug2 / patches / 160-event_block_fix.patch
1 --- a/uevent.c
2 +++ b/uevent.c
3 @@ -132,6 +132,8 @@ struct uevent_t *uevent_dup(const struct
4
5 dest = xmalloc(sizeof(struct uevent_t));
6 dest->action = src->action;
7 + dest->seqnum = src->seqnum;
8 + dest->action_str = strdup(src->action_str);
9 dest->env_vars_c = src->env_vars_c;
10 dest->env_vars = xmalloc(sizeof(struct env_var_t) * dest->env_vars_c);
11 dest->plain_s = src->plain_s;
12 --- a/workers/worker_fork.c
13 +++ b/workers/worker_fork.c
14 @@ -1,6 +1,69 @@
15 #include "worker_fork.h"
16
17 static struct worker_fork_ctx_t *global_ctx;
18 +static struct worker_fork_uevent_t *uevent_list;
19 +
20 +static void worker_fork_uevent_free(struct worker_fork_uevent_t *node) {
21 + uevent_free(node->uevent);
22 + free(node);
23 +}
24 +
25 +static void worker_fork_uevent_add(void *in_ctx, struct uevent_t *uevent) {
26 + char **env;
27 + int i;
28 + struct worker_fork_ctx_t *ctx = in_ctx;
29 + struct worker_fork_uevent_t *node, *walker;
30 +
31 + node = malloc(sizeof (struct worker_fork_uevent_t));
32 + node->uevent = uevent_dup(uevent);
33 + node->next = NULL;
34 +
35 + if (!uevent_list) uevent_list = node;
36 + else {
37 + /*
38 + * Put events that need to fork first and in reverse order
39 + */
40 + env = xmalloc(sizeof(char *) * node->uevent->env_vars_c);
41 + for (i = 0; i < node->uevent->env_vars_c; i++) {
42 + env[i] = alloc_env(node->uevent->env_vars[i].key, node->uevent->env_vars[i].value);
43 + putenv(env[i]);
44 + }
45 + if (ruleset_flags(&ctx->settings->rules, uevent) & FLAG_SLOW) {
46 + node->next = uevent_list;
47 + uevent_list = node;
48 + }
49 + else {
50 + for (walker = uevent_list; walker->next; walker = walker->next);
51 + walker->next = node;
52 + }
53 + for (i = 0; i < node->uevent->env_vars_c; i++) {
54 + unsetenv(node->uevent->env_vars[i].key);
55 + free(env[i]);
56 + }
57 + free(env);
58 + }
59 +}
60 +
61 +static void worker_fork_uevent_del(struct worker_fork_uevent_t *node) {
62 + struct worker_fork_uevent_t *walker;
63 +
64 + if (node == uevent_list) {
65 + uevent_list = node->next;
66 + }
67 + else {
68 + for (walker = uevent_list; walker->next; walker = walker->next)
69 + if (walker->next == node) walker->next = node->next;
70 + }
71 + worker_fork_uevent_free(node);
72 +}
73 +
74 +static void worker_fork_uevent_empty(void) {
75 + struct worker_fork_uevent_t *walker;
76 +
77 + if (!uevent_list) return;
78 + for (walker = uevent_list; walker->next; walker = walker->next) worker_fork_uevent_free(walker);
79 + uevent_list = NULL;
80 +}
81
82 /**
83 * Destroys data structures related to the given child ID (not PID).
84 @@ -315,6 +378,8 @@ static void *worker_fork_init(struct set
85 struct worker_fork_ctx_t *ctx;
86 PRINTFUNC();
87
88 + uevent_list = NULL;
89 +
90 ctx = malloc(sizeof(struct worker_fork_ctx_t));
91 ctx->children = NULL;
92 ctx->children_count = 0;
93 @@ -376,6 +441,7 @@ static void worker_fork_deinit(void *in_
94 free(ctx->children);
95 free(ctx);
96 global_ctx = NULL;
97 + worker_fork_uevent_empty();
98 }
99
100
101 @@ -384,15 +450,26 @@ static int worker_fork_process(void *in_
102 int i;
103 struct worker_fork_child_t *child;
104 struct worker_fork_ctx_t *ctx = in_ctx;
105 + struct worker_fork_uevent_t *node, *walker;
106 + event_seqnum_t seqnum;
107 +
108 + worker_fork_uevent_add(ctx, uevent);
109 + walker = uevent_list;
110
111 /*
112 - * A big loop, because if we fail to process the event,
113 + * A big loop, because if we fail to process the events,
114 * we don't want to give up.
115 *
116 * TODO: Decide if we want to limit the number of attempts
117 * or set a time limit before reporting terminal failure.
118 */
119 do {
120 + /*
121 + * If more events are waiting, return to receive them
122 + */
123 + if (!seqnum_get(&seqnum) && seqnum > uevent->seqnum) break;
124 +
125 + node = walker;
126 worker_fork_update_children(ctx);
127
128 child = NULL;
129 @@ -407,9 +484,9 @@ static int worker_fork_process(void *in_
130 * No child process is currently available.
131 */
132 if (child == NULL) {
133 - env = xmalloc(sizeof(char *) * uevent->env_vars_c);
134 - for (i = 0; i < uevent->env_vars_c; i++) {
135 - env[i] = alloc_env(uevent->env_vars[i].key, uevent->env_vars[i].value);
136 + env = xmalloc(sizeof(char *) * node->uevent->env_vars_c);
137 + for (i = 0; i < node->uevent->env_vars_c; i++) {
138 + env[i] = alloc_env(node->uevent->env_vars[i].key, node->uevent->env_vars[i].value);
139 putenv(env[i]);
140 }
141
142 @@ -418,8 +495,11 @@ static int worker_fork_process(void *in_
143 * can execute them in the main process?
144 */
145 if (ctx->always_fork == 0 && ctx->settings->dumb == 0 &&
146 - (ruleset_flags(&ctx->settings->rules, uevent) & FLAG_MASK_SLOW) == 0) {
147 - action_perform(ctx->settings, uevent);
148 + (ruleset_flags(&ctx->settings->rules, node->uevent) & FLAG_MASK_SLOW) == 0) {
149 + action_perform(ctx->settings, node->uevent);
150 + walker = walker->next;
151 + worker_fork_uevent_del(node);
152 + if (walker) continue;
153 break;
154 }
155
156 @@ -427,11 +507,11 @@ static int worker_fork_process(void *in_
157 * We have to fork off a new child.
158 */
159 if (ctx->children_count < ctx->max_children ||
160 - (ruleset_flags(&ctx->settings->rules, uevent) & FLAG_SLOW))
161 + (ruleset_flags(&ctx->settings->rules, node->uevent) & FLAG_SLOW))
162 child = worker_fork_spawn(ctx);
163
164 - for (i = 0; i < uevent->env_vars_c; i++) {
165 - unsetenv(uevent->env_vars[i].key);
166 + for (i = 0; i < node->uevent->env_vars_c; i++) {
167 + unsetenv(node->uevent->env_vars[i].key);
168 free(env[i]);
169 }
170 free(env);
171 @@ -442,9 +522,14 @@ static int worker_fork_process(void *in_
172 */
173 if (child != NULL) {
174 child->busy = 1;
175 - if (!worker_fork_relay_event(child->event_fd, uevent));
176 - break;
177 - child->busy = 0;
178 + if (worker_fork_relay_event(child->event_fd, node->uevent)) {
179 + child->busy = 0;
180 + continue;
181 + }
182 + walker = walker->next;
183 + worker_fork_uevent_del(node);
184 + if (walker) continue;
185 + break;
186 }
187
188 /*
189 --- a/workers/worker_fork.h
190 +++ b/workers/worker_fork.h
191 @@ -35,4 +35,9 @@ struct worker_fork_ctx_t {
192 struct settings_t *settings;
193 };
194
195 +struct worker_fork_uevent_t {
196 + struct uevent_t *uevent;
197 + struct worker_fork_uevent_t *next;
198 +};
199 +
200 #endif
This page took 0.068736 seconds and 5 git commands to generate.