From 9414f3be0c3f191fdea212ecc3157af5e70a45de Mon Sep 17 00:00:00 2001 From: Dhaval Giani Date: Wed, 22 Apr 2009 15:30:19 +0530 Subject: 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 --- include/libcgroup.h | 19 +++++++++++++++ src/api.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/libcgroup.map | 6 +++++ 3 files changed, 93 insertions(+) diff --git a/include/libcgroup.h b/include/libcgroup.h index efa852b..085c17a 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 4d5b524..baeb856 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 dd44fd7..2e2348e 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; -- cgit From e672700698bf8078ed8cc277855760d6d030dae5 Mon Sep 17 00:00:00 2001 From: Dhaval Giani Date: Wed, 22 Apr 2009 15:30:20 +0530 Subject: libcgroup: Add test cases for new get_task API This is the test case for the new API. This test takes one argument, the group name. Sample run on my system with this test case returns, [dhaval@gondor tests]$ ../libtool --mode=execute ./walk_task a Printing the details of groups a Pid is 6092 Pid is 11315 Pid is 11318 Pid is 11319 Pid is 11324 Pid is 13234 [dhaval@gondor tests]$ Signed-off-by: Dhaval Giani Acked-by: Balbir Singh Acked-by: Bharata B Rao --- tests/Makefile.am | 3 ++- tests/walk_task.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/walk_task.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 5999389..41aebd3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,7 +2,7 @@ INCLUDES = -I$(top_srcdir)/include LDADD = $(top_srcdir)/src/.libs/libcgroup.la # compile the tests, but do not install them -noinst_PROGRAMS = libcgrouptest01 libcg_ba setuid pathtest walk_test read_stats +noinst_PROGRAMS = libcgrouptest01 libcg_ba setuid pathtest walk_test read_stats walk_task libcgrouptest01_SOURCES=libcgrouptest01.c test_functions.c libcgrouptest.h libcg_ba_SOURCES=libcg_ba.cpp @@ -10,6 +10,7 @@ setuid_SOURCES=setuid.c pathtest_SOURCES=pathtest.c walk_test_SOURCES=walk_test.c read_stats_SOURCES=read_stats.c +walk_task_SOURCES=walk_task.c EXTRA_DIST = pathtest.sh runlibcgrouptest.sh diff --git a/tests/walk_task.c b/tests/walk_task.c new file mode 100644 index 0000000..fb89963 --- /dev/null +++ b/tests/walk_task.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int ret, i; + char *group = NULL; + FILE *tasks = NULL; + + if (argc < 2) { + printf("No list of groups provided\n"); + return -1; + } + + ret = cgroup_init(); + + if (ret) { + printf("cgroup_init failed with %s\n", cgroup_strerror(ret)); + return -1; + } + + for (i = 1; i < argc; i++) { + pid_t pid; + group = strdup(argv[i]); + printf("Printing the details of groups %s\n", group); + ret = cgroup_get_task_begin(group, "cpu", (void *) &tasks, + &pid); + while (!ret) { + printf("Pid is %u\n", pid); + ret = cgroup_get_task_next((void *) tasks, &pid); + if (ret && ret != ECGEOF) { + printf("cgroup_get_task_next failed with %s\n", + cgroup_strerror(ret)); + if (ret == ECGOTHER) + printf("failure with %s\n", + strerror(errno)); + return -1; + } + } + free(group); + group = NULL; + ret = cgroup_get_task_end((void **) &tasks); + } + + return 0; + +} -- cgit From 7136dbf03169a9dbe515175c480276fb1877a7b1 Mon Sep 17 00:00:00 2001 From: Dhaval Giani Date: Wed, 22 Apr 2009 15:48:18 +0530 Subject: libcgroup: Correct the version to which the statistics API belong These APIs were not available in v0.33. They will be a part of v0.34 however. Make the change in libcgroup.map reflecting this. Signed-off-by: Dhaval Giani --- src/libcgroup.map | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcgroup.map b/src/libcgroup.map index 2e2348e..4b95daa 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -52,9 +52,6 @@ global: cgroup_walk_tree_begin; cgroup_walk_tree_next; cgroup_walk_tree_end; - cgroup_read_stats_begin; - cgroup_read_stats_next; - cgroup_read_stats_end; } CGROUP_0.32.1; CGROUP_0.34 { @@ -62,4 +59,7 @@ global: cgroup_get_task_begin; cgroup_get_task_end; cgroup_get_task_next; + cgroup_read_stats_begin; + cgroup_read_stats_next; + cgroup_read_stats_end; } CGROUP_0.33; -- cgit