]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
libcgroup: Introduce get_controller API
authorDhaval Giani <dhaval@linux.vnet.ibm.com>
Thu, 18 Jun 2009 14:12:48 +0000 (19:42 +0530)
committerDhaval Giani <dhaval@linux.vnet.ibm.com>
Thu, 18 Jun 2009 14:19:40 +0000 (19:49 +0530)
This set of APIs will allow the caller to query the mount table
and find out what controller is mounted at what path.

Test program has been included in the patch. Running the test program
results in

[dhaval@gondor tests]$ ../libtool --mode=execute ./get_controller
Controller cpu is mounted at /cgroup
Controller cpuacct is mounted at /cgroup
Controller memory is mounted at /cgroup1
[dhaval@gondor tests]$

Which is the setup on this system.

Changes from v2
1. Remove the incorrect comments as pointed out by Bharata

Changes from v1
1. Use a new structure as mentioned by bharata to return the values.

Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Cc: Jan Safranek <jsafrane@redhat.com>
Acked-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
include/libcgroup.h
src/api.c
src/libcgroup.map
tests/Makefile.am
tests/get_controller.c [new file with mode: 0644]

index dd87c63808624263525e56e77bc60c93e99fdd70..e2abdc8701df886220733f1d1ac81feb1805c916 100644 (file)
@@ -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);
index ab35ed7c598b61f9ab5714dc4f9890a80f0e7154..63813a3df85fc8405d31d7e56d9249f1690b95c7 100644 (file)
--- 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
index 0748bb348b42fe59a3aa5d3cc6fa6d4fe3db69fa..adcf9059e295f5f9d7e5762ad355a3eb8bf95da0 100644 (file)
@@ -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;
index 41aebd3ba715748c9aed1f063717bbd874be9de8..e8401f22ce0844d37dac41d5142678a100be991c 100644 (file)
@@ -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 (file)
index 0000000..1829f5c
--- /dev/null
@@ -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;
+}