Root/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
201

Archive Download this file



interactive