On 11/21/2012 01:10 PM, Ivana Hutarova Varekova wrote:
> Template cgroups mean control groups which are set in cgrules.conf file and
> the name contains % variable like %U (see cgrules.conf manual page for the
> whole list of variables).
>
> This patch change cgroup_change_cgroup_flags function. Now if the wanted
> group is template group and the group does not exist then
> cgroup_change_cgroup_flags create the control group on the fly .
>
> For now the created group can't be set - there is always used function
> cgroup_create_cgroup. This will be changed in other patch in this patchset.
>
> EXAMPLE:
> e.g.
> @students devices people/students/%U
> cgroup_change_cgroup_flags will create a cgroup /people/students/john if
> user john from group students run a command and the people does not exist yet.
> if /people/students group does not exist it will be created as well
>
>
> Signed-off-by: Ivana Hutarova Varekova <[email protected]>
> ---
>
> src/api.c | 175
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 175 insertions(+), 0 deletions(-)
>
> diff --git a/src/api.c b/src/api.c
> index ea75cca..178c19e 100644
> --- a/src/api.c
> +++ b/src/api.c
> @@ -2635,6 +2635,174 @@ static struct cgroup_rule
> *cgroup_find_matching_rule(uid_t uid,
> return ret;
> }
>
> +/* Procedure the existence of cgroup "prefix" is in subsystem controller_name
> + * return 0 on success
> + */
> +int cgroup_exist_in_subsystem(char *controller_name, char *prefix)
> +{
> + DIR *dir;
> + char path[FILENAME_MAX];
> +
> + pthread_rwlock_rdlock(&cg_mount_table_lock);
> + if (!cg_build_path_locked(prefix, path, controller_name)) {
> + pthread_rwlock_unlock(&cg_mount_table_lock);
> + return 1;
> + }
> + pthread_rwlock_unlock(&cg_mount_table_lock);
> +
> + dir = opendir(path);
> + if (dir == NULL) {
> + /* cgroup in wanted subsystem does not exist */
> + return 1;
> + } else {
> + /* cgroup in wanted subsystem exists */
> + return 0;
> + closedir(dir);
> + }
> +}
> +
> +/* auxiliary function return a pointer to the string
> + * which is copy of input string and end with the backslash
backslash -> slash
> + */
> +char *cgroup_copy_with_backslash(char *input)
> +{
> + char *output;
> + int len = strlen(input);
> +
> + /* if input does not end with '/', allocate one more space for it */
> + if ((input[len-1]) != '/')
input[len-1] will contain '\0', you have the indexes wrong in whole
function.
> + len = len+1;
> +
> + output = (char *)malloc(sizeof(char)*(len));
> + if (output == NULL)
> + return NULL;
> +
> + strcpy(output, input);
> + output[len-1] = '/';
> + output[len] = '\0';
> +
> + return output;
> +}
> +
> +/* create control group based given template
> + * if the group already don't exist
> + * dest is template name with substitute variables
There is no 'dest' parameter.
> + * tmp is used cgrules rule
It should have proper name, tmp is too ambiguous.
> + */
> +int cgroup_create_template_group(char *orig_group_name, struct cgroup_rule
> *tmp,
> + int flags)
> +{
> +
> + char *template_name = NULL; /* name of the template */
> + char *group_name = NULL; /* name of the group based on template -
> + variables are substituted */
> + char *template_position; /* denotes directory in template path
> + which is investigated */
> + char *group_position; /* denotes directory in cgroup path
> + which is investigated */
> +
> + struct cgroup *template_group = NULL;
> + int ret = 0;
> + int i;
> + int exist;
> + int first;
> + struct cgroup_controller *controller;
> +
> + /* template name and group name have to have '/' sign at the end */
> + template_name = cgroup_copy_with_backslash(tmp->destination);
> + if (template_name == NULL) {
> + ret = ECGOTHER;
please set last_errno
> + goto end;
> + }
> + group_name = cgroup_copy_with_backslash(orig_group_name);
> + if (group_name == NULL) {
> + ret = ECGOTHER;
please set last_errno
> + goto end;
> + }
> +
> + /* set start positions */
> + template_position = strchr(template_name, '/');
> + group_position = strchr(group_name, '/');
> +
> + /* go recursively through whole path to template group and create given
> + * directory if it does not exist yet
> + */
I am not sure this functionality is needed at all.
Why not call cgroup_config_create_template_group() directly here? It
should create the parent groups automatically.
Or do I miss something?
> + while ((group_position != NULL) && (template_position != NULL)) {
> + /* set new subpath */
> + group_position[0] = '\0';
> + template_position[0] = '\0';
> + first = 0;
> +
> + /* test for which controllers wanted group does not exist */
> + i = 0;
> + while (tmp->controllers[i] != NULL) {
> + exist = cgroup_exist_in_subsystem(tmp->controllers[i],
> + group_name);
> +
> + if (exist != 0) {
> + /* the cgroup does not exist */
> + if (first == 0) {
> + /* it is the first controller for which
> + the group does not exist */
> + first = 1;
> + template_group =
> + cgroup_new_cgroup(group_name);
> + if (template_group == NULL) {
> + ret = ECGFAIL;
> + goto end;
> + }
> + }
> +
> + controller = cgroup_add_controller(
> + template_group, tmp->controllers[i]);
> + if (!controller) {
> + cgroup_free(&template_group);
> + ret = ECGFAIL;
> + goto end;
> + }
> + }
> + i++;
> + }
> +
> + if (first == 1) {
> + /* new group have to be created */
> + if (strcmp(group_name, template_name) == 0) {
> + /* the prefix cgroup without template */
> + ret = cgroup_create_cgroup(template_group, 0);
> + } else {
> + /* TODO: this will be a function which use
> + * template to create relevant cgroup
> + * now cgroup_create_cgroup is used
> + ret = cgroup_config_create_template_group(
> + template_group, template_name,
> + 0, flags);
> + */
> + ret = cgroup_create_cgroup(template_group, 0);
> + }
> +
> + if (ret != 0) {
> + cgroup_free(&template_group);
> + goto end;
> + }
> + cgroup_dbg("Group %s created - based on template %s\n",
> + group_name, template_name);
> +
> + cgroup_free(&template_group);
> + }
> + template_position[0] = '/';
> + group_position[0] = '/';
> + template_position = strchr(++template_position, '/');
> + group_position = strchr(++group_position, '/');
> + }
> +
> +end:
> + if (group_name != NULL)
> + free(group_name);
> + if (template_name != NULL)
> + free(template_name);
> + return ret;
> +}
> +
> int cgroup_change_cgroup_flags(uid_t uid, gid_t gid,
> const char *procname, pid_t pid, int flags)
> {
> @@ -2783,7 +2951,14 @@ int cgroup_change_cgroup_flags(uid_t uid, gid_t gid,
> newdest[j] = tmp->destination[i];
> }
> }
> +
> newdest[j] = 0;
> + if (strcmp(newdest, tmp->destination) != 0) {
> + /* destination tag contains templates */
> +
> + cgroup_dbg("control group %s is template\n", newdest);
> + ret = cgroup_create_template_group(newdest, tmp, flags);
> + }
>
> /* Apply the rule */
> ret = cgroup_change_cgroup_path(newdest,
>
>
> ------------------------------------------------------------------------------
> Monitor your physical, virtual and cloud infrastructure from a single
> web console. Get in-depth insight into apps, servers, databases, vmware,
> SAP, cloud infrastructure, etc. Download 30-day Free Trial.
> Pricing starts from $795 for 25 servers or applications!
> http://p.sf.net/sfu/zoho_dev2dev_nov
> _______________________________________________
> Libcg-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/libcg-devel
>
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel