This patch adds a new API to get a list of procs. This is guaranteed to be sorted.
TODO: 1. Ensure only unique values make it through Signed-off-by: Dhaval Giani <[email protected]> --- include/libcgroup/groups.h | 10 +++++ src/api.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ src/libcgroup.map | 7 +++ 3 files changed, 103 insertions(+) Index: libcg/src/api.c =================================================================== --- libcg.orig/src/api.c +++ libcg/src/api.c @@ -3386,3 +3386,89 @@ int cgroup_get_all_controller_begin(void return cgroup_get_all_controller_next(handle, info); } + +static int pid_compare(const void *a, const void *b) +{ + const pid_t *pid1, *pid2; + + pid1 = (pid_t *) a; + pid2 = (pid_t *) b; + + if (*pid1 < *pid2) + return -1; + + if (*pid1 > *pid2) + return 1; + + return 0; +} + +/* + *pids needs to be completely uninitialized so that we can set it up + * + * Caller must free up pids. + */ +int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size) +{ + char cgroup_path[FILENAME_MAX]; + FILE *procs; + pid_t *tmp_list; + int tot_procs = 1; + int n = 0; + + cg_build_path(name, cgroup_path, controller); + strncat(cgroup_path, "/cgroup.procs", FILENAME_MAX-strlen(cgroup_path)); + + /* + * Read all the procs and then sort them up. + */ + + tmp_list = *pids; + + /* + * Keep doubling the memory allocated if needed + */ + tmp_list= malloc(sizeof(pid_t) * tot_procs); + if (!tmp_list) { + last_errno = errno; + return ECGOTHER; + } + + procs = fopen(cgroup_path, "r"); + if (!procs) { + last_errno = errno; + return ECGOTHER; + } + + while (!feof(procs)) { + while (n < tot_procs) { + pid_t pid; + fscanf(procs, "%u", &pid); + tmp_list[n] = pid; + n++; + } + if (!feof(procs)) { + tot_procs *= 2; + tmp_list = realloc(tmp_list, sizeof(pid_t) * tot_procs); + if (!tmp_list) { + last_errno = errno; + return ECGOTHER; + } + } + } + + /* + * We decrement n because for some reason the last value + * gets repeated twice. Still need to investigate why, and + * if we are losing the last (sorted?) value, this is the + * obvious place to check. + */ + n--; + *size = n; + + qsort(tmp_list, n, sizeof(pid_t), &pid_compare); + + *pids = tmp_list; + + return 0; +} Index: libcg/src/libcgroup.map =================================================================== --- libcg.orig/src/libcgroup.map +++ libcg/src/libcgroup.map @@ -85,3 +85,10 @@ global: cgroup_get_value_name_count; cgroup_get_value_name; } CGROUP_0.34; + +CGROUP_0.36 { +} CGROUP_0.35; + +CGROUP_0.37 { + cgroup_get_procs; +} CGROUP_0.36; Index: libcg/include/libcgroup/groups.h =================================================================== --- libcg.orig/include/libcgroup/groups.h +++ libcg/include/libcgroup/groups.h @@ -503,6 +503,16 @@ int cgroup_get_value_name_count(struct c */ char *cgroup_get_value_name(struct cgroup_controller *controller, int index); +/** + * Get the list of process in a cgroup. This list is guaranteed to + * be sorted. It is not necessary that it is unique. + * @param name The name of the cgroup + * @param controller The name of the controller + * @param pids The list of pids. Should be uninitialized when passed + * to the API. Should be freed by the caller using free. + * @param size The size of the pids array returned by the API. + */ +int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size); /** * @} ------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first _______________________________________________ Libcg-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libcg-devel
