On 11/15/19 2:29 PM, Dhaval Giani wrote:
On Wed, Nov 6, 2019 at 3:43 PM Tom Hromatka <tom.hroma...@oracle.com> wrote:
This commit adds a function that, given a pid, can read in
the controllers and cgroups listed in /proc/{pid}/cgroup.
The caller is expected to allocate the controller_list[]
and cgroup_list[] arrays as well as null each entry in the
arrays. cg_get_cgroups_from_proc_cgroups() will allocate
the necessary memory for each string within the arrays.
Note that it's common to have many controllers on newer
kernels, so MAX_MNT_ELEMENTS was increased to 16 to handle
these additional controllers.
Gonna be pedantic and ask for another patch for that one, which can be
fast pathed in to the project.
Good call. I'll add that to v2.
Thanks.
Tom
Thanks!
Dhaval
Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
src/api.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++
src/libcgroup-internal.h | 2 +-
2 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/src/api.c b/src/api.c
index 907475f8d6cf..105816a3ff51 100644
--- a/src/api.c
+++ b/src/api.c
@@ -4189,6 +4189,109 @@ int cgroup_get_uid_gid_from_procfs(pid_t pid, uid_t
*euid, gid_t *egid)
}
/**
+ * Given a pid, this function will return the controllers and cgroups that
+ * the pid is a member of. The caller is expected to allocate the
+ * controller_list[] and cgroup_list[] arrays as well as null each entry in
+ * the arrays. This function will allocate the necessary memory for each
+ * string within the arrays.
+ *
+ * @param pid The process id
+ * @param cgroup_list[] An array of char pointers to hold the cgroups
+ * @param controller_list[] An array of char pointers to hold the list
+ * of controllers
+ * @param list_len The size of the arrays
+ */
+static int cg_get_cgroups_from_proc_cgroups(pid_t pid, char *cgroup_list[],
+ char *controller_list[],
+ int list_len)
+{
+ char path[FILENAME_MAX];
+ char buf[4092];
+ char *stok_buff = NULL;
+ int ret = 0;
+ size_t buff_len;
+ int idx = 0;
+ FILE *f;
+
+ sprintf(path, "/proc/%d/cgroup", pid);
+ f = fopen(path, "re");
+ if (!f)
+ return ECGROUPNOTEXIST;
+
+ while (fgets(buf, sizeof(buf), f)) {
+ /*
+ * Each line in /proc/{pid}/cgroup is like the following:
+ *
+ * {cg#}:{controller}:{cgname}
+ *
+ * e.g.
+ * 7:devices:/user.slice
+ */
+
+ /* read in the cgroup number. we don't care about it */
+ stok_buff = strtok(buf, ":");
+ /* read in the controller name */
+ stok_buff = strtok(NULL, ":");
+
+ /*
+ * after this point, we have allocated memory. if we return
+ * an error code after this, it's up to us to free the
+ * memory we allocated
+ */
+ controller_list[idx] = strndup(stok_buff,
+ strlen(stok_buff) + 1);
+
+ /* read in the cgroup name */
+ stok_buff = strtok(NULL, ":");
+
+ if (stok_buff == NULL) {
+ /*
+ * An empty controller is reported on some kernels.
+ * It may look like this:
+ * 0::/user.slice/user-1000.slice/session-1.scope
+ *
+ * Ignore this controller and move on. Note that we
+ * need to free the controller list entry we made.
+ */
+ free(controller_list[idx]);
+ controller_list[idx] = NULL;
+ continue;
+ }
+
+ buff_len = strlen(stok_buff);
+ if (stok_buff[buff_len - 1] == '\n')
+ /* Don't copy the trailing newline char */
+ buff_len--;
+
+ /* read in the cgroup name */
+ if (buff_len > 1) {
+ /*
+ * Strip off the leading '/' for every cgroup but
+ * the root cgroup
+ */
+ cgroup_list[idx] = malloc(buff_len);
+ snprintf(cgroup_list[idx], buff_len, "%s",
+ &stok_buff[1]);
+ } else {
+ /*
+ * Retain the leading '/' since we're in the root
+ * cgroup
+ */
+ cgroup_list[idx] = strndup(stok_buff, buff_len);
+ }
+
+ idx++;
+ if (idx >= list_len) {
+ cgroup_warn("Maximum mount elements reached. "
+ "Consider increasing MAX_MNT_ELEMENTS\n");
+ break;
+ }
+ }
+ fclose(f);
+ return ret;
+}
+
+/**
* Get process name from /proc/<pid>/status file.
* @param pid: The process id
* @param pname_status : The process name
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index e438916dafaf..b52c82c3f042 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -28,7 +28,7 @@ __BEGIN_DECLS
#include <setjmp.h>
/* Maximum number of mount points/controllers */
-#define MAX_MNT_ELEMENTS 8
+#define MAX_MNT_ELEMENTS 16
/* Estimated number of groups created */
#define MAX_GROUP_ELEMENTS 128
--
1.8.3.1
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel