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 <varek...@redhat.com> > --- > > 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 > Libcg-devel@lists.sourceforge.net > 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 Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel