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

Reply via email to