hotplug2: add fork handling optimization (also fixes that pesky pppoe race condition...
[openwrt/staging/florian.git] / package / hotplug2 / patches / 120-fork_handling.patch
1 Index: hotplug2-0.9/hotplug2.c
2 ===================================================================
3 --- hotplug2-0.9.orig/hotplug2.c 2007-06-25 11:36:44.800185312 +0200
4 +++ hotplug2-0.9/hotplug2.c 2007-06-25 11:39:08.318367232 +0200
5 @@ -313,6 +313,17 @@
6 }
7
8 #ifdef HAVE_RULES
9 +static int action_needs_fork(struct hotplug2_event_t *event, struct rules_t *rules)
10 +{
11 + int i, rv;
12 +
13 + for (i = 0; i < rules->rules_c; i++) {
14 + if (rule_needs_fork(event, &rules->rules[i]))
15 + return 1;
16 + }
17 + return 0;
18 +}
19 +
20 void perform_action(struct hotplug2_event_t *event, struct rules_t *rules) {
21 int i, rv;
22
23 @@ -565,14 +576,20 @@
24 cur_seqnum = strtoull(seqnum, NULL, 0);
25 if (cur_seqnum > highest_seqnum)
26 highest_seqnum = cur_seqnum;
27 -
28 +
29 if ((dumb && tmpevent->action == ACTION_ADD && modalias != NULL) || (!dumb)) {
30 - /*
31 - * We have more children than we want. Wait until SIGCHLD handler reduces
32 - * their numbers.
33 - */
34 - while (child_c >= max_child_c) {
35 - usleep(HOTPLUG2_THROTTLE_INTERVAL);
36 + int untracked = 0;
37 +
38 + if (!dumb && !action_needs_fork(tmpevent, rules))
39 + untracked = 1;
40 + else {
41 + /*
42 + * We have more children than we want. Wait until SIGCHLD handler reduces
43 + * their numbers.
44 + */
45 + while (child_c >= max_child_c) {
46 + usleep(HOTPLUG2_THROTTLE_INTERVAL);
47 + }
48 }
49
50 sigemptyset(&block_mask);
51 @@ -595,13 +612,16 @@
52 break;
53 default:
54 DBG("spawn", "spawning: %d.", p);
55 - child = add_child(child, p, cur_seqnum);
56 - child_c++;
57 + if (!untracked) {
58 + child = add_child(child, p, cur_seqnum);
59 + child_c++;
60 + }
61 break;
62 }
63 sigprocmask(SIG_UNBLOCK, &block_mask, 0);
64 }
65
66 +done:
67 free_hotplug2_event(tmpevent);
68 }
69
70 Index: hotplug2-0.9/rules.c
71 ===================================================================
72 --- hotplug2-0.9.orig/rules.c 2007-06-25 11:36:44.801185160 +0200
73 +++ hotplug2-0.9/rules.c 2007-06-25 11:36:44.822181968 +0200
74 @@ -363,6 +363,41 @@
75 return EVAL_NOT_AVAILABLE;
76 }
77
78 +int rule_needs_fork(struct hotplug2_event_t *event, struct rule_t *rule)
79 +{
80 + int i, last_rv;
81 +
82 + for (i = 0; i < rule->conditions_c; i++) {
83 + if (rule_condition_eval(event, &(rule->conditions[i])) != EVAL_MATCH)
84 + return 0;
85 + }
86 + for (i = 0; i < rule->actions_c; i++) {
87 + switch (rule->actions[i].type) {
88 + case ACT_STOP_PROCESSING:
89 + return 0;
90 + break;
91 + case ACT_STOP_IF_FAILED:
92 + if (last_rv != 0)
93 + return 0;
94 + break;
95 + case ACT_NEXT_EVENT:
96 + return 0;
97 + break;
98 + case ACT_NEXT_IF_FAILED:
99 + if (last_rv != 0)
100 + return 0;
101 + break;
102 + case ACT_RUN_SHELL:
103 + return 1;
104 + break;
105 + case ACT_RUN_NOSHELL:
106 + return 1;
107 + break;
108 + }
109 + }
110 + return 0;
111 +}
112 +
113 int rule_execute(struct hotplug2_event_t *event, struct rule_t *rule) {
114 int i, last_rv;
115
116 Index: hotplug2-0.9/rules.h
117 ===================================================================
118 --- hotplug2-0.9.orig/rules.h 2007-06-25 11:36:44.801185160 +0200
119 +++ hotplug2-0.9/rules.h 2007-06-25 11:36:44.822181968 +0200
120 @@ -77,5 +77,6 @@
121 int rule_execute(struct hotplug2_event_t *, struct rule_t *);
122 void rules_free(struct rules_t *);
123 struct rules_t *rules_from_config(char *);
124 +int rule_needs_fork(struct hotplug2_event_t *event, struct rule_t *rule);
125
126 #endif /* ifndef RULES_H*/
127 Index: hotplug2-0.9/childlist.c
128 ===================================================================
129 --- hotplug2-0.9.orig/childlist.c 2007-06-25 11:40:23.477941240 +0200
130 +++ hotplug2-0.9/childlist.c 2007-06-25 11:40:48.164188360 +0200
131 @@ -41,10 +41,8 @@
132 struct hotplug2_child_t *remove_child_by_pid(struct hotplug2_child_t *child, pid_t pid, event_seqnum_t *largest_seqnum, int *child_c) {
133 struct hotplug2_child_t *tmp_child;
134
135 - if (child == NULL) {
136 - ERROR("remove_child_by_pid", "Invalid child list passed (NULL).");
137 + if (child == NULL)
138 return NULL;
139 - }
140
141 tmp_child = child;
142