[libvirt] [PATCH] cgroup.c: don't leak mem+FD upon OOM

Jim Meyering jim at meyering.net
Thu Feb 4 10:24:06 UTC 2010


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 at 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;

}




More information about the libvir-list mailing list