Here's the patch:
(note, no need to test for mapping == NULL in the no_memory block)
From 91dbe896fff64783df1c68769a57a267441143ae Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Thu, 4 Feb 2010 11:22:20 +0100
Subject: [PATCH] cgroup.c: don't leak mem+FD upon OOM
* src/util/cgroup.c (virCgroupDetectPlacement): Close the mapping
FILE* also upon error.
---
src/util/cgroup.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index e6f0270..4446c7f 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -183,6 +183,7 @@ static int virCgroupDetectPlacement(virCgroupPtr group)
return 0;
no_memory:
+ fclose(mapping);
return -ENOMEM;
}
--
1.7.0.rc1.193.ge8618
Here's the (fixed) function:
/*
* Process /proc/self/cgroup figuring out what cgroup
* sub-path the current process is assigned to. ie not
* neccessarily in the root
*/
static int virCgroupDetectPlacement(virCgroupPtr group)
{
int i;
FILE *mapping = NULL;
char line[1024];
mapping = fopen("/proc/self/cgroup", "r");
if (mapping == NULL) {
VIR_ERROR0("Unable to open /proc/self/cgroup");
return -ENOENT;
}
while (fgets(line, sizeof(line), mapping) != NULL) {
char *controllers = strchr(line, ':');
char *path = controllers ? strchr(controllers+1, ':') : NULL;
char *nl = path ? strchr(path, '\n') : NULL;
if (!controllers || !path)
continue;
if (nl)
*nl = '\0';
*path = '\0';
controllers++;
path++;
for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
const char *typestr = virCgroupControllerTypeToString(i);
int typelen = strlen(typestr);
char *tmp = controllers;
while (tmp) {
char *next = strchr(tmp, ',');
int len;
if (next) {
len = next-tmp;
next++;
} else {
len = strlen(tmp);
}
if (typelen == len && STREQLEN(typestr, tmp, len) &&
!(group->controllers[i].placement = strdup(STREQ(path,
"/") ? "" : path)))
goto no_memory;
tmp = next;
}
}
}
fclose(mapping);
return 0;
no_memory:
fclose(mapping);
return -ENOMEM;
}