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

Reply via email to