#ifndef _LIBCGROUP_ITERATORS_H #define _LIBCGROUP_ITERATORS_H #ifndef _LIBCGROUP_H_INSIDE #error "Only should be included directly." #endif #ifndef SWIG #include #include #include #endif __BEGIN_DECLS /** * @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 * void* handle pointer, which is managed internally by @c libcgroup. * Each iterator provides at least these functions: * - int iterator_name_begin(void **handle, my_type *item) * - 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. * - int iterator_name_next(void **handle, my_type *item) * - 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. * - void iterator_name_end(void **handle) * - Free any data associated with the iterator. This function must be * called even when iterator_name_begin() 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 { /** * 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. @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; }; /** * Walk through the directory tree for the specified controller. * 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 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); /** * 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 value of the given variable for the specified * controller and control group. * The value is read up to newline character or at most max-1 characters, * whichever comes first (i.e. similar to fgets()). * @param controller Name of the controller for which stats are requested. * @param path Path to control group, relative to hierarchy root. * @param name is variable name. * @param handle Handle to be used during iteration. * @param buffer Buffer to read the value into. * The buffer is always zero-terminated. * @param max Maximal lenght of the buffer * @return #ECGEOF when the stats file is empty. */ int cgroup_read_value_begin(const char *controller, const char *path, char *name, void **handle, char *buffer, int max); /** * Read the next string from the given variable handle * which is generated by cgroup_read_stats_begin() function. * the value is read up to newline character or at most max-1 characters, * whichever comes first (i.e. similar to fgets()) per * cgroup_read_stats_next() call * @param handle Handle to be used during iteration. * @param data returned the string. * @param buffer Buffer to read the value into. * The buffer is always zero-terminated. * @param max Maximal lenght of the buffer * @return #ECGEOF when the iterator finishes getting the list of stats. */ int cgroup_read_value_next(void **handle, char *buffer, int max); /** * Release the iterator. */ int cgroup_read_value_end(void **handle); /** * @} * * @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. * @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); /** * @} * * @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. * @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. */ 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. * @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); /** * 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); /** * @} * * @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); /** * 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); /** * @} * * @name List all mount points of a controller. * Use following functions to list all mount points of a hierarchy with given * controller. */ /** * Read the first mount point of the hierarchy with given controller. * The first is the same as the mount point returned by * cgroup_get_subsys_mount_point(). * @param handle Handle to be used for iteration. * @param controller Controller name. * @param path Buffer to fill the path into. The buffer must be at least * FILENAME_MAX characters long. */ int cgroup_get_subsys_mount_point_begin(const char *controller, void **handle, char *path); /** * Read next mount point of the hierarchy with given controller. * @param handle Handle to be used for iteration. * @param path Buffer to fill the path into. The buffer must be at least * FILENAME_MAX characters long. */ int cgroup_get_subsys_mount_point_next(void **handle, char *path); /** * Release the iterator. */ int cgroup_get_subsys_mount_point_end(void **handle); /** * @} * @} */ __END_DECLS #endif /* _LIBCGROUP_ITERATORS_H */