]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
Document the iterators
authorJan Safranek <jsafrane@redhat.com>
Mon, 29 Mar 2010 10:00:42 +0000 (12:00 +0200)
committerJan Safranek <jsafrane@redhat.com>
Mon, 29 Mar 2010 10:00:42 +0000 (12:00 +0200)
Signed-off-by: Jan Safranek <jsafrane@redhat.com>
include/libcgroup/iterators.h

index e8df12a6122da46e1ab90fa55a84d766020b8652..f572becabc1767f2373bdf09193f31751a697f20 100644 (file)
 
 __BEGIN_DECLS
 
-/*
- * Don't use CGROUP_WALK_TYPE_FILE right now. It is added here for
- * later refactoring and better implementation. Most users *should*
- * use CGROUP_WALK_TYPE_PRE_DIR.
+/**
+ * @defgroup group_iterators 3. Iterators
+ * @{
+ * So-called iterators are a code pattern to retrieve various data from
+ * libcgroup in distinct chunks, for example when an application needs to read
+ * list of groups in a hierarchy, it uses iterator to get one group at a time.
+ * Iterator is opaque to the application, the application sees only
+ * <tt>void* handle</tt> pointer, which is managed internally by @c libcgroup.
+ * Each iterator provides at least these functions:
+ * - <tt>int <i>iterator_name</i>_begin(void **handle, my_type *item)</tt>
+ *     - Initialize the iterator, store pointer to it into the @c handle.
+ *     - Return the first element in the iterator, let's say it's @c my_type.
+ *     - Return @c 0, if the operation succeeded.
+ *     - Return #ECGEOF, if the operation succeeded, but the iterator is empty.
+ *       The value of @c item is undefined in this case.
+ *     - Return any other error code on error.
+ * - <tt>int <i>iterator_name</i>_next(void **handle, my_type *item)</tt>
+ *     - Advance to next element in the iterator and return it.
+ *     - Return @c 0, if the operation succeeded.
+ *     - Return #ECGEOF, if there is no item to advance to, i.e. the iterator
+ *       is already at its end. The value of @c item is undefined in this case.
+ *     - Return any other error code on error.
+ * - <tt>void <i>iterator_name</i>_end(void **handle)</tt>
+ *     - Free any data associated with the iterator. This function must be
+ *     called even when <tt><i>iterator_name</i>_begin()</tt> fails.
+ *
+ * @todo not all iterators follow this pattern, e.g. cgroup_walk_tree_begin()
+ * can result both in a state that  cgroup_walk_tree_end() is not needed
+ * and will sigsegv and in a state that cgroup_walk_tree_end() is needed
+ * to free allocated memory. Complete review is needed!
+ * @par Example of iterator usage:
+ * @code
+ * void *handle; // our iterator handle
+ * my_type item; // the data returned by the iterator
+ * int ret;
+ * ret = iterator_name_begin(&handle, &item);
+ * while (ret == 0) {
+ *     // process the item here
+ *     ret = iterator_name_begin(&handle, &item);
+ * }
+ * if (ret != ECGEOF) {
+ *     // process the error here
+ * }
+ * iterator_name_end(&handle);
+ * @endcode
+ *
+ * @name Walk through control group filesystem
+ * @{
+ * This iterator returns all subgroups of given control group. It can be used
+ * to return all groups in given hierarchy, when root control group is provided.
+ */
+
+/**
+ * Type of the walk.
  */
 enum cgroup_walk_type {
-       CGROUP_WALK_TYPE_PRE_DIR = 0x1, /* Pre Order Directory */
-       CGROUP_WALK_TYPE_POST_DIR = 0x2,        /* Post Order Directory */
+       /**
+        * Pre-order directory walk, return a directory first and then its
+        * subdirectories.
+        * E.g. directories would be returned in this order:
+        * @code
+        * /
+        * /group
+        * /group/subgroup1
+        * /group/subgroup1/subsubgroup
+        * /group/subgroup2
+        * @endcode
+        */
+       CGROUP_WALK_TYPE_PRE_DIR = 0x1,
+       /**
+        * Post-order directory walk, return subdirectories of a directory
+        * first and then the directory itself.
+        * E.g. directories would be returned in this order:
+        * @code
+        * /group/subgroup1/subsubgroup
+        * /group/subgroup1
+        * /group/subgroup2
+        * /group
+        * /
+        * @endcode
+        */
+       CGROUP_WALK_TYPE_POST_DIR = 0x2,
 };
 
+/**
+ * Type of returned entity.
+ */
 enum cgroup_file_type {
-       CGROUP_FILE_TYPE_FILE,          /* File */
-       CGROUP_FILE_TYPE_DIR,           /* Directory */
-       CGROUP_FILE_TYPE_OTHER,         /* Directory */
+       CGROUP_FILE_TYPE_FILE,          /**< File. */
+       CGROUP_FILE_TYPE_DIR,           /**< Directory. */
+       CGROUP_FILE_TYPE_OTHER,         /**< Directory. @todo really? */
 };
+
+/**
+ * Information about found directory (= a control group).
+ */
 struct cgroup_file_info {
+       /** Type of the entity. */
        enum cgroup_file_type type;
+       /** Name of the entity. */
        const char *path;
+       /** Name of its parent. */
        const char *parent;
+       /**
+        * Full path to the entity. To get path relative to the root of the
+        * walk, you must store its @c full_path (or its length)
+        * and calculate the relative path by yourself.
+        */
        const char *full_path;
+       /**
+        * Depth of the entity, how many directories below the root of
+        * walk it is.
+        */
        short depth;
 };
 
-#define CG_VALUE_MAX 100
-struct cgroup_stat {
-       char name[FILENAME_MAX];
-       char value[CG_VALUE_MAX];
-};
-
-struct cgroup_mount_point {
-       char name[FILENAME_MAX];
-       char path[FILENAME_MAX];
-};
-
-/*
- * Detailed information about available controller.
- */
-
-struct controller_data {
-/** Controller name. */
-       char name[FILENAME_MAX];
-/**
- * Hierarchy ID. Controllers with the same hierarchy ID
- * are mounted together as one hierarchy. Controllers with
- * ID 0 are not currently used.
- */
-       int hierarchy;
-/** Number of groups. */
-       int num_cgroups;
-/** Enabled flag */
-       int enabled;
-};
-
 /**
  * Walk through the directory tree for the specified controller.
- * @controller: Name of the controller, for which we want to walk
- * the directory tree
- * @base_path: Begin walking from this path
- * @depth: The maximum depth to which the function should walk, 0
- * implies all the way down
- * @handle: Handle to be used during iteration
- * @info: info filled and returned about directory information
+ * The directory representing @c base_path is returned in @c info.
+ * Use cgroup_walk_tree_set_flags() to specify, in which order should be next
+ * directories returned.
+ * @param controller Name of the controller, for which we want to walk
+ * the directory tree.
+ * @param base_path Begin walking from this path. Use "/" to walk through
+ * full hierarchy.
+ * @param depth The maximum depth to which the function should walk, 0
+ * implies all the way down.
+ * @param handle Handle to be used during iteration.
+ * @param info Info filled and returned about directory information.
+ * @param base_level Opaque integer which you must pass to subsequent
+ *     cgroup_walk_tree_next.
+ * @todo why base_level is not hidden in **handle?
+ * @return #ECGEOF when there is no node.
  */
 int cgroup_walk_tree_begin(const char *controller, const char *base_path, int depth,
                                void **handle, struct cgroup_file_info *info,
                                int *base_level);
 /**
- * Get the next element during the walk
- * @depth: The maximum depth to which the function should walk, 0
- * implies all the way down
- * @handle: Handle to be used during iteration
- * @info: info filled and returned about directory information
- *
- * Returns ECGEOF when we are done walking through the nodes.
+ * Get the next directory in the walk.
+ * @param depth The maximum depth to which the function should walk, 0
+ * implies all the way down.
+ * @param handle Handle to be used during iteration.
+ * @param info Info filled and returned about the next directory.
+ * @param base_level Value of base_level returned by cgroup_walk_tree_begin().
+ * @return #ECGEOF when we are done walking through the nodes.
  */
 int cgroup_walk_tree_next(int depth, void **handle,
                                struct cgroup_file_info *info, int base_level);
+
+/**
+ * Release the iterator.
+ */
 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
- *
+ * Set the flags for walk_tree. Currently available flags are in
+ * #cgroup_walk_type enum.
+ * @param handle Handle of the iterator.
+ * @param flags
  */
 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.
- * @handle: Handle to be used during iteration.
- * @stat: Stats values will be filled and returned here.
+ * @}
+ *
+ * @name Read group stats
+ * libcgroup's cgroup_get_value_string() reads only relatively short parametrs
+ * of a group. Use following functions to read @c stats parameter, which can
+ * be quite long.
+ */
+
+/**
+ * Maximum length of a value in stats file.
+ */
+#define CG_VALUE_MAX 100
+/**
+ * One item in stats file.
+ */
+struct cgroup_stat {
+       char name[FILENAME_MAX];
+       char value[CG_VALUE_MAX];
+};
+
+/**
+ * Read the statistics values (= @c stats parameter) for the specified
+ * controller and control group. One line is returned per
+ * cgroup_read_stats_begin() and cgroup_read_stats_next() call.
+ * @param controller Name of the controller for which stats are requested.
+ * @param path Path to control group, relative to hierarchy root.
+ * @param handle Handle to be used during iteration.
+ * @param stat Returned first item in the stats file.
+ * @return #ECGEOF when the stats file is empty.
  */
 int cgroup_read_stats_begin(const char *controller, const char *path, void **handle,
                                struct cgroup_stat *stat);
 
 /**
  * Read the next stat value.
- * @handle: Handle to be used during iteration.
- * @stat: Stats values will be filled and returned here.
+ * @param handle Handle to be used during iteration.
+ * @param stat Returned next item in the stats file.
+ * @return #ECGEOF when the iterator finishes getting the list of stats.
  */
 int cgroup_read_stats_next(void **handle, struct cgroup_stat *stat);
 
+/**
+ * Release the iterator.
+ */
 int cgroup_read_stats_end(void **handle);
 
 /**
- * Read the tasks file to get the list of tasks in a cgroup
- * @cgroup: Name of the cgroup
- * @controller: Name of the cgroup subsystem
- * @handle: Handle to be used in the iteration
- * @pid: The pid read from the tasks file. Will be filled in by the API
+ * @}
+ *
+ * @name List all tasks in a group
+ * Use following functions to read @c tasks file of a group.
+ * @{
+ */
+
+/**
+ * Read the tasks file to get the list of tasks in a cgroup.
+ * @param cgroup Name of the cgroup.
+ * @param controller Name of the cgroup subsystem.
+ * @param handle Handle to be used in the iteration.
+ * @param pid The pid read from the tasks file.
+ * @return #ECGEOF when the group does not contain any tasks.
  */
 int cgroup_get_task_begin(const char *cgroup, const char *controller, void **handle,
                                                                pid_t *pid);
 
 /**
- * Read the next task value
- * @handle: The handle used for iterating
- * @pid: The variable where the value will be stored
+ * Read the next task value.
+ * @param handle The handle used for iterating.
+ * @param pid The variable where the value will be stored.
  *
- * return ECGEOF when the iterator finishes getting the list of tasks.
+ * @return #ECGEOF when the iterator finishes getting the list of tasks.
  */
 int cgroup_get_task_next(void **handle, pid_t *pid);
+
+/**
+ * Release the iterator.
+ */
 int cgroup_get_task_end(void **handle);
 
+/**
+ * @}
+ *
+ * @name List mounted controllers
+ * Use following function to list mounted controllers and to see, how they
+ * are mounted together in hierarchies.
+ * Use cgroup_get_all_controller_begin() (see later) to list all controllers,
+ * including those which are not mounted.
+ * @{
+ */
+
+/**
+ * Information about mounted controller.
+ */
+struct cgroup_mount_point {
+       /** Name of the controller. */
+       char name[FILENAME_MAX];
+       /** Mount point of the controller. */
+       char path[FILENAME_MAX];
+};
+
 /**
  * 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.
+ * mounted.
+ * @param handle Handle to be used for iteration.
+ * @param info The variable where the path to the controller is stored.
+ * @return #ECGEOF when no controllers are mounted.
  */
 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.
+
+/**
+ * Read the next mounted controller.
+ * While walking through the mount table, the controllers are
+ * returned in order of their mount points, i.e. controllers mounted together
+ * in one hierarchy are returned next to each other.
+ * @param handle Handle to be used for iteration.
+ * @param info The variable where the path to the controller is stored.
+ * @return #ECGEOF when all controllers were already returned.
  */
 int cgroup_get_controller_next(void **handle, struct cgroup_mount_point *info);
+
+/**
+ * Release the iterator.
+ */
 int cgroup_get_controller_end(void **handle);
 
 /**
- * Read the list of controllers from /proc/cgroups (not mounted included)
- * @param handle: Handle to be used for iteration.
- * @param info: The structure which contains all controller data
+ * @}
+ *
+ * @name List all controllers
+ * Use following functions to list all controllers, including those which are
+ * not mounted. The controllers are returned in the same order as in
+ * /proc/cgroups file, i.e. mostly random.
+ */
+
+/**
+ * Detailed information about available controller.
+ */
+struct controller_data {
+       /** Controller name. */
+       char name[FILENAME_MAX];
+       /**
+        * Hierarchy ID. Controllers with the same hierarchy ID
+        * are mounted together as one hierarchy. Controllers with
+        * ID 0 are not currently mounted anywhere.
+        */
+       int hierarchy;
+       /** Number of groups. */
+       int num_cgroups;
+       /** Enabled flag. */
+       int enabled;
+};
+
+/**
+ * Read the first of controllers from /proc/cgroups.
+ * @param handle Handle to be used for iteration.
+ * @param info The structure which will be filled with controller data.
  */
 int cgroup_get_all_controller_begin(void **handle,
        struct controller_data *info);
-/*
- * While walking through the mount table, the controllers will be
- * returned in the same order as is in /proc/cgroups file
+/**
+ * Read next controllers from /proc/cgroups.
+ * @param handle Handle to be used for iteration.
+ * @param info The structure which will be filled with controller data.
  */
 int cgroup_get_all_controller_next(void **handle, struct controller_data *info);
+
+/**
+ * Release the iterator
+ */
 int cgroup_get_all_controller_end(void **handle);
 
+/**
+ * @}
+ * @}
+ */
 __END_DECLS
 
 #endif /* _LIBCGROUP_ITERATORS_H */