File: //usr/include/libcgroup/groups.h
#ifndef _LIBCGROUP_GROUPS_H
#define _LIBCGROUP_GROUPS_H
#ifndef _LIBCGROUP_H_INSIDE
#error "Only <libcgroup.h> should be included directly."
#endif
#ifndef SWIG
#include <features.h>
#include <sys/types.h>
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* Flags for cgroup_delete_cgroup_ext().
*/
enum cgroup_delete_flag {
/**
* Ignore errors caused by migration of tasks to parent group.
*/
CGFLAG_DELETE_IGNORE_MIGRATION = 1,
/**
* Recursively delete all child groups.
*/
CGFLAG_DELETE_RECURSIVE = 2,
/**
* Delete the cgroup only if it is empty, i.e. it has no subgroups and
* no processes inside. This flag cannot be used with
* CGFLAG_DELETE_RECURSIVE.
*/
CGFLAG_DELETE_EMPTY_ONLY = 4,
};
/**
* @defgroup group_groups 2. Group manipulation API
* @{
*
* @name Basic infrastructure
* @{
* <tt>struct cgroup*</tt> is the heart of @c libcgroup API.
* The structure is opaque to applications, all access to the structure is
* through appropriate functions.
*
* The most important information is that <b> one <tt>struct cgroup*</tt> can
* represent zero, one or more real control groups in kernel</b>.
* The <tt>struct cgroup*</tt> is identified by name of the group, which must be
* set by cgroup_new_cgroup(). Multiple controllers (aka subsystems) can be
* attached to one <tt>struct cgroup*</tt> using cgroup_add_controller(). These
* controllers <b>can belong to different hierarchies</b>.
*
* This approach is different to the one in the Linux kernel - a control group
* must be part of exactly one hierarchy there. In @c libcgroup, a group can be
* part of multiple hierarchies, as long as the group name is the same.
*
* @par Example:
* Let there be following control groups:
* @code
* cpu,cpuacct:/
* cpu,cpuacct:/foo
* cpu,cpuacct:/bar
* freezer:/
* freezer:/foo
* @endcode
* I.e. there is @c cpu and @c cpuacct controller mounted together in one
* hierarchy, with @c foo and @c bar groups. In addition, @c freezer is
* mounted as separate hierarchy, with only one @c foo group.
*
* @par
* Following code creates <tt>struct cgroup*</tt> structure, which represents
* one group <tt>cpu,cpuacct:/foo</tt>:
* @code
* struct cgroup *foo = cgroup_new_cgroup("foo");
* cgroup_add_controller(foo, "cpu");
* @endcode
* Now, you can call e.g. cgroup_delete_cgroup() and the group is deleted from
* the hierarchy. You can note that it's enough to add only one controller to
* the group to fully identify a group in <tt>cpu,cpuacct</tt> hierarchy.
*
* @par
* Following code creates <tt>struct cgroup*</tt> structure, which represents
* @b two groups, <tt>cpu,cpuacct:/foo</tt> and <tt>freezer:/foo</tt>:
* @code
* struct cgroup *foo = cgroup_new_cgroup("foo");
* cgroup_add_controller(foo, "cpu");
* cgroup_add_controller(foo, "freezer");
* @endcode
* Now, if you call e.g. cgroup_delete_cgroup(), the group gets deleted from
* @b both hierarchies.
*
* @todo add some propaganda what's so great on this approach... I personally
* think it is broken and confusing (see TODOs below).
*
* Following functions are provided to create/destroy various libcgroup
* structures. Please note that none of these functions actually create or
* delete a cgroup in kernel!
*/
/**
* @struct cgroup
*
* Structure describing one or more control groups. The structure is opaque to
* applications.
*/
struct cgroup;
/**
* @struct cgroup_controller
* Structure describing a controller attached to one struct @c cgroup, including
* parameters of the group and their values. The structure is opaque to
* applications.
* @see groups
*/
struct cgroup_controller;
/**
* Uninitialized file/directory permissions used for task/control files.
*/
#define NO_PERMS (-1U)
/**
* Uninitialized UID/GID used for task/control files.
*/
#define NO_UID_GID (-1U)
/**
* Allocate new cgroup structure. This function itself does not create new
* control group in kernel, only new <tt>struct cgroup</tt> inside libcgroup!
*
* @param name Path to the group, relative from root group. Use @c "/" or @c "."
* for the root group itself and @c "/foo/bar/baz" or @c "foo/bar/baz" for
* subgroups.
* @todo suggest one preferred way, either "/foo" or "foo".
* @returns Created group or NULL on error.
*/
struct cgroup *cgroup_new_cgroup(const char *name);
/**
* Attach new controller to cgroup. This function just modifies internal
* libcgroup structure, not the kernel control group.
*
* @param cgroup
* @param name Name of the controller, e.g. "freezer".
* @return Created controller or NULL on error.
*/
struct cgroup_controller *cgroup_add_controller(struct cgroup *cgroup,
const char *name);
/**
* Attach all mounted controllers to given cgroup. This function just modifies
* internal libcgroup structure, not the kernel control group.
*
* @param cgroup
* @return zero or error number
*/
int cgroup_add_all_controllers(struct cgroup *cgroup);
/**
* Return appropriate controller from given group.
* The controller must be added before using cgroup_add_controller() or loaded
* from kernel using cgroup_get_cgroup().
* @param cgroup
* @param name Name of the controller, e.g. "freezer".
*/
struct cgroup_controller *cgroup_get_controller(struct cgroup *cgroup,
const char *name);
/**
* Free internal @c cgroup structure. This function frees also all controllers
* attached to the @c cgroup, including all parameters and their values.
* @param cgroup
*/
void cgroup_free(struct cgroup **cgroup);
/**
* Free internal list of controllers from the group.
* @todo should this function be public???
* @param cgroup
*/
void cgroup_free_controllers(struct cgroup *cgroup);
/**
* @}
* @name Group manipulation API
* Using following functions you can create and remove control groups and
* change their parameters.
* @note All access to kernel is through previously mounted cgroup filesystems.
* @c libcgroup does not mount/unmount anything for you.
* @{
*/
/**
* Physically create a control group in kernel. The group is created in all
* hierarchies, which cover controllers added by cgroup_add_controller().
* All parameters set by cgroup_add_value_* functions are written.
* The created groups has owner which was set by cgroup_set_uid_gid() and
* permissions set by cgroup_set_permissions.
* @param cgroup
* @param ignore_ownership When nozero, all errors are ignored when setting
* owner of the group and/or its tasks file.
* @todo what is ignore_ownership good for?
* @retval #ECGROUPNOTEQUAL if not all specified controller parameters
* were successfully set.
*/
int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership);
/**
* Physically create new control group in kernel, with all parameters and values
* copied from its parent group. The group is created in all hierarchies, where
* the parent group exists. I.e. following code creates subgroup in all
* hierarchies, because all of them have root (=parent) group.
* @code
* struct cgroup *foo = cgroup_new_cgroup("foo");
* cgroup_create_cgroup_from_parent(foo, 0);
* @endcode
* @todo what is this good for? Why the list of controllers added by
* cgroup_add_controller() is not used, like in cgroup_create_cgroup()? I can't
* crate subgroup of root group in just one hierarchy with this function!
*
* @param cgroup The cgroup to create. Only it's name is used, everything else
* is discarded.
* @param ignore_ownership When nozero, all errors are ignored when setting
* owner of the group and/or its tasks file.
* @todo what is ignore_ownership good for?
* @retval #ECGROUPNOTEQUAL if not all inherited controller parameters
* were successfully set (this is expected).
*/
int cgroup_create_cgroup_from_parent(struct cgroup *cgroup,
int ignore_ownership);
/**
* Physically modify a control group in kernel. All parameters added by
* cgroup_add_value_ or cgroup_set_value_ are written.
* Currently it's not possible to change and owner of a group.
*
* @param cgroup
*/
int cgroup_modify_cgroup(struct cgroup *cgroup);
/**
* Physically remove a control group from kernel. The group is removed from
* all hierarchies, which cover controllers added by cgroup_add_controller()
* or cgroup_get_cgroup(). All tasks inside the group are automatically moved
* to parent group.
*
* The group being removed must be empty, i.e. without subgroups. Use
* cgroup_delete_cgroup_ext() for recursive delete.
*
* @param cgroup
* @param ignore_migration When nozero, all errors are ignored when migrating
* tasks from the group to the parent group.
* @todo what is ignore_migration good for? rmdir() will fail if tasks were not moved.
*/
int cgroup_delete_cgroup(struct cgroup *cgroup, int ignore_migration);
/**
* Physically remove a control group from kernel.
* All tasks are automatically moved to parent group.
* If #CGFLAG_DELETE_IGNORE_MIGRATION flag is used, the errors that occurred
* during the task movement are ignored.
* #CGFLAG_DELETE_RECURSIVE flag specifies that all subgroups should be removed
* too. If root group is being removed with this flag specified, all subgroups
* are removed but the root group itself is left undeleted.
* @see cgroup_delete_flag.
*
* @param cgroup
* @param flags Combination of CGFLAG_DELETE_* flags, which indicate what and
* how to delete.
*/
int cgroup_delete_cgroup_ext(struct cgroup *cgroup, int flags);
/**
* @}
* @name Other functions
* @{
* Helper functions to manipulate with control groups.
*/
/**
* Read all information regarding the group from kernel.
* Based on name of the group, list of controllers and all parameters and their
* values are read from all hierarchies, where a group with given name exists.
* All existing controllers are replaced. I.e. following code will fill @c root
* with controllers from all hierarchies, because the root group is available in
* all of them.
* @code
* struct cgroup *root = cgroup_new_cgroup("/");
* cgroup_get_cgroup(root);
* @endcode
*
* @todo what is this function good for? Why is not considered only the list of
* controllers attached by cgroup_add_controller()? What owners will return
* cgroup_get_uid_gid() if the group is in multiple hierarchies, each with
* different owner of tasks file?
*
* @param cgroup The cgroup to load. Only it's name is used, everything else
* is replaced.
*/
int cgroup_get_cgroup(struct cgroup *cgroup);
/**
* Copy all controllers, their parameters and values. Group name, permissions
* and ownerships are not coppied. All existing controllers
* in the source group are discarded.
*
* @param dst Destination group.
* @param src Source group.
*/
int cgroup_copy_cgroup(struct cgroup *dst, struct cgroup *src);
/**
* Compare names, owners, controllers, parameters and values of two groups.
*
* @param cgroup_a
* @param cgroup_b
*
* @retval 0 if the groups are the same.
* @retval #ECGROUPNOTEQUAL if the groups are not the same.
* @retval #ECGCONTROLLERNOTEQUAL if the only difference are controllers,
* parameters or their values.
*/
int cgroup_compare_cgroup(struct cgroup *cgroup_a, struct cgroup *cgroup_b);
/**
* Compare names, parameters and values of two controllers.
*
* @param cgca
* @param cgcb
*
* @retval 0 if the controllers are the same.
* @retval #ECGCONTROLLERNOTEQUAL if the controllers are not equal.
*/
int cgroup_compare_controllers(struct cgroup_controller *cgca,
struct cgroup_controller *cgcb);
/**
* Set owner of the group control files and the @c tasks file. This function
* modifies only @c libcgroup internal @c cgroup structure, use
* cgroup_create_cgroup() afterwards to create the group with given owners.
*
* @param cgroup
* @param tasks_uid UID of the owner of group's @c tasks file.
* @param tasks_gid GID of the owner of group's @c tasks file.
* @param control_uid UID of the owner of group's control files (i.e.
* parameters).
* @param control_gid GID of the owner of group's control files (i.e.
* parameters).
*/
int cgroup_set_uid_gid(struct cgroup *cgroup, uid_t tasks_uid, gid_t tasks_gid,
uid_t control_uid, gid_t control_gid);
/**
* Return owners of the group's @c tasks file and control files.
* The data is read from @c libcgroup internal @c cgroup structure, use
* cgroup_set_uid_gid() or cgroup_get_cgroup() to fill it.
*/
int cgroup_get_uid_gid(struct cgroup *cgroup, uid_t *tasks_uid,
gid_t *tasks_gid, uid_t *control_uid, gid_t *control_gid);
/**
* Stores given file permissions of the group's control and tasks files
* into the @c cgroup data structure. Use NO_PERMS if permissions shouldn't
* be changed or a value which applicable to chmod(2). Please note that
* the given permissions are masked with the file owner's permissions.
* For example if a control file has permissions 640 and control_fperm is
* 471 the result will be 460.
* @param cgroup
* @param control_dperm Directory permission for the group.
* @param control_fperm File permission for the control files.
* @param task_fperm File permissions for task file.
*/
void cgroup_set_permissions(struct cgroup *cgroup,
mode_t control_dperm, mode_t control_fperm,
mode_t task_fperm);
/**
* @}
* @name Group parameters
* These are functions can read or modify parameter of a group.
* @note All these functions read/write parameters to @c libcgorup internal
* structures. Use cgroup_get_cgroup() to load parameters from kernel to these
* internal structures and cgroup_modify_cgroup() or cgroup_create_cgroup() to
* write changes to kernel.
* @{
*/
/**
* Add parameter and its value to internal @c libcgroup structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*
*/
int cgroup_add_value_string(struct cgroup_controller *controller,
const char *name, const char *value);
/**
* Add parameter and its value to internal @c libcgroup structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
* Content of the value is copied to internal structures and is not needed
* after return from the function.
*
* @param controller
* @param name Name of the parameter.
* @param value
*
*/
int cgroup_add_value_int64(struct cgroup_controller *controller,
const char *name, int64_t value);
/**
* Add parameter and its value to internal @c libcgroup structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*
*/
int cgroup_add_value_uint64(struct cgroup_controller *controller,
const char *name, u_int64_t value);
/**
* Add parameter and its value to internal @c libcgroup structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*
*/
int cgroup_add_value_bool(struct cgroup_controller *controller,
const char *name, bool value);
/**
* Read a parameter value from @c libcgroup internal structures.
* Use @c cgroup_get_cgroup() to fill these structures with data from kernel.
* It's up to the caller to free returned value.
*
* This function works only for 'short' parameters. Use
* cgroup_read_stats_begin(), cgroup_read_stats_next() and
* cgroup_read_stats_end() to read @c stats parameter, which can be longer
* than libcgroup's internal buffers.
* @todo rephrase, it's too vague... How big is the buffer actually?
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_get_value_string(struct cgroup_controller *controller,
const char *name, char **value);
/**
* Read a parameter value from @c libcgroup internal structures.
* Use @c cgroup_get_cgroup() to fill these structures with data from kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_get_value_int64(struct cgroup_controller *controller,
const char *name, int64_t *value);
/**
* Read a parameter value from @c libcgroup internal structures.
* Use @c cgroup_get_cgroup() to fill these structures with data from kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_get_value_uint64(struct cgroup_controller *controller,
const char *name, u_int64_t *value);
/**
* Read a parameter value from @c libcgroup internal structures.
* Use @c cgroup_get_cgroup() to fill these structures with data from kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_get_value_bool(struct cgroup_controller *controller,
const char *name, bool *value);
/**
* Set a parameter value in @c libcgroup internal structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_set_value_string(struct cgroup_controller *controller,
const char *name, const char *value);
/**
* Set a parameter value in @c libcgroup internal structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
* Content of the value is copied to internal structures and is not needed
* after return from the function.
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_set_value_int64(struct cgroup_controller *controller,
const char *name, int64_t value);
/**
* Set a parameter value in @c libcgroup internal structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_set_value_uint64(struct cgroup_controller *controller,
const char *name, u_int64_t value);
/**
* Set a parameter value in @c libcgroup internal structures.
* Use cgroup_modify_cgroup() or cgroup_create_cgroup() to write it to kernel.
*
* @param controller
* @param name Name of the parameter.
* @param value
*/
int cgroup_set_value_bool(struct cgroup_controller *controller,
const char *name, bool value);
/**
* Return the number of variables for the specified controller in @c libcgroup
* internal structures. Use cgroup_get_cgroup() to fill these structures with
* data from kernel. Use this function together with cgroup_get_value_name()
* to list all parameters of a group.
*
* @param controller
* @return Count of the parameters or -1 on error.
*/
int cgroup_get_value_name_count(struct cgroup_controller *controller);
/**
* Return the name of parameter of controller at given index.
* The index goes from 0 to cgroup_get_value_name_count()-1.
* Use this function to list all parameter of the controller.
*
* @note The returned value is pointer to internal @c libcgroup structure,
* do not free it.
*
* @param controller
* @param index Index of the parameter.
* @return Name of the parameter.
*/
char *cgroup_get_value_name(struct cgroup_controller *controller, int index);
/**
* Get the list of process in a cgroup. This list is guaranteed to
* be sorted. It is not necessary that it is unique.
* @param name The name of the cgroup
* @param controller The name of the controller
* @param pids The list of pids. Should be uninitialized when passed
* to the API. Should be freed by the caller using free.
* @param size The size of the pids array returned by the API.
*/
int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size);
/**
* Change permission of files and directories of given group
* @param cgroup The cgroup which permissions should be changed
* @param dir_mode The permission mode of group directory
* @param dirm_change Denotes whether the directory change should be done
* @param file_mode The permission mode of group files
* @param filem_change Denotes whether the directory change should be done
*/
int cg_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode,
int dirm_change, mode_t file_mode, int filem_change);
/**
* Get the name of the cgroup from a given cgroup
* @param cgroup The cgroup whose name is needed
*/
char *cgroup_get_cgroup_name(struct cgroup *cgroup);
/**
* @}
* @}
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _LIBCGROUP_GROUPS_H */