From: Dhaval Giani Date: Wed, 22 Apr 2009 10:00:19 +0000 (+0530) Subject: libcgroup: Add new API to walk tasks X-Git-Tag: v0.34~64^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9414f3be0c3f191fdea212ecc3157af5e70a45de;p=thirdparty%2Flibcgroup.git libcgroup: Add new API to walk tasks Add a new API to iterate through the tasks file to get the list of all the tasks in a cgroup. Signed-off-by: Dhaval Giani Acked-by: Balbir Singh Acked-by: Bharata B Rao --- diff --git a/include/libcgroup.h b/include/libcgroup.h index efa852b9..085c17ac 100644 --- a/include/libcgroup.h +++ b/include/libcgroup.h @@ -274,6 +274,25 @@ int cgroup_read_stats_next(void **handle, struct cgroup_stat *stat); int cgroup_read_stats_end(void **handle); +/** + * Read the tasks file to get the list of tasks in a cgroup + * @cgroup: Name of the cgroup + * @controller: Name of the cgroup subsystem + * @handle: Handle to be used in the iteration + * @pid: The pid read from the tasks file. Will be filled in by the API + */ +int cgroup_get_task_begin(char *cgroup, char *controller, void **handle, + pid_t *pid); + +/** + * Read the next task value + * @handle: The handle used for iterating + * @pid: The variable where the value will be stored + * + * return ECGEOF when the iterator finishes getting the list of tasks. + */ +int cgroup_get_task_next(void *handle, pid_t *pid); +int cgroup_get_task_end(void **handle); /* The wrappers for filling libcg structures */ struct cgroup *cgroup_new_cgroup(const char *name); diff --git a/src/api.c b/src/api.c index 4d5b5246..baeb856a 100644 --- a/src/api.c +++ b/src/api.c @@ -2407,3 +2407,71 @@ int cgroup_read_stats_begin(char *controller, char *path, void **handle, *handle = fp; return ret; } + +int cgroup_get_task_end(void **handle) +{ + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; + + if (!*handle) + return ECGINVAL; + + fclose((FILE *) *handle); + *handle = NULL; + + return 0; +} + +int cgroup_get_task_next(void *handle, pid_t *pid) +{ + int ret; + + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; + + if (!handle) + return ECGINVAL; + + ret = fscanf((FILE *) handle, "%u", pid); + + if (ret != 1) { + if (ret == EOF) + return ECGEOF; + last_errno = errno; + return ECGOTHER; + } + + return 0; +} + +int cgroup_get_task_begin(char *cgroup, char *controller, void **handle, + pid_t *pid) +{ + int ret = 0; + char path[FILENAME_MAX]; + char *fullpath = NULL; + + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; + + if (!cg_build_path(cgroup, path, controller)) + return ECGOTHER; + + ret = asprintf(&fullpath, "%s/tasks", path); + + if (ret < 0) { + last_errno = errno; + return ECGOTHER; + } + + *handle = (void *) fopen(fullpath, "r"); + free(fullpath); + + if (!*handle) { + last_errno = errno; + return ECGOTHER; + } + ret = cgroup_get_task_next(*handle, pid); + + return ret; +} diff --git a/src/libcgroup.map b/src/libcgroup.map index dd44fd7c..2e2348e0 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -57,3 +57,9 @@ global: cgroup_read_stats_end; } CGROUP_0.32.1; +CGROUP_0.34 { +global: + cgroup_get_task_begin; + cgroup_get_task_end; + cgroup_get_task_next; +} CGROUP_0.33;