aboutsummaryrefslogtreecommitdiffstats
path: root/package/hotplug2/patches/100-env_memleak.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-12-09 18:50:49 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-12-09 18:50:49 +0000
commit679cab88fe71ce59c158f2a6ba99b669a9069f63 (patch)
treeacc30c3875e38895d7b46a93b2d2977b70d3425f /package/hotplug2/patches/100-env_memleak.patch
parentd5d8a225f886ebe776a75d5a877a5af96f658abf (diff)
downloadupstream-679cab88fe71ce59c158f2a6ba99b669a9069f63.tar.gz
upstream-679cab88fe71ce59c158f2a6ba99b669a9069f63.tar.bz2
upstream-679cab88fe71ce59c158f2a6ba99b669a9069f63.zip
Fix a memory leak in hotplug2 environment handling. Bump hotplug2 to the latest svn revision, remove obsolete patches.
Memory leak is caused by the way hotplug2 handles environment variables, using setenv() and unsetenv(). setenv() creates copies of the supplied strings, but, due to a POSIX blunder, these copies are never destroyed by unsetenv(), neither in glibc nor uclibc - not until the program terminates. Since some events are handled directly in the main process, even when configured with the "fork" worker, hotplug2 memory usage will keep growing over time. This can be observed by running "udevtrigger" and noting the increase in hotplug2 VmRSS after each run. This patch uses putenv() instead, which leaves storage management to the caller, so that we can explicitly delete stuff when it's no longer needed. Signed-off-by: Aleksandar Radovanovic <biblbroks@sezampro.rs> SVN-Revision: 18725
Diffstat (limited to 'package/hotplug2/patches/100-env_memleak.patch')
-rw-r--r--package/hotplug2/patches/100-env_memleak.patch64
1 files changed, 64 insertions, 0 deletions
diff --git a/package/hotplug2/patches/100-env_memleak.patch b/package/hotplug2/patches/100-env_memleak.patch
new file mode 100644
index 0000000000..31f404029e
--- /dev/null
+++ b/package/hotplug2/patches/100-env_memleak.patch
@@ -0,0 +1,64 @@
+diff -Naur a/action.c b/action.c
+--- a/action.c 2009-11-18 13:15:21.000000000 +0000
++++ b/action.c 2009-11-18 13:11:19.000000000 +0000
+@@ -31,6 +31,30 @@
+ }
+
+ /**
++ * Creates a "key=value" string from the given key and value
++ *
++ * @1 Key
++ * @2 Value
++ *
++ * Returns: Newly allocated string in "key=value" form
++ *
++ */
++static char* alloc_env(const char *key, const char *value) {
++ size_t keylen, vallen;
++ char *combined;
++
++ keylen = strlen(key);
++ vallen = strlen(value) + 1;
++
++ combined = xmalloc(keylen + vallen + 1);
++ memcpy(combined, key, keylen);
++ combined[keylen] = '=';
++ memcpy(&combined[keylen + 1], value, vallen);
++
++ return combined;
++}
++
++/**
+ * Choose what action should be taken according to passed settings.
+ *
+ * @1 Hotplug settings
+@@ -41,16 +65,25 @@
+ */
+ void action_perform(struct settings_t *settings, struct uevent_t *event) {
+ int i;
++ char **env;
++
++ env = xmalloc(sizeof(char *) * event->env_vars_c);
++
++ for (i = 0; i < event->env_vars_c; i++) {
++ env[i] = alloc_env(event->env_vars[i].key, event->env_vars[i].value);
++ putenv(env[i]);
++ }
+
+- for (i = 0; i < event->env_vars_c; i++)
+- setenv(event->env_vars[i].key, event->env_vars[i].value, 1);
+-
+ if (settings->dumb == 0) {
+ ruleset_execute(&settings->rules, event, settings);
+ } else {
+ action_dumb(settings, event);
+ }
+
+- for (i = 0; i < event->env_vars_c; i++)
++ for (i = 0; i < event->env_vars_c; i++) {
+ unsetenv(event->env_vars[i].key);
++ free(env[i]);
++ }
++
++ free(env);
+ }