]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
libcgroup: Add flags to the walk_tree handle
authorDhaval Giani <dhaval@linux.vnet.ibm.com>
Thu, 18 Jun 2009 14:12:45 +0000 (19:42 +0530)
committerDhaval Giani <dhaval@linux.vnet.ibm.com>
Thu, 18 Jun 2009 14:19:39 +0000 (19:49 +0530)
Introduce a cgroup_tree_handle structure so that we can track flags for
the walk_tree operation. In a number of cases we would prefer to walk the
tree in postorder as opposed to pre-order which is the current default.
This patch does the addition.

Changes since V1:
1. Added checks for !handle as suggested by Bharata

Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Acked-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Acked-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
include/libcgroup.h
src/api.c
src/libcgroup-internal.h

index c526f58b03175735b4added2ac9f509434f46ca3..149a56012330e811ef6b2de5bb1681677d050eaf 100644 (file)
@@ -255,6 +255,16 @@ int cgroup_walk_tree_next(const int depth, void **handle,
                                struct cgroup_file_info *info, int base_level);
 int cgroup_walk_tree_end(void **handle);
 
+/**
+ * This API is used to set the flags for walk_tree API. Currently availble
+ *  flags are
+ *
+ *  CGROUP_WALK_TYPE_PRE_DIR
+ *  CGROUP_WALK_TYPE_POST_DIR
+ *
+ */
+int cgroup_walk_tree_set_flags(void **handle, int flags);
+
 /**
  * Read the statistics values for the specified controller
  * @controller: Name of the controller for which stats are requested.
index 4de06a3582eb9d9117cf701f8e2ac212c89b2afc..f746bb2168bfaba271cc7b6a559e5880d90bbc6e 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -2256,7 +2256,7 @@ int cgroup_walk_tree_next(const int depth, void **handle,
                                struct cgroup_file_info *info, int base_level)
 {
        int ret = 0;
-       FTS *fts = *(FTS **)handle;
+       struct cgroup_tree_handle *entry;
        FTSENT *ent;
 
        if (!cgroup_initialized)
@@ -2264,26 +2264,34 @@ int cgroup_walk_tree_next(const int depth, void **handle,
 
        if (!handle)
                return ECGINVAL;
-       ent = fts_read(fts);
+
+       entry = (struct cgroup_tree_handle *) *handle;
+
+       ent = fts_read(entry->fts);
        if (!ent)
                return ECGEOF;
        if (!base_level && depth)
                base_level = ent->fts_level + depth;
-       ret = cg_walk_node(fts, ent, base_level, info);
-       *handle = fts;
+       ret = cg_walk_node(entry->fts, ent, base_level, info);
+       *handle = entry;
        return ret;
 }
 
 int cgroup_walk_tree_end(void **handle)
 {
-       FTS *fts = *(FTS **)handle;
+       struct cgroup_tree_handle *entry;
 
        if (!cgroup_initialized)
                return ECGROUPNOTINITIALIZED;
 
        if (!handle)
                return ECGINVAL;
-       fts_close(fts);
+
+       entry = (struct cgroup_tree_handle *) *handle;
+
+       fts_close(entry->fts);
+       free(entry);
+       *handle = NULL;
        return 0;
 }
 
@@ -2300,31 +2308,63 @@ int cgroup_walk_tree_begin(char *controller, char *base_path, const int depth,
        char full_path[FILENAME_MAX];
        FTSENT *ent;
        FTS *fts;
+       struct cgroup_tree_handle *entry;
 
        if (!cgroup_initialized)
                return ECGROUPNOTINITIALIZED;
 
+       if (!handle)
+               return ECGINVAL;
+
        if (!cg_build_path(base_path, full_path, controller))
                return ECGOTHER;
 
+       entry = calloc(sizeof(struct cgroup_tree_handle), 1);
+
+       if (!entry) {
+               last_errno = errno;
+               return ECGOTHER;
+       }
+
        *base_level = 0;
        cg_path[0] = full_path;
        cg_path[1] = NULL;
 
-       fts = fts_open(cg_path, FTS_LOGICAL | FTS_NOCHDIR |
+       entry->fts = fts_open(cg_path, FTS_LOGICAL | FTS_NOCHDIR |
                                FTS_NOSTAT, NULL);
-       ent = fts_read(fts);
+       ent = fts_read(entry->fts);
        if (!ent) {
                cgroup_dbg("fts_read failed\n");
                return ECGINVAL;
        }
        if (!*base_level && depth)
                *base_level = ent->fts_level + depth;
-       ret = cg_walk_node(fts, ent, *base_level, info);
-       *handle = fts;
+       ret = cg_walk_node(entry->fts, ent, *base_level, info);
+       *handle = entry;
        return ret;
 }
 
+int cgroup_walk_tree_set_flags(void **handle, int flags)
+{
+       struct cgroup_tree_handle *entry;
+
+       if (!cgroup_initialized)
+               return ECGROUPNOTINITIALIZED;
+
+       if (!handle)
+               return ECGINVAL;
+
+       if ((flags & CGROUP_WALK_TYPE_PRE_DIR) &&
+                       (flags & CGROUP_WALK_TYPE_POST_DIR))
+               return ECGINVAL;
+
+       entry = (struct cgroup_tree_handle *) *handle;
+       entry->flags = flags;
+
+       *handle = entry;
+       return 0;
+}
+
 /*
  * This parses a stat line which is in the form of (name value) pair
  * separated by a space.
index 705ac8824e4baace7d8c173a2a8abf99d15af26c..95ff76cb7d225b5aed4d3b7b00203d54c46bd4e1 100644 (file)
 __BEGIN_DECLS
 
 #include "config.h"
+#include <fts.h>
 #include <libcgroup.h>
 #include <limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #define CGRULES_CONF_FILE       "/etc/cgrules.conf"
 #define CGRULES_MAX_FIELDS_PER_LINE            3
@@ -87,6 +90,12 @@ struct cgroup_rule_list {
        int len;
 };
 
+/*The walk_tree handle */
+struct cgroup_tree_handle {
+       FTS *fts;
+       int flags;
+};
+
 
 /* Internal API */
 char *cg_build_path(char *name, char *path, char *type);