diff options
-rw-r--r-- | include/libcgroup.h | 21 | ||||
-rw-r--r-- | src/api.c | 74 | ||||
-rw-r--r-- | src/libcgroup.map | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/get_controller.c | 34 |
5 files changed, 134 insertions, 1 deletions
diff --git a/include/libcgroup.h b/include/libcgroup.h index dd87c63..e2abdc8 100644 --- a/include/libcgroup.h +++ b/include/libcgroup.h @@ -134,6 +134,11 @@ struct cgroup_stat { char value[CG_VALUE_MAX]; }; +struct cgroup_mount_point { + char name[FILENAME_MAX]; + char path[FILENAME_MAX]; +}; + /* Functions and structures that can be used by the application*/ struct cgroup; struct cgroup_controller; @@ -303,6 +308,22 @@ int cgroup_get_task_begin(char *cgroup, char *controller, void **handle, */ int cgroup_get_task_next(void **handle, pid_t *pid); int cgroup_get_task_end(void **handle); + +/** + * Read the mount table to give a list where each controller is + * mounted + * @handle: Handle to be used for iteration. + * @name: The variable where the name is stored. Should be freed by caller. + * @path: Te variable where the path to the controller is stored. Should be + * freed by the caller. + */ +int cgroup_get_controller_begin(void **handle, struct cgroup_mount_point *info); +/* + * While walking through the mount table, the controllers will be + * returned in order of their mount points. + */ +int cgroup_get_controller_next(void **handle, struct cgroup_mount_point *info); +int cgroup_get_controller_end(void **handle); /* The wrappers for filling libcg structures */ struct cgroup *cgroup_new_cgroup(const char *name); @@ -2541,6 +2541,80 @@ int cgroup_get_task_begin(char *cgroup, char *controller, void **handle, return ret; } + +int cgroup_get_controller_end(void **handle) +{ + int *pos = (int *) *handle; + + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; + + if (!pos) + return ECGINVAL; + + free(pos); + *handle = NULL; + + return 0; +} + +int cgroup_get_controller_next(void **handle, struct cgroup_mount_point *info) +{ + int *pos = (int *) *handle; + int ret = 0; + + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; + + if (!pos) + return ECGINVAL; + + if (!info) + return ECGINVAL; + + pthread_rwlock_rdlock(&cg_mount_table_lock); + + if (cg_mount_table[*pos].name[0] == '\0') { + ret = ECGEOF; + goto out_unlock; + } + + strncpy(info->name, cg_mount_table[*pos].name, FILENAME_MAX); + + strncpy(info->path, cg_mount_table[*pos].path, FILENAME_MAX); + + (*pos)++; + *handle = pos; + +out_unlock: + pthread_rwlock_unlock(&cg_mount_table_lock); + return ret; +} + +int cgroup_get_controller_begin(void **handle, struct cgroup_mount_point *info) +{ + int *pos; + + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; + + if (!info) + return ECGINVAL; + + pos = malloc(sizeof(int)); + + if (!pos) { + last_errno = errno; + return ECGOTHER; + } + + *pos = 0; + + *handle = pos; + + return cgroup_get_controller_next(handle, info); +} + /** * Get process data (euid and egid) from /proc/<pid>/status file. * @param pid: The process id diff --git a/src/libcgroup.map b/src/libcgroup.map index 0748bb3..adcf905 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -63,6 +63,9 @@ global: cgroup_read_stats_next; cgroup_read_stats_end; cgroup_walk_tree_set_flags; + cgroup_get_controller_end; + cgroup_get_controller_next; + cgroup_get_controller_begin; cgroup_get_controller; cgroup_get_uid_gid_from_procfs; } CGROUP_0.33; diff --git a/tests/Makefile.am b/tests/Makefile.am index 41aebd3..e8401f2 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 walk_task +noinst_PROGRAMS = libcgrouptest01 libcg_ba setuid pathtest walk_test read_stats walk_task get_controller libcgrouptest01_SOURCES=libcgrouptest01.c test_functions.c libcgrouptest.h libcg_ba_SOURCES=libcg_ba.cpp @@ -11,6 +11,7 @@ pathtest_SOURCES=pathtest.c walk_test_SOURCES=walk_test.c read_stats_SOURCES=read_stats.c walk_task_SOURCES=walk_task.c +get_controller_SOURCES=get_controller.c EXTRA_DIST = pathtest.sh runlibcgrouptest.sh diff --git a/tests/get_controller.c b/tests/get_controller.c new file mode 100644 index 0000000..1829f5c --- /dev/null +++ b/tests/get_controller.c @@ -0,0 +1,34 @@ +#include <libcgroup.h> +#include <stdio.h> +#include <stdlib.h> + +int main() +{ + int error; + void *handle; + struct cgroup_mount_point info; + + error = cgroup_init(); + + if (error) { + printf("cgroup_init failed with %s\n", cgroup_strerror(error)); + exit(1); + } + + error = cgroup_get_controller_begin(&handle, &info); + + while (error != ECGEOF) { + printf("Controller %s is mounted at %s\n", info.name, + info.path); + error = cgroup_get_controller_next(&handle, &info); + if (error && error != ECGEOF) { + printf("cgroup_get_contrller_next failed with %s", + cgroup_strerror(error)); + exit(1); + } + } + + error = cgroup_get_controller_end(&handle); + + return 0; +} |