]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
Current implementation of cgconfig.conf parser stores parameter values in
authorJan Safranek <jsafrane@redhat.com>
Tue, 10 Aug 2010 09:38:14 +0000 (15:08 +0530)
committerBalbir Singh <balbir@linux.vnet.ibm.com>
Tue, 10 Aug 2010 09:38:14 +0000 (15:08 +0530)
ugly string (name-value pairs separated by ':', name and value themselves
separated by ' '), which does not allow users to have ' ' and ':' in
parameter values. Both are desired for devices.allow and devices.deny.

Let's rewrite the parser to store the parsed name-value pairs in a
dictionary, without any limitation on characters allowed in names and
values.

Signed-off-by: Jan Safranek <jsafrane@redhat.com>
Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com>
src/config.c
src/libcgroup-internal.h
src/parse.y

index a29649a92d29954ae2fa937a1def785323a4772d..bce71780a6cbed42d6efae2c039d63b6dace3f45 100644 (file)
@@ -121,15 +121,15 @@ int cgroup_config_insert_cgroup(char *cg_name)
  * entry in the cgroup_table. The index is incremented in
  * cgroup_config_insert_cgroup
  */
-int cgroup_config_parse_controller_options(char *controller, char *name_value)
+int cgroup_config_parse_controller_options(char *controller,
+       struct cgroup_dictionary *values)
 {
-       char *buffer = NULL;
-       char *name, *value;
+       const char *name, *value;
        struct cgroup_controller *cgc;
        int error;
        struct cgroup *config_cgroup =
                &config_cgroup_table[cgroup_table_index];
-       char *nm_pairs, *nv_buf;
+       void *iter = NULL;
 
        cgroup_dbg("Adding controller %s, value %s\n", controller, name_value);
        cgc = cgroup_add_controller(config_cgroup, controller);
@@ -141,56 +141,33 @@ int cgroup_config_parse_controller_options(char *controller, char *name_value)
         * Did we just specify the controller to create the correct
         * set of directories, without setting any values?
         */
-       if (!name_value)
+       if (!values)
                goto done;
 
-       nm_pairs = strtok_r(name_value, ":", &nv_buf);
-       cgroup_dbg("[1] name value pair being processed is %s\n", nm_pairs);
-
-       name = strtok_r(nm_pairs, " ", &buffer);
-
-       if (!name)
-               goto parse_error;
-
-       value = strtok_r(NULL, " ", &buffer);
-
-       if (!value)
-               goto parse_error;
-
-       cgroup_dbg("name is %s, value is %s\n", name, value);
-       error = cgroup_add_value_string(cgc, name, value);
-
-       if (error)
-               goto parse_error;
-
-       while ((nm_pairs = strtok_r(NULL, ":", &nv_buf))) {
-               cgroup_dbg("[2] name value pair being processed is %s\n",
-                       nm_pairs);
-               name = strtok_r(nm_pairs, " ", &buffer);
-
+       error = cgroup_dictionary_iterator_begin(values, &iter, &name, &value);
+       while (error == 0) {
+               cgroup_dbg("[1] name value pair being processed is %s=%s\n",
+                               name, value);
                if (!name)
                        goto parse_error;
-
-               value = strtok_r(NULL, " ", &buffer);
-
-               if (!value)
-                       goto parse_error;
-
-               cgroup_dbg("name is %s, value is %s\n", name, value);
                error = cgroup_add_value_string(cgc, name, value);
-
                if (error)
                        goto parse_error;
+               error = cgroup_dictionary_iterator_next(&iter, &name, &value);
        }
+       cgroup_dictionary_iterator_end(&iter);
+       iter = NULL;
+
+       if (error != ECGEOF)
+               goto parse_error;
 
 done:
        free(controller);
-       free(name_value);
        return 1;
 
 parse_error:
        free(controller);
-       free(name_value);
+       cgroup_dictionary_iterator_end(&iter);
        cgroup_delete_cgroup(config_cgroup, 1);
        cgroup_table_index--;
        return 0;
index 92b9fd8d6fc1492de1bd65875a6e11c028b0bdf7..801b35e452abaf72274110a0906039aa4d4d31ce 100644 (file)
@@ -198,7 +198,8 @@ extern __thread char *cg_namespace_table[CG_CONTROLLER_MAX];
  * config related API
  */
 int cgroup_config_insert_cgroup(char *cg_name);
-int cgroup_config_parse_controller_options(char *controller, char *name_value);
+int cgroup_config_parse_controller_options(char *controller,
+               struct cgroup_dictionary *values);
 int cgroup_config_group_task_perm(char *perm_type, char *value);
 int cgroup_config_group_admin_perm(char *perm_type, char *value);
 int cgroup_config_insert_into_mount_table(char *name, char *mount_point);
index d40974254c93d7cde73e30fc8e38f74a84d1fb33..bf68a98e1623b3108d99de09ede3b28e26fef149 100644 (file)
@@ -43,11 +43,13 @@ int yywrap(void)
        char *name;
        char chr;
        int val;
+       struct cgroup_dictionary *values;
 }
-%type <name> ID namevalue_conf
+%type <name> ID
 %type <val> mountvalue_conf mount task_namevalue_conf admin_namevalue_conf
 %type <val> admin_conf task_conf task_or_admin group_conf group start
 %type <val> namespace namespace_conf
+%type <values> namevalue_conf
 %start start
 %%
 
@@ -93,6 +95,7 @@ group_conf
         :       ID '{' namevalue_conf '}'
        {
                $$ = cgroup_config_parse_controller_options($1, $3);
+               cgroup_dictionary_free($3);
                if (!$$) {
                        fprintf(stderr, "parsing failed at line number %d\n",
                                line_no);
@@ -103,6 +106,7 @@ group_conf
         |       group_conf ID '{' namevalue_conf '}'
        {
                $$ = cgroup_config_parse_controller_options($2, $4);
+               cgroup_dictionary_free($4);
                if (!$$) {
                        fprintf(stderr, "parsing failed at line number %d\n",
                                line_no);
@@ -125,25 +129,30 @@ group_conf
 namevalue_conf
         :       ID '=' ID ';'
        {
-               $1 = realloc($1, strlen($1) + strlen($3) + 2);
-               $1 = strncat($1, " ", strlen(" "));
-               $$ = strncat($1, $3, strlen($3));
-               free($3);
+               struct cgroup_dictionary *dict;
+               int ret;
+               ret = cgroup_dictionary_create(&dict, 0);
+               if (ret == 0)
+                       ret = cgroup_dictionary_add(dict, $1, $3);
+               if (ret) {
+                       fprintf(stderr, "parsing failed at line number %d:%s\n",
+                               line_no, cgroup_strerror(ret));
+                       $$ = NULL;
+                       return ECGCONFIGPARSEFAIL;
+               }
+               $$ = dict;
        }
         |       namevalue_conf ID '=' ID ';'
        {
-               int len = 0;
-               if ($1)
-                       len = strlen($1);
-               $2 = realloc($2, len + strlen($2) + strlen($4) + 3);
-               $2 = strncat($2, " ", strlen(" "));
-               $$ = strncat($2, $4, strlen($4));
-               if ($1) {
-                       $2 = strncat($2, ":", strlen(":"));
-                       $$ = strncat($2, $1, strlen($1));
-                       free($1);
+               int ret = 0;
+               ret = cgroup_dictionary_add($1, $2, $4);
+               if (ret != 0) {
+                       fprintf(stderr, "parsing failed at line number %d: %s\n",
+                               line_no, cgroup_strerror(ret));
+                       $$ = NULL;
+                       return ECGCONFIGPARSEFAIL;
                }
-               free($4);
+               $$ = $1;
        }
        |
        {