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. 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