]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
libcgroup: Get the list of procs
authorDhaval Giani <dhaval.giani@gmail.com>
Tue, 27 Jul 2010 11:51:36 +0000 (13:51 +0200)
committerDhaval Giani <dhaval.giani@gmail.com>
Tue, 27 Jul 2010 11:51:36 +0000 (13:51 +0200)
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

[balbir@linux.vnet.ibm.com: Add a missing EOF check]
Signed-off-by: Dhaval Giani <dhaval.giani@gmail.com>
Acked-by: Balbir Singh <balbir@linux.vnet.ibm.com>
include/libcgroup/error.h
include/libcgroup/groups.h
src/api.c
src/libcgroup.map

index 9f91479351579f5082ebb2e2ddb12d8176c97b8d..908845ee397d356c62029eb204a125c6efabf7ab 100644 (file)
@@ -71,6 +71,7 @@ enum {
        ECGNAMESPACEPATHS,
        ECGNAMESPACECONTROLLER,
        ECGMOUNTNAMESPACE,
+       ECGROUPUNSUPP,
 };
 
 /**
index 3cdb832f42226289b3bac2b8905543e835d8fa7e..d212ec023e05ca87a6b75d386554088288e244be 100644 (file)
@@ -507,6 +507,16 @@ int cgroup_get_value_name_count(struct cgroup_controller *controller);
  */
 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 33c64ccb0034dec57d5c3242d46d62afc63ba002..195e0e6aa26dffbd2a387f20827a36cb73ad48af 100644 (file)
--- a/src/api.c
+++ b/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",
+       "This kernel does not support this feature",
 };
 
 static int cg_chown_file(FTS *fts, FTSENT *ent, uid_t owner, gid_t group)
@@ -3445,3 +3446,85 @@ int cgroup_get_all_controller_begin(void **handle, struct controller_data *info)
 
        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;
+       int err;
+
+       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;
+                       err = fscanf(procs, "%u", &pid);
+                       if (err == EOF)
+                               break;
+                       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;
+                       }
+               }
+       }
+
+       *size = n;
+
+       qsort(tmp_list, n, sizeof(pid_t), &pid_compare);
+
+       *pids = tmp_list;
+
+       return 0;
+}
index 06c5e0721b52319aacf8e0459b012e3607247efa..130fc768216c84edf72f988da87a8f868052ac35 100644 (file)
@@ -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;