diff options
author | Felix Fietkau <nbd@openwrt.org> | 2007-06-25 09:47:58 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2007-06-25 09:47:58 +0000 |
commit | 13f087cd5aae235234d0f8d43627b5a47fe7dd2e (patch) | |
tree | f521a56dd6a5f2a89ca1224264115ae3ffefdf90 | |
parent | 05c0ca34a722cc87ef1519fd36c82acd8022a7c8 (diff) | |
download | upstream-13f087cd5aae235234d0f8d43627b5a47fe7dd2e.tar.gz upstream-13f087cd5aae235234d0f8d43627b5a47fe7dd2e.tar.bz2 upstream-13f087cd5aae235234d0f8d43627b5a47fe7dd2e.zip |
hotplug2: add fork handling optimization (also fixes that pesky pppoe race condition in #1655)
SVN-Revision: 7726
-rw-r--r-- | package/hotplug2/patches/120-fork_handling.patch | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/package/hotplug2/patches/120-fork_handling.patch b/package/hotplug2/patches/120-fork_handling.patch new file mode 100644 index 0000000000..c234a6cb72 --- /dev/null +++ b/package/hotplug2/patches/120-fork_handling.patch @@ -0,0 +1,142 @@ +Index: hotplug2-0.9/hotplug2.c +=================================================================== +--- hotplug2-0.9.orig/hotplug2.c 2007-06-25 11:36:44.800185312 +0200 ++++ hotplug2-0.9/hotplug2.c 2007-06-25 11:39:08.318367232 +0200 +@@ -313,6 +313,17 @@ + } + + #ifdef HAVE_RULES ++static int action_needs_fork(struct hotplug2_event_t *event, struct rules_t *rules) ++{ ++ int i, rv; ++ ++ for (i = 0; i < rules->rules_c; i++) { ++ if (rule_needs_fork(event, &rules->rules[i])) ++ return 1; ++ } ++ return 0; ++} ++ + void perform_action(struct hotplug2_event_t *event, struct rules_t *rules) { + int i, rv; + +@@ -565,14 +576,20 @@ + cur_seqnum = strtoull(seqnum, NULL, 0); + if (cur_seqnum > highest_seqnum) + highest_seqnum = cur_seqnum; +- ++ + if ((dumb && tmpevent->action == ACTION_ADD && modalias != NULL) || (!dumb)) { +- /* +- * We have more children than we want. Wait until SIGCHLD handler reduces +- * their numbers. +- */ +- while (child_c >= max_child_c) { +- usleep(HOTPLUG2_THROTTLE_INTERVAL); ++ int untracked = 0; ++ ++ if (!dumb && !action_needs_fork(tmpevent, rules)) ++ untracked = 1; ++ else { ++ /* ++ * We have more children than we want. Wait until SIGCHLD handler reduces ++ * their numbers. ++ */ ++ while (child_c >= max_child_c) { ++ usleep(HOTPLUG2_THROTTLE_INTERVAL); ++ } + } + + sigemptyset(&block_mask); +@@ -595,13 +612,16 @@ + break; + default: + DBG("spawn", "spawning: %d.", p); +- child = add_child(child, p, cur_seqnum); +- child_c++; ++ if (!untracked) { ++ child = add_child(child, p, cur_seqnum); ++ child_c++; ++ } + break; + } + sigprocmask(SIG_UNBLOCK, &block_mask, 0); + } + ++done: + free_hotplug2_event(tmpevent); + } + +Index: hotplug2-0.9/rules.c +=================================================================== +--- hotplug2-0.9.orig/rules.c 2007-06-25 11:36:44.801185160 +0200 ++++ hotplug2-0.9/rules.c 2007-06-25 11:36:44.822181968 +0200 +@@ -363,6 +363,41 @@ + return EVAL_NOT_AVAILABLE; + } + ++int rule_needs_fork(struct hotplug2_event_t *event, struct rule_t *rule) ++{ ++ int i, last_rv; ++ ++ for (i = 0; i < rule->conditions_c; i++) { ++ if (rule_condition_eval(event, &(rule->conditions[i])) != EVAL_MATCH) ++ return 0; ++ } ++ for (i = 0; i < rule->actions_c; i++) { ++ switch (rule->actions[i].type) { ++ case ACT_STOP_PROCESSING: ++ return 0; ++ break; ++ case ACT_STOP_IF_FAILED: ++ if (last_rv != 0) ++ return 0; ++ break; ++ case ACT_NEXT_EVENT: ++ return 0; ++ break; ++ case ACT_NEXT_IF_FAILED: ++ if (last_rv != 0) ++ return 0; ++ break; ++ case ACT_RUN_SHELL: ++ return 1; ++ break; ++ case ACT_RUN_NOSHELL: ++ return 1; ++ break; ++ } ++ } ++ return 0; ++} ++ + int rule_execute(struct hotplug2_event_t *event, struct rule_t *rule) { + int i, last_rv; + +Index: hotplug2-0.9/rules.h +=================================================================== +--- hotplug2-0.9.orig/rules.h 2007-06-25 11:36:44.801185160 +0200 ++++ hotplug2-0.9/rules.h 2007-06-25 11:36:44.822181968 +0200 +@@ -77,5 +77,6 @@ + int rule_execute(struct hotplug2_event_t *, struct rule_t *); + void rules_free(struct rules_t *); + struct rules_t *rules_from_config(char *); ++int rule_needs_fork(struct hotplug2_event_t *event, struct rule_t *rule); + + #endif /* ifndef RULES_H*/ +Index: hotplug2-0.9/childlist.c +=================================================================== +--- hotplug2-0.9.orig/childlist.c 2007-06-25 11:40:23.477941240 +0200 ++++ hotplug2-0.9/childlist.c 2007-06-25 11:40:48.164188360 +0200 +@@ -41,10 +41,8 @@ + struct hotplug2_child_t *remove_child_by_pid(struct hotplug2_child_t *child, pid_t pid, event_seqnum_t *largest_seqnum, int *child_c) { + struct hotplug2_child_t *tmp_child; + +- if (child == NULL) { +- ERROR("remove_child_by_pid", "Invalid child list passed (NULL)."); ++ if (child == NULL) + return NULL; +- } + + tmp_child = child; + |