summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Safranek <jsafrane@redhat.com>2010-03-29 12:00:42 +0200
committerJan Safranek <jsafrane@redhat.com>2010-03-29 12:00:42 +0200
commitf07927f590cc88199573cedb3a77b600e0f08cde (patch)
tree5698d2535ec8589ab0741742d0d87686ae481ddd
parent25ea9f6791ced27cfe8d24de4f3560b814c640b9 (diff)
downloadlibcg-f07927f590cc88199573cedb3a77b600e0f08cde.tar.gz
libcg-f07927f590cc88199573cedb3a77b600e0f08cde.tar.xz
libcg-f07927f590cc88199573cedb3a77b600e0f08cde.zip
Document the iterators
Signed-off-by: Jan Safranek <jsafrane@redhat.com>
-rw-r--r--include/libcgroup/iterators.h358
1 files changed, 269 insertions, 89 deletions
diff --git a/include/libcgroup/iterators.h b/include/libcgroup/iterators.h
index e8df12a..f572bec 100644
--- a/include/libcgroup/iterators.h
+++ b/include/libcgroup/iterators.h
@@ -11,164 +11,344 @@
__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 */