summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libcgroup.h21
-rw-r--r--src/api.c74
-rw-r--r--src/libcgroup.map3
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/get_controller.c34
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);
diff --git a/src/api.c b/src/api.c
index ab35ed7..63813a3 100644
--- a/src/api.c
+++ b/src/api.c
@@ -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;
+}