diff options
author | Jan Safranek <jsafrane@redhat.com> | 2010-03-29 12:00:42 +0200 |
---|---|---|
committer | Jan Safranek <jsafrane@redhat.com> | 2010-03-29 12:00:42 +0200 |
commit | f07927f590cc88199573cedb3a77b600e0f08cde (patch) | |
tree | 5698d2535ec8589ab0741742d0d87686ae481ddd | |
parent | 25ea9f6791ced27cfe8d24de4f3560b814c640b9 (diff) | |
download | libcg-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.h | 358 |
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 */ |