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 <[email protected]>

---
 include/libcgroup.h      |   10 +++++++
 src/api.c                |   60 +++++++++++++++++++++++++++++++++++++++--------
 src/libcgroup-internal.h |    9 +++++++
 3 files changed, 69 insertions(+), 10 deletions(-)

Index: libcg/src/libcgroup-internal.h
===================================================================
--- libcg.orig/src/libcgroup-internal.h
+++ libcg/src/libcgroup-internal.h
@@ -19,8 +19,11 @@
 __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);
Index: libcg/src/api.c
===================================================================
--- libcg.orig/src/api.c
+++ libcg/src/api.c
@@ -2241,7 +2241,7 @@ int cgroup_walk_tree_next(const int dept
                                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)
@@ -2249,26 +2249,34 @@ int cgroup_walk_tree_next(const int dept
 
        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;
 }
 
@@ -2285,31 +2293,63 @@ int cgroup_walk_tree_begin(char *control
        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: libcg/include/libcgroup.h
===================================================================
--- libcg.orig/include/libcgroup.h
+++ libcg/include/libcgroup.h
@@ -256,6 +256,16 @@ int cgroup_walk_tree_next(const int dept
 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.
  * @path: cgroup path.



------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables 
unlimited royalty-free distribution of the report engine 
for externally facing server and web deployment. 
http://p.sf.net/sfu/businessobjects
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to