* Balbir Singh <[email protected]> [2010-03-15 09:04:22]:

> * Dhaval Giani <[email protected]> [2010-03-12 11:14:06]:
> 
> > On Fri, Mar 12, 2010 at 8:39 AM, Rafael Tinoco <[email protected]> wrote:
> > > Yes!!! Thank you very much.. Its working now.. 37 thousand lines, 1400
> > > users (one cgroup for each user) :D
> > > Server is up and running now :D
> > >
> > 
> > Balbir,
> > 
> > So do we change the hardcoded limit? And what do we change it to? :)
> >
>

How does this patch look? Rafael, could you please test to see if this
works for you?

 
Allow cgconfigparser to create groups > MAX_GROUPS

From: Balbir Singh <[email protected]>

Rafael Tinoco <[email protected]> noticed that the maximum
number of cgroups created using cgconfigparser fell short of 2000. Balbir
found a limitation in the code, that limited this number to a predefined
maximum. This patch fixes the limitation, although not in the most
optimized way, since we want to avoid double parsing of the configuraiton
file.

This patch realloc's the data structure that holds parsed cgroups.

Tested via setting MAX_CGROUPS=1 and loading a configuration file with
2 groups defined.

Signed-off-by: Balbir Singh <[email protected]>
---

 src/config.c |   35 ++++++++++++++++++++++++++++++-----
 src/parse.y  |   12 +++++++++---
 2 files changed, 39 insertions(+), 8 deletions(-)


diff --git a/src/config.c b/src/config.c
index f89ef36..c4dd92a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -44,7 +44,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#define MAX_CGROUPS 1024
+unsigned int MAX_CGROUPS = 64; /* NOTE: This value changes dynamically */
 
 extern FILE *yyin;
 extern int yyparse(void);
@@ -64,7 +64,7 @@ static int config_table_index;
 static int namespace_table_index;
 static pthread_rwlock_t config_table_lock = PTHREAD_RWLOCK_INITIALIZER;
 static pthread_rwlock_t namespace_table_lock = PTHREAD_RWLOCK_INITIALIZER;
-static struct cgroup config_cgroup_table[MAX_CGROUPS];
+static struct cgroup *config_cgroup_table;
 int cgroup_table_index;
 
 /*
@@ -84,10 +84,30 @@ static const char cgroup_filesystem[] = "cgroup";
  */
 int cgroup_config_insert_cgroup(char *cg_name)
 {
-       struct cgroup *config_cgroup =
-                       &config_cgroup_table[cgroup_table_index];
+       struct cgroup *config_cgroup;
+
+       if (cgroup_table_index >= MAX_CGROUPS - 1) {
+               struct cgroup *newblk;
+               if (MAX_CGROUPS >= INT_MAX) {
+                       last_errno = ENOMEM;
+                       return 0;
+               }
+               MAX_CGROUPS *= 2;
+               newblk = realloc(config_cgroup_table, (MAX_CGROUPS *
+                                       sizeof(struct cgroup)));
+               if (!newblk) {
+                       last_errno = ENOMEM;
+                       return 0;
+               }
+               config_cgroup_table = newblk;
+               cgroup_dbg("MAX_CGROUPS %d\n", MAX_CGROUPS);
+               cgroup_dbg("reallocated config_cgroup to %p\n", config_cgroup);
+       }
 
+       config_cgroup = &config_cgroup_table[cgroup_table_index];
+       memset(config_cgroup, 0, sizeof(struct cgroup));
        strncpy(config_cgroup->name, cg_name, FILENAME_MAX);
+
        /*
         * Since this will be the last part to be parsed.
         */
@@ -662,9 +682,11 @@ int cgroup_config_load_config(const char *pathname)
                return ECGOTHER;
        }
 
+       config_cgroup_table = malloc(MAX_CGROUPS * sizeof(struct cgroup));
        if (yyparse() != 0) {
                cgroup_dbg("Failed to parse file %s\n", pathname);
                fclose(yyin);
+               free(config_cgroup_table);
                return ECGCONFIGPARSEFAIL;
        }
 
@@ -675,8 +697,10 @@ int cgroup_config_load_config(const char *pathname)
         * The configuration should have either namespace or mount.
         * Not both and not none.
         */
-       if (namespace_enabled == mount_enabled)
+       if (namespace_enabled == mount_enabled) {
+               free(config_cgroup_table);
                return ECGMOUNTNAMESPACE;
+       }
 
        /*
         * We do not allow both mount and namespace sections in the
@@ -715,6 +739,7 @@ err_grp:
        cgroup_config_destroy_groups();
 err_mnt:
        cgroup_config_unmount_controllers();
+       free(config_cgroup_table);
        fclose(yyin);
        return error;
 }
diff --git a/src/parse.y b/src/parse.y
index 47abee6..12cdf47 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -72,9 +72,15 @@ start   : start group
 group   :       GROUP ID '{' group_conf '}'
        {
                $$ = $4;
-               if ($$)
-                       cgroup_config_insert_cgroup($2);
-               else {
+               if ($$) {
+                       $$ = cgroup_config_insert_cgroup($2);
+                       if (!$$) {
+                               fprintf(stderr, "failed to insert group"
+                                       " check size and memory");
+                               $$ = ECGOTHER;
+                               return $$;
+                       }
+               } else {
                        fprintf(stderr, "parsing failed at line number %d\n",
                                line_no);
                        $$ = ECGCONFIGPARSEFAIL;

-- 
        Three Cheers,
        Balbir

------------------------------------------------------------------------------
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
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to