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&#174; 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&#174; 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

Reply via email to