Sorry, wrong mailing list... :( Please ignore. Jan
On 03/11/2010 04:18 PM, Jan Safranek wrote: > The patch is the same as before, now it includes Makwfile and > .spec changes. I tested it compiles, make dist produces tarball > with all headers, so does also the rpm. 'make' should automatically > catch all changes in new headers and recompile dependent (=all) sources > when any header changes. > > Split the big header file to smaller ones. The ultimate goal behind this is > to document each macro/enum/struct/function with doxygen comments and > having all of them in one file would lead to really huge one. > > I tried to distribute functions to groups with similar functionality.This > structure is also base of future doxygen documentation - I'd like > to have one page for each include file. E.g. there would be 'Iterators' page, > with some overview and maybe examples how to use our iterator handles + list > of > all iterator functions with their description. Dtto for all other files - so > the > functions in a header file should be composed in some 'natural' and > 'reader-friendly' way. > > libcgroup.h > - does not declare anything, it just includes all the other files. In > future, it might contain base of doxygen documentation (some > introduction etc.) > > libcgroup/base.h > - global macros and types, included by all other headers. Maybe it would be > good idea to have this file without function declarations? > > libcgroup/config.h > - configuration reading/unloading > > libcgroup/groups.h > - group manipulation stuff (create/modify/delete/free, incl. controllers > and > get/set values) > > libcgroup/iterators.h > - various walks, *_begin/next/end > > libcgroup/tasks.h > - task classification, incl. rules cache manipulation > > I am still not satisfied with function declarations in 'base.h', especially > cgroup_get_subsys_mount_point... Should there be 'util.h' with such > functions? > > Feel free to suggest better groups and/or names. Consequences of this decision > will be there for a long time and I'd want to do it right at the first > attempt. > > There is no automake/autoconf stuff in this patch, I'll make sure these new > files gets distributed and installed if we agree on content of the files. > Still, current version should be fully compilable. > > In addition, I probably removed some #includes, which are not needed now when > looking for the minimal #include set to build the project. I also hope I did > not > miss any function declaration or macro... > > Signed-off-by: Jan Safranek<jsafr...@redhat.com> > --- > > dist/libcgroup.spec.in | 1 > include/Makefile.am | 4 > include/libcgroup.h | 469 > ----------------------------------------- > include/libcgroup/base.h | 88 ++++++++ > include/libcgroup/config.h | 16 + > include/libcgroup/groups.h | 106 +++++++++ > include/libcgroup/iterators.h | 170 +++++++++++++++ > include/libcgroup/tasks.h | 133 ++++++++++++ > src/api.c | 1 > src/tools/cgcreate.c | 1 > tests/libcg_ba.cpp | 1 > 11 files changed, 524 insertions(+), 466 deletions(-) > create mode 100644 include/libcgroup/base.h > create mode 100644 include/libcgroup/config.h > create mode 100644 include/libcgroup/groups.h > create mode 100644 include/libcgroup/iterators.h > create mode 100644 include/libcgroup/tasks.h > > diff --git a/dist/libcgroup.spec.in b/dist/libcgroup.spec.in > index 27ab880..33ddcf4 100644 > --- a/dist/libcgroup.spec.in > +++ b/dist/libcgroup.spec.in > @@ -120,6 +120,7 @@ fi > %files devel > %defattr(-,root,root,-) > %{_includedir}/libcgroup.h > +%{_includedir}/libcgroup/*.h > %{_libdir}/libcgroup.* > %doc COPYING INSTALL > > diff --git a/include/Makefile.am b/include/Makefile.am > index 2733f09..853918d 100644 > --- a/include/Makefile.am > +++ b/include/Makefile.am > @@ -1,2 +1,2 @@ > -include_HEADERS = libcgroup.h > - > +# Using 'nobase_', we what groups.h in /usr/include/libcgroup/ directory > +nobase_include_HEADERS = libcgroup.h libcgroup/base.h libcgroup/groups.h > libcgroup/tasks.h libcgroup/iterators.h libcgroup/config.h > diff --git a/include/libcgroup.h b/include/libcgroup.h > index 2cac820..279e573 100644 > --- a/include/libcgroup.h > +++ b/include/libcgroup.h > @@ -16,469 +16,10 @@ > #ifndef _LIBCG_H > #define _LIBCG_H > > -#include<features.h> > - > -__BEGIN_DECLS > - > -#include<grp.h> > -#include<stdbool.h> > -#include<stdio.h> > -#include<sys/types.h> > -#include<linux/cn_proc.h> > - > -/* Maximum number of mount points/controllers */ > -#define MAX_MNT_ELEMENTS 8 > -/* Estimated number of groups created */ > -#define MAX_GROUP_ELEMENTS 128 > - > -/* > - * NOTE: Wide characters are not supported at the moment. Wide character > support > - * would require us to use a scanner/parser that can parse beyond ASCII > - */ > - > -/* Definitions for the uid and gid members of a cgroup_rules */ > -#define CGRULE_INVALID (-1) > -#define CGRULE_WILD (-2) > - > -#define CGRULE_SUCCESS_STORE_PID "SUCCESS_STORE_PID" > - > -/* Flags for cgroup_change_cgroup_uid_gid() */ > -enum cgflags { > - CGFLAG_USECACHE = 0x01, > -}; > - > -enum cgroup_errors { > - ECGROUPNOTCOMPILED=50000, > - ECGROUPNOTMOUNTED, > - ECGROUPNOTEXIST, > - ECGROUPNOTCREATED, > - ECGROUPSUBSYSNOTMOUNTED, > - ECGROUPNOTOWNER, > - ECGROUPMULTIMOUNTED,/* Controllers bound to different mount points */ > - ECGROUPNOTALLOWED, /* This is the stock error. Default error. */ > - ECGMAXVALUESEXCEEDED, > - ECGCONTROLLEREXISTS, > - ECGVALUEEXISTS, > - ECGINVAL, > - ECGCONTROLLERCREATEFAILED, > - ECGFAIL, > - ECGROUPNOTINITIALIZED, > - ECGROUPVALUENOTEXIST, > - /* Represents error coming from other libraries like glibc. libcgroup > - * users need to check errno upon encoutering ECGOTHER. > - */ > - ECGOTHER, /* OS error, see errno */ > - ECGROUPNOTEQUAL, > - ECGCONTROLLERNOTEQUAL, > - ECGROUPPARSEFAIL, /* Failed to parse rules configuration file. */ > - ECGROUPNORULES, /* Rules list does not exist. */ > - ECGMOUNTFAIL, > - ECGSENTINEL, /* Please insert further error codes above this */ > - ECGEOF, /* End of file, iterator */ > - ECGCONFIGPARSEFAIL,/* Failed to parse config file (cgconfig.conf). */ > - ECGNAMESPACEPATHS, > - ECGNAMESPACECONTROLLER, > - ECGMOUNTNAMESPACE, > -}; > - > -#define ECGRULESPARSEFAIL ECGROUPPARSEFAIL > - > -/* > - * 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. > - */ > -enum cgroup_walk_type { > - CGROUP_WALK_TYPE_PRE_DIR = 0x1, /* Pre Order Directory */ > - CGROUP_WALK_TYPE_POST_DIR = 0x2, /* Post Order Directory */ > -}; > - > -enum cgroup_file_type { > - CGROUP_FILE_TYPE_FILE, /* File */ > - CGROUP_FILE_TYPE_DIR, /* Directory */ > - CGROUP_FILE_TYPE_OTHER, /* Directory */ > -}; > - > -enum cgroup_daemon_type { > - CGROUP_DAEMON_UNCHANGE_CHILDREN = 0x1, > -}; > - > -/** > - * 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, > -}; > - > -struct cgroup_file_info { > - enum cgroup_file_type type; > - const char *path; > - const char *parent; > - const char *full_path; > - short depth; > -}; > - > -#define CG_NV_MAX 100 > -#define CG_CONTROLLER_MAX 100 > -/* this is NOT ENOUGH for stat variables */ > -#define CG_VALUE_MAX 100 > -/* Max number of mounted hierarchies. Event if one controller is mounted per > - * hier, it can not exceed CG_CONTROLLER_MAX > - */ > -#define CG_HIER_MAX CG_CONTROLLER_MAX > - > -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; > -}; > - > -/* Functions and structures that can be used by the application*/ > -struct cgroup; > -struct cgroup_controller; > - > -int cgroup_init(void); > -int cgroup_attach_task(struct cgroup *cgroup); > -int cgroup_modify_cgroup(struct cgroup *cgroup); > -int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership); > -int cgroup_delete_cgroup(struct cgroup *cgroup, int ignore_migration); > -int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid); > -int cgroup_get_cgroup(struct cgroup *cgroup); > -int cgroup_create_cgroup_from_parent(struct cgroup *cgroup, int > ignore_ownership); > -int cgroup_copy_cgroup(struct cgroup *dst, struct cgroup *src); > - > -/** > - * Delete control group. > - * 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. > - * > - * @param cgroup Group to delete. > - * @param flags Combination of CGFLAG_DELETE_* flags, which indicate what > and > - * how to delete. > - */ > -int cgroup_delete_cgroup_ext(struct cgroup *cgroup, int flags); > - > -/** > - * Changes the cgroup of a program based on the rules in the config file. > - * If a rule exists for the given UID, GID or PROCESS NAME, then the given > - * PID is placed into the correct group. By default, this function parses > - * the configuration file each time it is called. > - * > - * The flags can alter the behavior of this function: > - * CGFLAG_USECACHE: Use cached rules instead of parsing the config file > - * > - * This function may NOT be thread safe. > - * @param uid The UID to match > - * @param gid The GID to match > - * @param procname The PROCESS NAME to match > - * @param pid The PID of the process to move > - * @param flags Bit flags to change the behavior, as defined above > - * @return 0 on success,> 0 on error > - * TODO: Determine thread-safeness and fix of not safe. > - */ > -int cgroup_change_cgroup_flags(const uid_t uid, const gid_t gid, > - char *procname, const pid_t pid, const int flags); > - > -/** > - * Changes the cgroup of a program based on the rules in the config file. > If a > - * rule exists for the given UID or GID, then the given PID is placed into > the > - * correct group. By default, this function parses the configuration file > each > - * time it is called. > - * > - * The flags can alter the behavior of this function: > - * CGFLAG_USECACHE: Use cached rules instead of parsing the config file > - * > - * This function may NOT be thread safe. > - * @param uid The UID to match > - * @param gid The GID to match > - * @param pid The PID of the process to move > - * @param flags Bit flags to change the behavior, as defined above > - * @return 0 on success,> 0 on error > - * TODO: Determine thread-safeness and fix if not safe. > - */ > -int cgroup_change_cgroup_uid_gid_flags(const uid_t uid, const gid_t gid, > - const pid_t pid, const int flags); > - > -/** > - * Provides backwards-compatibility with older versions of the API. This > - * function is deprecated, and cgroup_change_cgroup_uid_gid_flags() should be > - * used instead. In fact, this function simply calls the newer one with > flags > - * set to 0 (none). > - * @param uid The UID to match > - * @param gid The GID to match > - * @param pid The PID of the process to move > - * @return 0 on success,> 0 on error > - * > - */ > -int cgroup_change_cgroup_uid_gid(uid_t uid, gid_t gid, pid_t pid); > - > -/** > - * Changes the cgroup of a program based on the path provided. In this case, > - * the user must already know into which cgroup the task should be placed and > - * no rules will be parsed. > - * > - * returns 0 on success. > - */ > -int cgroup_change_cgroup_path(char *path, pid_t pid, char *controllers[]); > - > -/** > - * Print the cached rules table. This function should be called only after > - * first calling cgroup_parse_config(), but it will work with an empty rule > - * list. > - * @param fp The file stream to print to > - */ > -void cgroup_print_rules_config(FILE *fp); > - > -/** > - * Reloads the rules list, using the given configuration file. This function > - * is probably NOT thread safe (calls cgroup_parse_rules_config()). > - * @return 0 on success,> 0 on failure > - */ > -int cgroup_reload_cached_rules(void); > - > -/** > - * Initializes the rules cache. > - * @return 0 on success,> 0 on failure > - */ > -int cgroup_init_rules_cache(void); > - > -/** > - * Get the current cgroup path where the task specified by pid_t pid > - * has been classified > - */ > -int cgroup_get_current_controller_path(pid_t pid, const char *controller, > - char **current_path); > -/** > - * Return error corresponding to @code in human readable format. > - * @code: error code for which the corresponding error string is to be > - * returned > - */ > -const char *cgroup_strerror(int code); > - > -/** > - * Return last errno, which caused ECGOTHER error. > - */ > -int cgroup_get_last_errno(); > - > -/** > - * 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 > - */ > -int cgroup_walk_tree_begin(char *controller, char *base_path, const 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. > - */ > -int cgroup_walk_tree_next(const int depth, void **handle, > - struct cgroup_file_info *info, int base_level); > -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 > - * > - */ > -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. > - */ > -int cgroup_read_stats_begin(char *controller, 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. > - */ > -int cgroup_read_stats_next(void **handle, struct cgroup_stat *stat); > - > -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 > - */ > -int cgroup_get_task_begin(char *cgroup, char *controller, void **handle, > - pid_t *pid); > - > -/** > - * Register the unchanged process to a cgrulesengd daemon. > - * If the daemon does not work, this function returns 0 as success. > - * @param pid: The process id > - * @param flags Bit flags to change the behavior, as defined above > - * @return 0 on success,> 0 on error. > - */ > -int cgroup_register_unchanged_process(pid_t pid, int flags); > - > -/** > - * Read the next task value > - * @handle: The handle used for iterating > - * @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); > -int cgroup_get_task_end(void **handle); > - > -/** > - * 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. > - */ > -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. > - */ > -int cgroup_get_controller_next(void **handle, struct cgroup_mount_point > *info); > -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 > - */ > -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 > - */ > -int cgroup_get_all_controller_next(void **handle, struct controller_data > *info); > -int cgroup_get_all_controller_end(void **handle); > - > -/* > - * Reads the mount to table to give the mount point of a controller > - * @controller: Name of the controller > - * @mount_point: The string where the mount point is stored. Please note, > - * the caller must free mount_point. > - */ > -int cgroup_get_subsys_mount_point(char *controller, char **mount_point); > - > -/* The wrappers for filling libcg structures */ > - > -struct cgroup *cgroup_new_cgroup(const char *name); > -struct cgroup_controller *cgroup_add_controller(struct cgroup *cgroup, > - const char *name); > -void cgroup_free(struct cgroup **cgroup); > -void cgroup_free_controllers(struct cgroup *cgroup); > -int cgroup_add_value_string(struct cgroup_controller *controller, > - const char *name, const char *value); > -int cgroup_add_value_int64(struct cgroup_controller *controller, > - const char *name, int64_t value); > -int cgroup_add_value_uint64(struct cgroup_controller *controller, > - const char *name, u_int64_t value); > -int cgroup_add_value_bool(struct cgroup_controller *controller, > - const char *name, bool value); > -int cgroup_compare_cgroup(struct cgroup *cgroup_a, struct cgroup *cgroup_b); > -int cgroup_compare_controllers(struct cgroup_controller *cgca, > - struct cgroup_controller *cgcb); > -int cgroup_set_uid_gid(struct cgroup *cgroup, uid_t tasks_uid, gid_t > tasks_gid, > - uid_t control_uid, gid_t control_gid); > -int cgroup_get_uid_gid(struct cgroup *cgroup, uid_t *tasks_uid, > - gid_t *tasks_gid, uid_t *control_uid, gid_t *control_gid); > -int cgroup_get_value_string(struct cgroup_controller *controller, > - const char *name, char **value); > -int cgroup_set_value_string(struct cgroup_controller *controller, > - const char *name, const char *value); > -int cgroup_get_value_int64(struct cgroup_controller *controller, > - const char *name, int64_t *value); > -int cgroup_set_value_int64(struct cgroup_controller *controller, > - const char *name, int64_t value); > -int cgroup_get_value_uint64(struct cgroup_controller *controller, > - const char *name, u_int64_t *value); > -int cgroup_set_value_uint64(struct cgroup_controller *controller, > - const char *name, u_int64_t value); > -int cgroup_get_value_bool(struct cgroup_controller *controller, > - const char *name, bool *value); > -int cgroup_set_value_bool(struct cgroup_controller *controller, > - const char *name, bool value); > -struct cgroup_controller *cgroup_get_controller(struct cgroup *cgroup, > - const char *name); > - > -/** > - * Return the number of variables for the specified controller, if the > - * structure does not exist -1 is returned > - * @param controller Name of the controller for which stats are requested. > - */ > -int cgroup_get_value_name_count(struct cgroup_controller *controller); > - > -/** > - * Return the "index" variable for the specified controller, > - * the return value is the pointer to the internal structure so > - * don't dealocate it, or change the content of the memory space. > - * @param controller Name of the controller for which stats are requested. > - * @param index number of the variable. > - */ > -char *cgroup_get_value_name(struct cgroup_controller *controller, int index); > -/* > - * Config related stuff > - */ > -int cgroup_config_load_config(const char *pathname); > -int cgroup_unload_cgroups(void); > - > -__END_DECLS > +#include<libcgroup/base.h> > +#include<libcgroup/iterators.h> > +#include<libcgroup/groups.h> > +#include<libcgroup/tasks.h> > +#include<libcgroup/config.h> > > #endif /* _LIBCG_H */ > diff --git a/include/libcgroup/base.h b/include/libcgroup/base.h > new file mode 100644 > index 0000000..1bb9b38 > --- /dev/null > +++ b/include/libcgroup/base.h > @@ -0,0 +1,88 @@ > +#ifndef _LIBCG_BASE_H > +#define _LIBCG_BASE_H > + > +#include<features.h> > + > +__BEGIN_DECLS > + > +/* Maximum number of mount points/controllers */ > +#define MAX_MNT_ELEMENTS 8 > +/* Estimated number of groups created */ > +#define MAX_GROUP_ELEMENTS 128 > + > +enum cgroup_errors { > + ECGROUPNOTCOMPILED=50000, > + ECGROUPNOTMOUNTED, > + ECGROUPNOTEXIST, > + ECGROUPNOTCREATED, > + ECGROUPSUBSYSNOTMOUNTED, > + ECGROUPNOTOWNER, > + ECGROUPMULTIMOUNTED,/* Controllers bound to different mount points */ > + ECGROUPNOTALLOWED, /* This is the stock error. Default error. */ > + ECGMAXVALUESEXCEEDED, > + ECGCONTROLLEREXISTS, > + ECGVALUEEXISTS, > + ECGINVAL, > + ECGCONTROLLERCREATEFAILED, > + ECGFAIL, > + ECGROUPNOTINITIALIZED, > + ECGROUPVALUENOTEXIST, > + /* Represents error coming from other libraries like glibc. libcgroup > + * users need to check errno upon encoutering ECGOTHER. > + */ > + ECGOTHER, /* OS error, see errno */ > + ECGROUPNOTEQUAL, > + ECGCONTROLLERNOTEQUAL, > + ECGROUPPARSEFAIL, /* Failed to parse rules configuration file. */ > + ECGROUPNORULES, /* Rules list does not exist. */ > + ECGMOUNTFAIL, > + ECGSENTINEL, /* Please insert further error codes above this */ > + ECGEOF, /* End of file, iterator */ > + ECGCONFIGPARSEFAIL,/* Failed to parse config file (cgconfig.conf). */ > + ECGNAMESPACEPATHS, > + ECGNAMESPACECONTROLLER, > + ECGMOUNTNAMESPACE, > +}; > + > +#define ECGRULESPARSEFAIL ECGROUPPARSEFAIL > + > +#define CG_NV_MAX 100 > +#define CG_CONTROLLER_MAX 100 > +/* this is NOT ENOUGH for stat variables */ > +#define CG_VALUE_MAX 100 > +/* Max number of mounted hierarchies. Event if one controller is mounted per > + * hier, it can not exceed CG_CONTROLLER_MAX > + */ > +#define CG_HIER_MAX CG_CONTROLLER_MAX > + > + > + > +/* Functions and structures that can be used by the application*/ > +struct cgroup; > +struct cgroup_controller; > + > +int cgroup_init(void); > + > +/** > + * Return error corresponding to @code in human readable format. > + * @code: error code for which the corresponding error string is to be > + * returned > + */ > +const char *cgroup_strerror(int code); > + > +/** > + * Return last errno, which caused ECGOTHER error. > + */ > +int cgroup_get_last_errno(); > + > +/* > + * Reads the mount to table to give the mount point of a controller > + * @controller: Name of the controller > + * @mount_point: The string where the mount point is stored. Please note, > + * the caller must free mount_point. > + */ > +int cgroup_get_subsys_mount_point(char *controller, char **mount_point); > + > +__END_DECLS > + > +#endif /* _LIBCG_BASE_H */ > diff --git a/include/libcgroup/config.h b/include/libcgroup/config.h > new file mode 100644 > index 0000000..6fd8249 > --- /dev/null > +++ b/include/libcgroup/config.h > @@ -0,0 +1,16 @@ > +#ifndef _LIBCG_CONFIG_H > +#define _LIBCG_CONFIG_H > + > +#include<libcgroup/base.h> > + > +__BEGIN_DECLS > + > +/* > + * Config related stuff > + */ > +int cgroup_config_load_config(const char *pathname); > +int cgroup_unload_cgroups(void); > + > +__END_DECLS > + > +#endif /*_LIBCG_CONFIG_H*/ > diff --git a/include/libcgroup/groups.h b/include/libcgroup/groups.h > new file mode 100644 > index 0000000..ae540ed > --- /dev/null > +++ b/include/libcgroup/groups.h > @@ -0,0 +1,106 @@ > +#ifndef _LIBCG_GROUPS_H > +#define _LIBCG_GROUPS_H > + > +#include<libcgroup/base.h> > + > +#include<sys/types.h> > +#include<stdbool.h> > + > +__BEGIN_DECLS > + > +/** > + * 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, > +}; > + > +int cgroup_modify_cgroup(struct cgroup *cgroup); > +int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership); > +int cgroup_delete_cgroup(struct cgroup *cgroup, int ignore_migration); > +int cgroup_get_cgroup(struct cgroup *cgroup); > +int cgroup_create_cgroup_from_parent(struct cgroup *cgroup, int > ignore_ownership); > +int cgroup_copy_cgroup(struct cgroup *dst, struct cgroup *src); > + > +/** > + * Delete control group. > + * 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. > + * > + * @param cgroup Group to delete. > + * @param flags Combination of CGFLAG_DELETE_* flags, which indicate what > and > + * how to delete. > + */ > +int cgroup_delete_cgroup_ext(struct cgroup *cgroup, int flags); > + > +struct cgroup *cgroup_new_cgroup(const char *name); > +struct cgroup_controller *cgroup_add_controller(struct cgroup *cgroup, > + const char *name); > +void cgroup_free(struct cgroup **cgroup); > +void cgroup_free_controllers(struct cgroup *cgroup); > +int cgroup_compare_cgroup(struct cgroup *cgroup_a, struct cgroup *cgroup_b); > +int cgroup_compare_controllers(struct cgroup_controller *cgca, > + struct cgroup_controller *cgcb); > +struct cgroup_controller *cgroup_get_controller(struct cgroup *cgroup, > + const char *name); > + > +int cgroup_add_value_string(struct cgroup_controller *controller, > + const char *name, const char *value); > +int cgroup_add_value_int64(struct cgroup_controller *controller, > + const char *name, int64_t value); > +int cgroup_add_value_uint64(struct cgroup_controller *controller, > + const char *name, u_int64_t value); > +int cgroup_add_value_bool(struct cgroup_controller *controller, > + const char *name, bool value); > +int cgroup_set_uid_gid(struct cgroup *cgroup, uid_t tasks_uid, gid_t > tasks_gid, > + uid_t control_uid, gid_t control_gid); > +int cgroup_get_uid_gid(struct cgroup *cgroup, uid_t *tasks_uid, > + gid_t *tasks_gid, uid_t *control_uid, gid_t *control_gid); > +int cgroup_get_value_string(struct cgroup_controller *controller, > + const char *name, char **value); > +int cgroup_set_value_string(struct cgroup_controller *controller, > + const char *name, const char *value); > +int cgroup_get_value_int64(struct cgroup_controller *controller, > + const char *name, int64_t *value); > +int cgroup_set_value_int64(struct cgroup_controller *controller, > + const char *name, int64_t value); > +int cgroup_get_value_uint64(struct cgroup_controller *controller, > + const char *name, u_int64_t *value); > +int cgroup_set_value_uint64(struct cgroup_controller *controller, > + const char *name, u_int64_t value); > +int cgroup_get_value_bool(struct cgroup_controller *controller, > + const char *name, bool *value); > +int cgroup_set_value_bool(struct cgroup_controller *controller, > + const char *name, bool value); > +/** > + * Return the number of variables for the specified controller, if the > + * structure does not exist -1 is returned > + * @param controller Name of the controller for which stats are requested. > + */ > +int cgroup_get_value_name_count(struct cgroup_controller *controller); > + > +/** > + * Return the "index" variable for the specified controller, > + * the return value is the pointer to the internal structure so > + * don't dealocate it, or change the content of the memory space. > + * @param controller Name of the controller for which stats are requested. > + * @param index number of the variable. > + */ > +char *cgroup_get_value_name(struct cgroup_controller *controller, int index); > + > + > +__END_DECLS > + > +#endif /* _LIBCG_GROUPS_H */ > diff --git a/include/libcgroup/iterators.h b/include/libcgroup/iterators.h > new file mode 100644 > index 0000000..4e3b644 > --- /dev/null > +++ b/include/libcgroup/iterators.h > @@ -0,0 +1,170 @@ > +#ifndef _LIBCG_ITERATORS_H > +#define _LIBCG_ITERATORS_H > + > +#include<libcgroup/base.h> > + > +#include<sys/types.h> > +#include<stdio.h> > + > +__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. > + */ > +enum cgroup_walk_type { > + CGROUP_WALK_TYPE_PRE_DIR = 0x1, /* Pre Order Directory */ > + CGROUP_WALK_TYPE_POST_DIR = 0x2, /* Post Order Directory */ > +}; > + > +enum cgroup_file_type { > + CGROUP_FILE_TYPE_FILE, /* File */ > + CGROUP_FILE_TYPE_DIR, /* Directory */ > + CGROUP_FILE_TYPE_OTHER, /* Directory */ > +}; > +struct cgroup_file_info { > + enum cgroup_file_type type; > + const char *path; > + const char *parent; > + const char *full_path; > + short depth; > +}; > + > +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 > + */ > +int cgroup_walk_tree_begin(char *controller, char *base_path, const 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. > + */ > +int cgroup_walk_tree_next(const int depth, void **handle, > + struct cgroup_file_info *info, int base_level); > +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 > + * > + */ > +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. > + */ > +int cgroup_read_stats_begin(char *controller, 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. > + */ > +int cgroup_read_stats_next(void **handle, struct cgroup_stat *stat); > + > +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 > + */ > +int cgroup_get_task_begin(char *cgroup, 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 > + * > + * return ECGEOF when the iterator finishes getting the list of tasks. > + */ > +int cgroup_get_task_next(void **handle, pid_t *pid); > +int cgroup_get_task_end(void **handle); > + > +/** > + * 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. > + */ > +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. > + */ > +int cgroup_get_controller_next(void **handle, struct cgroup_mount_point > *info); > +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 > + */ > +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 > + */ > +int cgroup_get_all_controller_next(void **handle, struct controller_data > *info); > +int cgroup_get_all_controller_end(void **handle); > + > +__END_DECLS > + > +#endif /* _LIBCG_ITERATORS_H */ > diff --git a/include/libcgroup/tasks.h b/include/libcgroup/tasks.h > new file mode 100644 > index 0000000..dad5fa1 > --- /dev/null > +++ b/include/libcgroup/tasks.h > @@ -0,0 +1,133 @@ > +#ifndef _LIBCG_TASKS_H > +#define _LIBCG_TASKS_H > + > +#include<libcgroup/base.h> > + > +#include<stdbool.h> > + > +__BEGIN_DECLS > + > +/* Definitions for the uid and gid members of a cgroup_rules */ > +#define CGRULE_INVALID (-1) > +#define CGRULE_WILD (-2) > + > + > +#define CGRULE_SUCCESS_STORE_PID "SUCCESS_STORE_PID" > + > +/* Flags for cgroup_change_cgroup_uid_gid() */ > +enum cgflags { > + CGFLAG_USECACHE = 0x01, > +}; > + > +enum cgroup_daemon_type { > + CGROUP_DAEMON_UNCHANGE_CHILDREN = 0x1, > +}; > + > +int cgroup_attach_task(struct cgroup *cgroup); > +int cgroup_attach_task_pid(struct cgroup *cgroup, pid_t tid); > + > +/** > + * Changes the cgroup of a program based on the rules in the config file. > + * If a rule exists for the given UID, GID or PROCESS NAME, then the given > + * PID is placed into the correct group. By default, this function parses > + * the configuration file each time it is called. > + * > + * The flags can alter the behavior of this function: > + * CGFLAG_USECACHE: Use cached rules instead of parsing the config file > + * > + * This function may NOT be thread safe. > + * @param uid The UID to match > + * @param gid The GID to match > + * @param procname The PROCESS NAME to match > + * @param pid The PID of the process to move > + * @param flags Bit flags to change the behavior, as defined above > + * @return 0 on success,> 0 on error > + * TODO: Determine thread-safeness and fix of not safe. > + */ > +int cgroup_change_cgroup_flags(const uid_t uid, const gid_t gid, > + char *procname, const pid_t pid, const int flags); > + > +/** > + * Changes the cgroup of a program based on the rules in the config file. > If a > + * rule exists for the given UID or GID, then the given PID is placed into > the > + * correct group. By default, this function parses the configuration file > each > + * time it is called. > + * > + * The flags can alter the behavior of this function: > + * CGFLAG_USECACHE: Use cached rules instead of parsing the config file > + * > + * This function may NOT be thread safe. > + * @param uid The UID to match > + * @param gid The GID to match > + * @param pid The PID of the process to move > + * @param flags Bit flags to change the behavior, as defined above > + * @return 0 on success,> 0 on error > + * TODO: Determine thread-safeness and fix if not safe. > + */ > +int cgroup_change_cgroup_uid_gid_flags(const uid_t uid, const gid_t gid, > + const pid_t pid, const int flags); > + > +/** > + * Provides backwards-compatibility with older versions of the API. This > + * function is deprecated, and cgroup_change_cgroup_uid_gid_flags() should be > + * used instead. In fact, this function simply calls the newer one with > flags > + * set to 0 (none). > + * @param uid The UID to match > + * @param gid The GID to match > + * @param pid The PID of the process to move > + * @return 0 on success,> 0 on error > + * > + */ > +int cgroup_change_cgroup_uid_gid(uid_t uid, gid_t gid, pid_t pid); > + > +/** > + * Changes the cgroup of a program based on the path provided. In this case, > + * the user must already know into which cgroup the task should be placed and > + * no rules will be parsed. > + * > + * returns 0 on success. > + */ > +int cgroup_change_cgroup_path(char *path, pid_t pid, char *controllers[]); > + > +/** > + * Print the cached rules table. This function should be called only after > + * first calling cgroup_parse_config(), but it will work with an empty rule > + * list. > + * @param fp The file stream to print to > + */ > +void cgroup_print_rules_config(FILE *fp); > + > +/** > + * Reloads the rules list, using the given configuration file. This function > + * is probably NOT thread safe (calls cgroup_parse_rules_config()). > + * @return 0 on success,> 0 on failure > + */ > +int cgroup_reload_cached_rules(void); > + > +/** > + * Initializes the rules cache. > + * @return 0 on success,> 0 on failure > + */ > +int cgroup_init_rules_cache(void); > + > +/** > + * Get the current cgroup path where the task specified by pid_t pid > + * has been classified > + */ > +int cgroup_get_current_controller_path(pid_t pid, const char *controller, > + char **current_path); > + > +/** > + * Register the unchanged process to a cgrulesengd daemon. > + * If the daemon does not work, this function returns 0 as success. > + * @param pid: The process id > + * @param flags Bit flags to change the behavior, as defined above > + * @return 0 on success,> 0 on error. > + */ > +int cgroup_register_unchanged_process(pid_t pid, int flags); > + > +__END_DECLS > + > +#endif /* _LIBCG_TASKS_H */ > + > + > diff --git a/src/api.c b/src/api.c > index 169df2e..4525311 100644 > --- a/src/api.c > +++ b/src/api.c > @@ -50,6 +50,7 @@ > #include<libgen.h> > #include<assert.h> > #include<linux/un.h> > +#include<grp.h> > > /* > * The errno which happend the last time (have to be thread specific) > diff --git a/src/tools/cgcreate.c b/src/tools/cgcreate.c > index aeb94f4..616fa16 100644 > --- a/src/tools/cgcreate.c > +++ b/src/tools/cgcreate.c > @@ -23,6 +23,7 @@ > #include<sys/types.h> > #include<errno.h> > #include<unistd.h> > +#include<grp.h> > > #include "tools-common.h" > > diff --git a/tests/libcg_ba.cpp b/tests/libcg_ba.cpp > index c9994d6..322794b 100644 > --- a/tests/libcg_ba.cpp > +++ b/tests/libcg_ba.cpp > @@ -24,6 +24,7 @@ using namespace std; > #include<errno.h> > #include<stdlib.h> > #include<string.h> > +#include<grp.h> > > #include "../config.h" > > > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > Ipmitool-devel mailing list > Ipmitool-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/ipmitool-devel ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ Ipmitool-devel mailing list Ipmitool-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ipmitool-devel