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
+ */
+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]) != '/')
+               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
+ * tmp is used cgrules rule
+ */
+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;
+               goto end;
+       }
+       group_name = cgroup_copy_with_backslash(orig_group_name);
+       if (group_name == NULL) {
+               ret = ECGOTHER;
+               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
+        */
+       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

Reply via email to