libcgroup: Get the list of procs

This patch adds a new API to get a list of procs. This is
guaranteed to be sorted.

TODO:
1. Ensure only unique values make it through

Signed-off-by: Dhaval Giani <[email protected]>
---
 include/libcgroup/error.h  |    1 
 include/libcgroup/groups.h |   10 +++++
 src/api.c                  |   87 +++++++++++++++++++++++++++++++++++++++++++++
 src/libcgroup.map          |    7 +++
 4 files changed, 105 insertions(+)

Index: libcg/src/api.c
===================================================================
--- libcg.orig/src/api.c
+++ libcg/src/api.c
@@ -116,6 +116,7 @@ const char const *cgroup_strerror_codes[
        "Have multiple paths for the same namespace",
        "Controller in namespace does not exist",
        "Cannot have mount and namespace keyword in the same configuration 
file",
+       "Your kernel does not support this feature",
 };
 
 static int cg_chown_file(FTS *fts, FTSENT *ent, uid_t owner, gid_t group)
@@ -3386,3 +3387,89 @@ int cgroup_get_all_controller_begin(void
 
        return cgroup_get_all_controller_next(handle, info);
 }
+
+static int pid_compare(const void *a, const void *b)
+{
+       const pid_t *pid1, *pid2;
+
+       pid1 = (pid_t *) a;
+       pid2 = (pid_t *) b;
+
+       return (*pid1 - *pid2);
+}
+
+/*
+ *pids needs to be completely uninitialized so that we can set it up
+ *
+ * Caller must free up pids.
+ */
+int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size)
+{
+       char cgroup_path[FILENAME_MAX];
+       FILE *procs;
+       pid_t *tmp_list;
+       int tot_procs = 16;
+       int n = 0;
+
+       cg_build_path(name, cgroup_path, controller);
+       strncat(cgroup_path, "/cgroup.procs", FILENAME_MAX-strlen(cgroup_path));
+
+       /*
+        * This kernel does have support for cgroup.procs
+        */
+       if (access(cgroup_path, F_OK))
+               return ECGROUPUNSUPP;
+
+       /*
+        * Read all the procs and then sort them up.
+        */
+
+       tmp_list = *pids;
+
+       /*
+        * Keep doubling the memory allocated if needed
+        */
+       tmp_list= malloc(sizeof(pid_t) * tot_procs);
+       if (!tmp_list) {
+               last_errno = errno;
+               return ECGOTHER;
+       }
+
+       procs = fopen(cgroup_path, "r");
+       if (!procs) {
+               last_errno = errno;
+               return ECGOTHER;
+       }
+
+       while (!feof(procs)) {
+               while (!feof(procs) && n < tot_procs) {
+                       pid_t pid;
+                       fscanf(procs, "%u", &pid);
+                       tmp_list[n] = pid;
+                       n++;
+               }
+               if (!feof(procs)) {
+                       tot_procs *= 2;
+                       tmp_list = realloc(tmp_list, sizeof(pid_t) * tot_procs);
+                       if (!tmp_list) {
+                               last_errno = errno;
+                               return ECGOTHER;
+                       }
+               }
+       }
+
+       /*
+        * We decrement n because for some reason the last value
+        * gets repeated twice. Still need to investigate why, and
+        * if we are losing the last (sorted?) value, this is the
+        * obvious place to check.
+        */
+       n--;
+       *size = n;
+
+       qsort(tmp_list, n, sizeof(pid_t), &pid_compare);
+
+       *pids = tmp_list;
+
+       return 0;
+}
Index: libcg/src/libcgroup.map
===================================================================
--- libcg.orig/src/libcgroup.map
+++ libcg/src/libcgroup.map
@@ -85,3 +85,10 @@ global:
        cgroup_get_value_name_count;
        cgroup_get_value_name;
 } CGROUP_0.34;
+
+CGROUP_0.36 {
+} CGROUP_0.35;
+
+CGROUP_0.37 {
+       cgroup_get_procs;
+} CGROUP_0.36;
Index: libcg/include/libcgroup/groups.h
===================================================================
--- libcg.orig/include/libcgroup/groups.h
+++ libcg/include/libcgroup/groups.h
@@ -503,6 +503,16 @@ int cgroup_get_value_name_count(struct c
  */
 char *cgroup_get_value_name(struct cgroup_controller *controller, int index);
 
+/**
+ * Get the list of process in a cgroup. This list is guaranteed to
+ * be sorted. It is not necessary that it is unique.
+ * @param name The name of the cgroup
+ * @param controller The name of the controller
+ * @param pids The list of pids. Should be uninitialized when passed
+ * to the API. Should be freed by the caller using free.
+ * @param size The size of the pids array returned by the API.
+ */
+int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size);
 
 /**
  * @}
Index: libcg/include/libcgroup/error.h
===================================================================
--- libcg.orig/include/libcgroup/error.h
+++ libcg/include/libcgroup/error.h
@@ -71,6 +71,7 @@ enum {
        ECGNAMESPACEPATHS,
        ECGNAMESPACECONTROLLER,
        ECGMOUNTNAMESPACE,
+       ECGROUPUNSUPP,
 };
 
 /**



------------------------------------------------------------------------------
The Palm PDK Hot Apps Program offers developers who use the
Plug-In Development Kit to bring their C/C++ apps to Palm for a share 
of $1 Million in cash or HP Products. Visit us here for more details:
http://ad.doubleclick.net/clk;226879339;13503038;l?
http://clk.atdmt.com/CRS/go/247765532/direct/01/
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to