The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/libresource/pull/5
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === This PR makes memory related information provided by libresource cgroup aware. If process is part of a cgroup then libresource figures out corresponding cgroup for memory controller and reads/interprets the information based on cgroup files.
From 0600cd30ccf1ccedf58ac9be62a9f2162780c8e6 Mon Sep 17 00:00:00 2001 From: Rahul Yadav <rahul.x.ya...@oracle.com> Date: Tue, 23 Apr 2019 12:18:46 -0700 Subject: [PATCH 1/2] Made code changes to make memory information cgroup aware. --- resmem.c | 444 ++++++++++++++++++++++++++++++++++++++++++++---- resmem.h | 2 + resnet.c | 4 +- resource.c | 4 +- resource_impl.h | 86 +++++++++- 5 files changed, 495 insertions(+), 45 deletions(-) diff --git a/resmem.c b/resmem.c index d0820e0..97a0eb4 100644 --- a/resmem.c +++ b/resmem.c @@ -19,7 +19,6 @@ #ifndef _RESOURCE_H #include "resource.h" #endif -#include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -27,6 +26,9 @@ #include "resmem.h" #include "resource_impl.h" #include <errno.h> +#include <libgen.h> + +#define startswith(str, buf) strncmp(str, buf, sizeof(str) - 1) /* read a specific information from file on the basis of a string. * String should tell what information is being read. @@ -36,7 +38,7 @@ static inline int get_info_infile(char *fname, char *res, void *out) const char *loc; char buf[MEMBUF_2048]; - if (file_to_buf(fname, buf) == -1) + if (file_to_buf(fname, buf, MEMBUF_2048) == -1) return -1; loc = strstr(buf, res); @@ -50,37 +52,295 @@ static inline int get_info_infile(char *fname, char *res, void *out) return 0; } +/* read information from a cgroup file. + */ +static inline size_t cgmemread(char *cg, char *file) +{ + char buf[MEMBUF_128]; + char fn[FNAMELEN]; + + snprintf(fn, FNAMELEN, "%s/%s%s/%s", DEFAULTCGFS, + MEMCGNAME, cg, file); + + if (file_to_buf(fn, buf, MEMBUF_128) == -1) + return 0; + + return (strtoul(buf, NULL, 10) / 1024); +} + +/* read memory limit from cgorup file + */ +static size_t cgmemlimit(char *cg, char *f) +{ + char *copy; + char *dir; + size_t mem = 0, retmem = 0; + + /* read memory limit for cgroup */ + if ((retmem = cgmemread(cg, f)) == -1) { + return 0; + } + + copy = strdup(cg); + dir = dirname(copy); + + /*read memory limit for parant cg */ + if (strcmp(dir, "/") != 0) { + if((mem = cgmemread(dir, f)) == 0) { + free(copy); + return 0; + } + if (mem < retmem) { + retmem = mem; + } + } + + free(copy); + return retmem; +} + +/* get memory stat from memory.stat file */ +static inline size_t cgmemstat(char *cg, char *stat) +{ + char fn[FNAMELEN]; + size_t ret; + + snprintf(fn, FNAMELEN, "%s/%s%s/%s", DEFAULTCGFS, + MEMCGNAME, cg, "memory.stat"); + + if (get_info_infile(fn, stat, &ret) == -1) + return 0; + + return (ret / 1024); +} + +/* Get all memory info for a cgroup */ +static int getmeminfoall(char *cg, void *out) +{ + size_t memtotal, mmusage, mmtot, cache, active_anon, inactive_anon, + active_file, inactive_file, swaptotal, swapfree, swusage, + swtot; + char fn[FNAMELEN]; + FILE *fp; + int err; + char buf[MEMBUF_128]; + + snprintf(fn, FNAMELEN, "%s/%s%s/%s", DEFAULTCGFS, + MEMCGNAME, cg, "memory.stat"); + + fp = fopen(fn, "r"); + + if (fp == NULL) { + err = errno; + eprintf("while opening File %s with errno: %d", fn, errno); + errno = err; + return -1; + } + + while(fgets(buf, sizeof(buf), fp) != NULL) { + if (startswith("cache", buf) == 0) { + sscanf(buf, "%*s%zu", &cache); + cache /= 1024; + } else if (startswith("active_anon", buf) == 0) { + sscanf(buf, "%*s%zu", &active_anon); + active_anon /= 1024; + } else if (startswith("inactive_anon", buf) == 0) { + sscanf(buf, "%*s%zu", &inactive_anon); + inactive_anon /= 1024; + } else if (startswith("active_file", buf) == 0) { + sscanf(buf, "%*s%zu", &active_file); + active_file /= 1024; + } else if (startswith("inactive_file", buf) == 0) { + sscanf(buf, "%*s%zu", &inactive_file); + inactive_file /= 1024; + } + } + fclose(fp); + + fp = fopen(MEMINFO_FILE, "r"); + if (fp == NULL) { + err = errno; + eprintf("while opening File %s with errno: %d", + MEMINFO_FILE, errno); + errno = err; + return -1; + } + + while(fgets(buf, sizeof(buf), fp) != NULL) { + if (startswith("MemTotal", buf) == 0) { + sscanf(buf, "%*s%zu", &memtotal); + } else if (startswith("SwapTotal", buf) == 0) { + sscanf(buf, "%*s%zu", &swaptotal); + } else if (startswith("SwapFree", buf) == 0) { + sscanf(buf, "%*s%zu", &swapfree); + } + } + fclose(fp); + + mmusage = cgmemread(cg, "memory.usage_in_bytes"); + mmtot = cgmemlimit(cg, "memory.limit_in_bytes"); + if (memtotal < mmtot) { + mmtot = memtotal; + } + + ((res_mem_infoall_t *)out)->memfree = mmtot - mmusage; + ((res_mem_infoall_t *)out)->memavailable = mmtot - mmusage + cache; + ((res_mem_infoall_t *)out)->memtotal = mmtot; + ((res_mem_infoall_t *)out)->active = active_anon + active_file; + ((res_mem_infoall_t *)out)->inactive = inactive_anon + inactive_file; + + swusage = cgmemread(cg, "memory.memsw.usage_in_bytes"); + swtot = cgmemlimit(cg, "memory.memsw.limit_in_bytes"); + + if (swtot > 0 && swtot < swaptotal) + swaptotal = swtot; + + if (swtot > 0 && swusage > 0) { + swusage = swusage - mmusage; + swapfree = (swusage < swaptotal) ? swaptotal - swusage : 0; + } + + ((res_mem_infoall_t *)out)->swaptotal = swaptotal; + ((res_mem_infoall_t *)out)->swapfree = swapfree; + + return 0; +} + /* Read resource information corresponding to res_id */ int getmeminfo(int res_id, void *out, void *hint, int pid, int flags) { char buf[MEMBUF_128]; FILE *fp; int err = 0; + size_t active_anon, active_file, inactive_anon, inactive_file, cache, + swaptotal, swapfree, swtot, swusage, mmusage, mmtot, memtotal; + int ret = 0; - switch (res_id) { + char *cg = get_cgroup(pid, MEMCGNAME); + + if (cg) { + clean_init(cg); + } + switch (res_id) { + /* if process is part of a cgroup then return memory info + *for that cgroup only. + */ case RES_MEM_FREE: - return get_info_infile(MEMINFO_FILE, "MemFree:", out); + if (cg) { + mmusage = cgmemread(cg, "memory.usage_in_bytes"); + if (get_info_infile(MEMINFO_FILE, "MemTotal:", + &memtotal) == -1) + return -1; + mmtot = cgmemlimit(cg, "memory.limit_in_bytes"); + if (memtotal < mmtot) { + mmtot = memtotal; + } + + *(size_t *)out = mmtot - mmusage; + return 0; + } else { + return get_info_infile(MEMINFO_FILE, "MemFree:", out); + } case RES_MEM_AVAILABLE: - return get_info_infile(MEMINFO_FILE, "MemAvailable:", out); + if (cg) { + mmusage = cgmemread(cg, "memory.usage_in_bytes"); + if (get_info_infile(MEMINFO_FILE, "MemTotal:", + &memtotal) == -1) + return -1; + + mmtot = cgmemlimit(cg, "memory.limit_in_bytes"); + + if (memtotal < mmtot) { + mmtot = memtotal; + } + cache = cgmemstat(cg, "cache"); + + *(size_t *)out = mmtot - mmusage + cache; + return 0; + } else { + return get_info_infile(MEMINFO_FILE, "MemAvailable:", + out); + } case RES_MEM_TOTAL: - return get_info_infile(MEMINFO_FILE, "MemTotal:", out); + ret = get_info_infile(MEMINFO_FILE, "MemTotal:", out); + if (cg) { + mmtot = cgmemlimit(cg, "memory.limit_in_bytes"); + if (ret != -1 && *(size_t *)out > mmtot) { + *(size_t *)out = mmtot; + } + } + return ret; case RES_MEM_ACTIVE: - return get_info_infile(MEMINFO_FILE, "Active:", out); + if (cg) { + active_anon = cgmemstat(cg, "\nactive_anon"); + active_file = cgmemstat(cg, "\nactive_file"); + *(size_t *)out = active_anon + active_file; + return 0; + } else { + return get_info_infile(MEMINFO_FILE, "Active:", out); + } case RES_MEM_INACTIVE: - return get_info_infile(MEMINFO_FILE, "Inactive:", out); + if (cg) { + inactive_anon = cgmemstat(cg, "\ninactive_anon"); + inactive_file = cgmemstat(cg, "\ninactive_file"); + *(size_t *)out = inactive_anon + inactive_file; + return 0; + } else { + return get_info_infile(MEMINFO_FILE, "Inactive:", out); + } case RES_MEM_SWAPTOTAL: - return get_info_infile(MEMINFO_FILE, "SwapTotal:", out); + ret = get_info_infile(MEMINFO_FILE, "SwapTotal:", out); + if (cg) { + swtot = cgmemlimit(cg, + "memory.memsw.limit_in_bytes"); + if (ret != -1 && swtot > 0 && *(size_t *)out > swtot) { + *(size_t *)out = swtot; + } + } + return ret; case RES_MEM_SWAPFREE: + if (cg) { + swusage = cgmemread(cg, "memory.memsw.usage_in_bytes"); + swtot = cgmemlimit(cg, + "memory.memsw.limit_in_bytes"); + + if (swusage > 0 && swtot > 0) { + mmusage = cgmemread(cg, + "memory.usage_in_bytes"); + if (get_info_infile(MEMINFO_FILE, + "SwapTotal:", &swaptotal) == -1) + return -1; + + if (swtot > swaptotal) { + swtot = swaptotal; + } + + swusage = swusage - mmusage; + if (swusage < swtot) + swapfree = swtot - swusage; + else + swapfree = 0; + *(size_t *)out = swapfree; + return 0; + } + } return get_info_infile(MEMINFO_FILE, "SwapFree:", out); case RES_MEM_INFOALL: + if (cg) { + if (getmeminfoall(cg, out) == -1) { + return -1; + } + break; + } + fp = fopen(MEMINFO_FILE, "r"); if (fp == NULL) { err = errno; @@ -93,33 +353,28 @@ int getmeminfo(int res_id, void *out, void *hint, int pid, int flags) * is required. */ while (fgets(buf, sizeof(buf), fp) != NULL) { - if (strncmp("MemTotal:", buf, MEMBUF_8) == 0) + if (startswith("MemTotal:", buf) == 0) { sscanf(buf, "%*s%zu", &((res_mem_infoall_t *)out)->memtotal); - - else if (strncmp("MemFree:", buf, MEMBUF_8) == 0) + } else if (startswith("MemFree:", buf) == 0) { sscanf(buf, "%*s%zu", &((res_mem_infoall_t *)out)->memfree); - - else if (strncmp("MemAvailable:", buf, MEMBUF_8) == 0) + } else if (startswith("MemAvailable:", buf) == 0) { sscanf(buf, "%*s%zu", &((res_mem_infoall_t *)out)->memavailable); - - else if (strncmp("Active:", buf, MEMBUF_8) == 0) + } else if (startswith("Active", buf) == 0) { sscanf(buf, "%*s%zu", &((res_mem_infoall_t *)out)->active); - - else if (strncmp("Inactive:", buf, MEMBUF_8) == 0) + } else if (startswith("Inactive", buf) == 0) { sscanf(buf, "%*s%zu", &((res_mem_infoall_t *)out)->inactive); - - else if (strncmp("SwapTotal:", buf, MEMBUF_8) == 0) + } else if (startswith("SwapTotal", buf) == 0) { sscanf(buf, "%*s%zu", &((res_mem_infoall_t *)out)->swaptotal); - - else if (strncmp("SwapFree:", buf, MEMBUF_8) == 0) + } else if (startswith("SwapFree", buf) == 0) { sscanf(buf, "%*s%zu", &((res_mem_infoall_t *)out)->swapfree); + } } fclose(fp); break; @@ -139,11 +394,20 @@ int getmeminfo(int res_id, void *out, void *hint, int pid, int flags) int populate_meminfo(res_blk_t *res, int pid, int flags) { - size_t temp; const char *loc; char buf[MEMBUF_2048]; + size_t active_anon = 0, active_file = 0, inactive_anon = 0, + inactive_file = 0, cache = 0, swaptotal = 0, swapfree = 0, + swtot = 0, swusage = 0, mmusage = 0, mmtot = 0, memtotal = 0, + memavailable = 0, memfree = 0, memactive = 0, meminactive = 0; + + char *cg = get_cgroup(pid, MEMCGNAME); + + if (cg) { + clean_init(cg); + } - if (file_to_buf(MEMINFO_FILE, buf) == -1) { + if (file_to_buf(MEMINFO_FILE, buf, MEMBUF_2048) == -1) { for (int i = 0 ; i < res->res_count; i++) res->res_unit[i]->status = errno; return -1; @@ -152,14 +416,14 @@ int populate_meminfo(res_blk_t *res, int pid, int flags) /* Macro to read memory related information corresponding to a string * from buffer. */ -#define SCANMEMSTR(str) do {\ +#define SCANMEMSTR(str, info) do {\ loc = strstr(buf, str);\ if (loc == NULL) {\ eprintf("%s is not found in file %s", str, MEMINFO_FILE);\ res->res_unit[i]->status = ENODATA;\ } else {\ - sscanf(loc, "%*s%zu", &temp);\ - (res->res_unit[i]->data).sz = temp;\ + sscanf(loc, "%*s%zu", &info);\ + (res->res_unit[i]->data).sz = info;\ res->res_unit[i]->status = RES_STATUS_FILLED;\ } \ } while (0)\ @@ -169,31 +433,132 @@ int populate_meminfo(res_blk_t *res, int pid, int flags) loc = NULL; switch (res->res_unit[i]->res_id) { case RES_MEM_FREE: - SCANMEMSTR("MemFree:"); + if (cg) { + if (!mmusage) + mmusage = cgmemread(cg, + "memory.usage_in_bytes"); + if (!memtotal) + SCANMEMSTR("MemTotal:", memtotal); + if (!mmtot) + mmtot = cgmemlimit(cg, + "memory.limit_in_bytes"); + + if (memtotal < mmtot) { + mmtot = memtotal; + } + + (res->res_unit[i]->data).sz = mmtot - mmusage; + res->res_unit[i]->status = RES_STATUS_FILLED; + } else { + SCANMEMSTR("MemFree:", memfree); + } break; case RES_MEM_AVAILABLE: - SCANMEMSTR("MemAvailable:"); + if (cg) { + if (!mmusage) + mmusage = cgmemread(cg, + "memory.usage_in_bytes"); + if (!memtotal) + SCANMEMSTR("MemTotal:", memtotal); + if (!mmtot) + mmtot = cgmemlimit(cg, + "memory.limit_in_bytes"); + + if (memtotal < mmtot) { + mmtot = memtotal; + } + + cache = cgmemstat(cg, "cache"); + (res->res_unit[i]->data).sz = + mmtot - mmusage + cache; + res->res_unit[i]->status = RES_STATUS_FILLED; + } else { + SCANMEMSTR("MemAvailable:", memavailable); + } break; case RES_MEM_TOTAL: - SCANMEMSTR("MemTotal:"); + if (!memtotal) + SCANMEMSTR("MemTotal:", memtotal); + if (cg) { + if (!mmtot) + mmtot = cgmemlimit(cg, + "memory.limit_in_bytes"); + if (memtotal > mmtot) + (res->res_unit[i]->data).sz = mmtot; + } + res->res_unit[i]->status = RES_STATUS_FILLED; break; case RES_MEM_ACTIVE: - SCANMEMSTR("Active:"); + if (cg) { + active_anon = cgmemstat(cg, "active_anon"); + active_file = cgmemstat(cg, "active_file"); + (res->res_unit[i]->data).sz = + active_anon + active_file; + res->res_unit[i]->status = RES_STATUS_FILLED; + } else { + SCANMEMSTR("Active:", memactive); + } break; case RES_MEM_INACTIVE: - SCANMEMSTR("Inactive:"); + if (cg) { + inactive_anon = cgmemstat(cg, "inactive_anon"); + inactive_file = cgmemstat(cg, "inactive_file"); + (res->res_unit[i]->data).sz = + inactive_anon + inactive_file; + res->res_unit[i]->status = RES_STATUS_FILLED; + } else { + SCANMEMSTR("Inactive:", meminactive); + } break; case RES_MEM_SWAPTOTAL: - SCANMEMSTR("SwapTotal:"); + if (!swaptotal) + SCANMEMSTR("SwapTotal:", swaptotal); + if (cg) { + swtot = cgmemlimit(cg, + "memory.memsw.limit_in_bytes"); + if (swtot > 0 && swaptotal > swtot) { + (res->res_unit[i]->data).sz = swtot; + } + } + res->res_unit[i]->status = RES_STATUS_FILLED; break; case RES_MEM_SWAPFREE: - SCANMEMSTR("SwapFree:"); + SCANMEMSTR("SwapFree:", swapfree); + + if (cg) { + swusage = cgmemread(cg, + "memory.memsw.usage_in_bytes"); + swtot = cgmemlimit(cg, + "memory.memsw.limit_in_bytes"); + + if (!swusage || !swtot) { + break; + } + + if (!mmusage) + mmusage = cgmemread(cg, + "memory.usage_in_bytes"); + if (!swaptotal) + SCANMEMSTR("SwapTotal:", swaptotal); + + if (swtot > swaptotal) { + swtot = swaptotal; + } + + swusage = swusage - mmusage; + if (swusage < swtot) + swapfree = swtot - swusage; + else + swapfree = 0; + (res->res_unit[i]->data).sz = swapfree; + res->res_unit[i]->status = RES_STATUS_FILLED; + } break; case RES_MEM_PAGESIZE: @@ -201,6 +566,16 @@ int populate_meminfo(res_blk_t *res, int pid, int flags) break; case RES_MEM_INFOALL: + if (cg) { + if (getmeminfoall(cg, + (res->res_unit[i]->data).ptr) == -1) { + res->res_unit[i]->status = ENODATA; + return -1; + } + res->res_unit[i]->status = RES_STATUS_FILLED; + break; + } + loc = strstr(buf, "MemTotal:"); sscanf(loc, "%*s%zu", &((res_mem_infoall_t *) (res->res_unit[i]->data).ptr)->memtotal); @@ -231,4 +606,3 @@ int populate_meminfo(res_blk_t *res, int pid, int flags) } return 0; } - diff --git a/resmem.h b/resmem.h index 7180ea9..96f5a93 100644 --- a/resmem.h +++ b/resmem.h @@ -26,6 +26,8 @@ #define MEMBUF_128 128 #define MEMBUF_2048 2048 +#define MEMCGNAME "memory" + extern int populate_meminfo(struct res_blk *res, int pid, int flags); extern int getmeminfo(int res_id, void *out, void *hint, int pid, int flags); diff --git a/resnet.c b/resnet.c index 2b8cc81..4f8c44a 100644 --- a/resnet.c +++ b/resnet.c @@ -198,8 +198,8 @@ static inline int getallnetinfo(void *out, void *hint) while (fgets(buf, sizeof(buf), fp) != NULL) { if (i == NET_ALLIFSTAT_SZ) { - msz = (sizeof(res_net_ifstat_t) * inum) + - NET_ALLIFSTAT_SZ; + msz = sizeof(res_net_ifstat_t) * (inum + + NET_ALLIFSTAT_SZ); rlst = (res_net_ifstat_t *)realloc(lst, msz); if(rlst == NULL) { fclose(fp); diff --git a/resource.c b/resource.c index 030157b..20471d7 100644 --- a/resource.c +++ b/resource.c @@ -150,6 +150,7 @@ int res_read(int res_id, void *out, void *hint, int pid, int flags) int ret; int err; + if (out == NULL) { switch (res_id) { /* In case of RES_NET_ALLIFSTAT memory is allocated on the @@ -171,8 +172,9 @@ int res_read(int res_id, void *out, void *hint, int pid, int flags) return getmeminfo(res_id, out, hint, pid, flags); /* Check if net proc file is needed to open */ - if (res_id >= NET_MIN && res_id < NET_MAX) + if (res_id >= NET_MIN && res_id < NET_MAX) { return getnetinfo(res_id, out, hint, pid, flags); + } switch (res_id) { case RES_KERN_RELEASE: diff --git a/resource_impl.h b/resource_impl.h index 35863b9..65ab9e9 100644 --- a/resource_impl.h +++ b/resource_impl.h @@ -23,26 +23,97 @@ #include <errno.h> #define RESOURCE_64 64 +#define RESOURCE_256 256 #define RESOURCE_2048 2048 +#define FNAMELEN RESOURCE_256 + +#define INITSCOPE "/init.scope" +#define DEFAULTCGFS "/sys/fs/cgroup" + #define eprintf(msg, ...) fprintf(stderr,\ "Err at line %d in file %s: "msg"\n",\ __LINE__, __FILE__, ##__VA_ARGS__)\ +static inline void clean_init(char *cg) +{ + char *p; + size_t cg_len = strlen(cg), init_len = strlen(INITSCOPE); + + if (cg_len < init_len) + return; + + p = cg + cg_len - init_len; + if (strcmp(p, INITSCOPE) == 0) { + if (p == cg) + *(p+1) = '\0'; + else + *p = '\0'; + } +} + +static inline char *get_cgroup(pid_t pid, const char *contrl) +{ + char fn[FNAMELEN]; + FILE *f; + char *line = NULL; + size_t len = 0; + size_t l = 0; + int ret; + char *cgrp = NULL; + char *c1, *c2; + + if (pid) { + ret = snprintf(fn, FNAMELEN, "/proc/%d/cgroup", pid); + } else { + ret = snprintf(fn, FNAMELEN, "/proc/self/cgroup"); + } + if (ret < 0 || ret >= FNAMELEN) + return NULL; + + if (!(f = fopen(fn, "r"))) + return NULL; + + while (getline(&line, &len, f) != -1) { + if (!line[0]) + continue; + c1 = strchr(line, ':'); + if (!c1) + goto out; + c1++; + c2 = strchr(c1, ':'); + if (!c2) + goto out; + *c2 = '\0'; + if (strcmp(c1, contrl) != 0) + continue; + c2++; + l = strlen(c2); + if (l && c2[l-1] == '\n') + c2[l-1] = '\0'; + if(strcmp(c2, "/") == 0) + goto out; + do { + cgrp = strdup(c2); + } while (!cgrp); + break; + } + +out: + fclose(f); + free(line); + return cgrp; +} -static inline int file_to_buf(char *fname, char *buf) +static inline int file_to_buf(char *fname, char *buf, unsigned int bufsz) { int fd = 0; size_t rdsz = 0; int err = 0; fd = open(fname, O_RDONLY); - if (fd == -1) { - err = errno; - eprintf("in opening File %s with errno: %d", fname, errno); - errno = err; + if (fd == -1) return -1; - } if (lseek(fd, 0L, SEEK_SET) == -1) { err = errno; @@ -52,7 +123,7 @@ static inline int file_to_buf(char *fname, char *buf) return -1; } - rdsz = read(fd, buf, RESOURCE_2048 - 1); + rdsz = read(fd, buf, bufsz - 1); if (rdsz < 0) { err = errno; eprintf("in read from File %s with errno: %d", fname, errno); @@ -65,4 +136,5 @@ static inline int file_to_buf(char *fname, char *buf) return rdsz; } + #endif /* _RESOURCE_IMPL_H */ From 56f427a7306956c759ed43600fde8fd4a342825f Mon Sep 17 00:00:00 2001 From: Rahul Yadav <rahul.x.ya...@oracle.com> Date: Tue, 23 Apr 2019 14:37:40 -0700 Subject: [PATCH 2/2] extra space removal and comments --- resource.c | 4 +--- resource_impl.h | 10 +++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/resource.c b/resource.c index 20471d7..030157b 100644 --- a/resource.c +++ b/resource.c @@ -150,7 +150,6 @@ int res_read(int res_id, void *out, void *hint, int pid, int flags) int ret; int err; - if (out == NULL) { switch (res_id) { /* In case of RES_NET_ALLIFSTAT memory is allocated on the @@ -172,9 +171,8 @@ int res_read(int res_id, void *out, void *hint, int pid, int flags) return getmeminfo(res_id, out, hint, pid, flags); /* Check if net proc file is needed to open */ - if (res_id >= NET_MIN && res_id < NET_MAX) { + if (res_id >= NET_MIN && res_id < NET_MAX) return getnetinfo(res_id, out, hint, pid, flags); - } switch (res_id) { case RES_KERN_RELEASE: diff --git a/resource_impl.h b/resource_impl.h index 65ab9e9..428dd77 100644 --- a/resource_impl.h +++ b/resource_impl.h @@ -29,6 +29,11 @@ #define FNAMELEN RESOURCE_256 #define INITSCOPE "/init.scope" + +/* We are assuming that cgroup is mounted at its usual location, + * If we have reeust from applications who do not mount cgroup at + * usual location, then we need to change this. + */ #define DEFAULTCGFS "/sys/fs/cgroup" #define eprintf(msg, ...) fprintf(stderr,\ @@ -52,6 +57,7 @@ static inline void clean_init(char *cg) } } +/* Get cgroup path for a particular controller */ static inline char *get_cgroup(pid_t pid, const char *contrl) { char fn[FNAMELEN]; @@ -63,11 +69,14 @@ static inline char *get_cgroup(pid_t pid, const char *contrl) char *cgrp = NULL; char *c1, *c2; + /* If no pid is provided then return cgroup info for current process. + */ if (pid) { ret = snprintf(fn, FNAMELEN, "/proc/%d/cgroup", pid); } else { ret = snprintf(fn, FNAMELEN, "/proc/self/cgroup"); } + if (ret < 0 || ret >= FNAMELEN) return NULL; @@ -136,5 +145,4 @@ static inline int file_to_buf(char *fname, char *buf, unsigned int bufsz) return rdsz; } - #endif /* _RESOURCE_IMPL_H */
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel