From: Dhaval Giani Date: Tue, 27 Jul 2010 11:51:36 +0000 (+0200) Subject: libcgroup: Get the list of procs X-Git-Tag: v0.37.1~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e943cf1af573fbe748d9f290f341511b8482de2;p=thirdparty%2Flibcgroup.git libcgroup: Get the list of procs 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 [balbir@linux.vnet.ibm.com: Add a missing EOF check] Signed-off-by: Dhaval Giani Acked-by: Balbir Singh --- diff --git a/include/libcgroup/error.h b/include/libcgroup/error.h index 9f914793..908845ee 100644 --- a/include/libcgroup/error.h +++ b/include/libcgroup/error.h @@ -71,6 +71,7 @@ enum { ECGNAMESPACEPATHS, ECGNAMESPACECONTROLLER, ECGMOUNTNAMESPACE, + ECGROUPUNSUPP, }; /** diff --git a/include/libcgroup/groups.h b/include/libcgroup/groups.h index 3cdb832f..d212ec02 100644 --- a/include/libcgroup/groups.h +++ b/include/libcgroup/groups.h @@ -507,6 +507,16 @@ int cgroup_get_value_name_count(struct cgroup_controller *controller); */ 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); /** * @} diff --git a/src/api.c b/src/api.c index 33c64ccb..195e0e6a 100644 --- a/src/api.c +++ b/src/api.c @@ -116,6 +116,7 @@ const char const *cgroup_strerror_codes[] = { "Have multiple paths for the same namespace", "Controller in namespace does not exist", "Cannot have mount and namespace keyword in the same configuration file", + "This kernel does not support this feature", }; static int cg_chown_file(FTS *fts, FTSENT *ent, uid_t owner, gid_t group) @@ -3445,3 +3446,85 @@ int cgroup_get_all_controller_begin(void **handle, struct controller_data *info) 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; + + return (*pid1 - *pid2); +} + +/* + *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 = 16; + int n = 0; + int err; + + cg_build_path(name, cgroup_path, controller); + strncat(cgroup_path, "/cgroup.procs", FILENAME_MAX-strlen(cgroup_path)); + + /* + * This kernel does have support for cgroup.procs + */ + if (access(cgroup_path, F_OK)) + return ECGROUPUNSUPP; + + /* + * 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 (!feof(procs) && n < tot_procs) { + pid_t pid; + err = fscanf(procs, "%u", &pid); + if (err == EOF) + break; + 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; + } + } + } + + *size = n; + + qsort(tmp_list, n, sizeof(pid_t), &pid_compare); + + *pids = tmp_list; + + return 0; +} diff --git a/src/libcgroup.map b/src/libcgroup.map index 06c5e072..130fc768 100644 --- a/src/libcgroup.map +++ b/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;