This patch implements loading files from /etc/cgconfig.d/. It uses 
already implemented functions. To hold list of files to be read for 
template reloading, new static variable for this list (list of template 
files) has been added to config.c. It is the same list as file list read 
with cgconfigparser (cgconfig.c file), i.e. the same functions are 
called. Because parser reads only one file, it is called for each file 
in template file list. Thus initialization, resp. template duplication 
has to be called before, resp. after each file parsing. Thus new 
functions has been presented, thus modifying config.[h|c] api. Again 
parsing more files for templates is analogy to parsing files for groups 
in cgconfig.c. cgrulesengd.c includes headers from tools folder. This 
requires modification of Makefile.am and regenerating Makefile.im. 
Again, all functions are reused, just added three more to deal with 
saving list of template files and parsing this files into one template 
table during initialization/reloading.

Tested on my local machine, all files are loaded properly, cgrulesengd 
properly creates groups based on templates from files from /etc/cgconfig.d/.

Signed-off-by: Jan Chaloupka<jchal...@redhat.com>
---
  include/libcgroup/config.h |  18 ++++
  src/config.c               | 203 
++++++++++++++++++++++++++++++++++++++++++++-
  src/daemon/Makefile.am     |   4 +-
  src/daemon/Makefile.in     |  25 +++++-
  src/daemon/cgrulesengd.c   |  36 +++++++-
  src/libcgroup-internal.h   |   3 +
  src/libcgroup.map          |   6 ++
  src/tools/tools-common.h   |   2 +-
  8 files changed, 286 insertions(+), 11 deletions(-)

diff --git a/include/libcgroup/config.h b/include/libcgroup/config.h
index 43568e1..cf52922 100644
--- a/include/libcgroup/config.h
+++ b/include/libcgroup/config.h
@@ -84,6 +84,24 @@ int cgroup_init_templates_cache(char *pathname);
  int cgroup_reload_cached_templates(char *pathname);

  /**
+ * Initializes the templates cache from files.
+ */
+struct cgroup_string_list;
+int cgroup_init_templates_cache_from_files(int * file_index);
+
+/**
+ * Reloads the templates list, using the given configuration files.
+ */
+int cgroup_reload_cached_templates_from_file(int * file_index);
+
+/**
+ * Setting source files of templates. This function has to be called before
+ * any call of cgroup_init_templates_cache_from_files and
+ * cgroup_reload_cached_templates_from_file.
+ */
+void cgroup_templates_cache_set_source_files(struct cgroup_string_list 
* tmpl_files);
+
+/**
   * Physically create a new control group in kernel, based on given control
   * group template and configuration file. If given template is not set in
   * configuration file, then the procedure works create the control group
diff --git a/src/config.c b/src/config.c
index e1ee0a8..c6096b2 100644
--- a/src/config.c
+++ b/src/config.c
@@ -41,6 +41,8 @@
  #include <sys/stat.h>
  #include <sys/types.h>

+#include "tools/tools-common.h"
+
  unsigned int MAX_CGROUPS = 64;    /* NOTE: This value changes 
dynamically */
  unsigned int MAX_TEMPLATES = 64;
                  /* NOTE: This value changes dynamically */
@@ -89,6 +91,7 @@ static int config_template_table_index;
   */
  static struct cgroup *template_table;
  static int template_table_index;
+static struct cgroup_string_list * template_files = NULL;


  /*
@@ -1572,6 +1575,199 @@ int cgroup_init_templates_cache(char *pathname)

  }

+/**
+ * Setting source files of templates. This function has to be called before
+ * any call of cgroup_init_templates_cache_from_files and
+ * cgroup_reload_cached_templates_from_file.
+ * @param tmpl_files
+ */
+void cgroup_templates_cache_set_source_files(struct cgroup_string_list 
* tmpl_files) {
+    template_files = tmpl_files;
+}
+
+/**
+ * Initializes the templates cache from files.
+ *    @return 0 on success, > 0 on error
+ */
+int cgroup_init_templates_cache_from_files(int * file_index) {
+        int ret = 0;
+    int i, j;
+
+        if (!template_files) {
+            /* source files has not been set */
+            cgroup_dbg("Template source files have not been set\n");
+            ret = ECGOTHER;
+            *file_index = -1;
+            return ret;
+        }
+
+    if (template_table) {
+        /* template structures have to be free */
+        for (i = 0; i < template_table_index; i++)
+            cgroup_free_controllers(&template_table[i]);
+        free(template_table);
+        template_table = NULL;
+    }
+    template_table_index = 0;
+
+    if ((config_template_table_index != 0) || (config_table_index != 0)) {
+        /* config structures have to be clean */
+        cgroup_free_config();
+    }
+
+        char * pathname;
+        int template_table_last_index = 0;
+
+        for (j = 0; j < template_files->count; j++) {
+            pathname = template_files->items[j];
+
+            cgroup_dbg("Loading cached templates from %s.\n", pathname);
+            /* Attempt to read the configuration file and cache the 
rules. */
+            ret = cgroup_parse_config(pathname);
+            if (ret) {
+                    cgroup_dbg("Could not initialize rule cache, error 
was: %d\n",
+                            ret);
+                    *file_index = j;
+                    return ret;
+            }
+
+            /* copy template data to templates cache structures */
+            if (config_template_table_index > 0) {
+                template_table_last_index = template_table_index;
+                template_table_index += config_template_table_index;
+                template_table = realloc(template_table, 
template_table_index*sizeof(struct cgroup));
+
+                if (template_table == NULL) {
+                        ret = ECGOTHER;
+                        return ret;
+                }
+
+                for (i = 0; i < config_template_table_index; i++) {
+                    template_table[i + template_table_last_index].index 
= 0;
+                }
+            }
+
+            cgroup_dbg("Init cache: copying templates to template table 
from %s.\n", pathname);
+            for (i = 0; i < config_template_table_index; i++) {
+                    int ti = i + template_table_last_index;
+                    cgroup_copy_cgroup(&template_table[ti],
+                            &config_template_table[i]);
+                    strcpy((template_table[ti]).name,
+                            (config_template_table[i]).name);
+                    template_table[ti].tasks_uid =
+                            config_template_table[i].tasks_uid;
+                    template_table[ti].tasks_gid =
+                            config_template_table[i].tasks_gid;
+                    template_table[ti].task_fperm =
+                            config_template_table[i].task_fperm;
+                    template_table[ti].control_uid =
+                            config_template_table[i].control_uid;
+                    template_table[ti].control_gid =
+                            config_template_table[i].control_gid;
+                    template_table[ti].control_fperm =
+                            config_template_table[i].control_fperm;
+                    template_table[ti].control_dperm =
+ config_template_table[i].control_dperm;
+            }
+            cgroup_dbg("Init cache: Templates to template table copied\n");
+        }
+
+    return ret;
+}
+
+/**
+ * Reloads the templates list, using the given configuration files.
+ *    @return 0 on success, > 0 on failure
+ */
+int cgroup_reload_cached_templates_from_file(int * file_index)
+{
+    int i, j;
+    int ret = 0;
+
+        if (!template_files) {
+            /* source files has not been set */
+            cgroup_dbg("Template source files have not been set\n");
+            ret = ECGOTHER;
+            *file_index = -1;
+            return ret;
+        }
+
+    if (template_table) {
+        /* template structures have to be free */
+        for (i = 0; i < template_table_index; i++)
+            cgroup_free_controllers(&template_table[i]);
+        free(template_table);
+        template_table = NULL;
+    }
+    template_table_index = 0;
+
+    if ((config_template_table_index != 0) || (config_table_index != 0)) {
+        /* config template structures have to be free as well*/
+        cgroup_free_config();
+    }
+
+
+        char * pathname;
+        int template_table_last_index = 0;
+
+        for (j = 0; j < template_files->count; j++) {
+            pathname = template_files->items[j];
+
+            /* reloading data to config template structures */
+            cgroup_dbg("Reloading cached templates from %s.\n", pathname);
+            ret = cgroup_parse_config(pathname);
+            if (ret) {
+                    cgroup_dbg("Could not reload template cache, error 
was: %d\n",
+                            ret);
+                    *file_index = j;
+                    return ret;
+            }
+
+            /* copy data to templates cache structures */
+            if (config_template_table_index > 0) {
+                template_table_last_index = template_table_index;
+                template_table_index += config_template_table_index;
+                template_table = realloc(template_table, 
template_table_index*sizeof(struct cgroup));
+
+                if (template_table == NULL) {
+                        ret = ECGOTHER;
+                        return ret;
+                }
+
+                /* clear cgroups of new templates */
+                for (i = 0; i < config_template_table_index; i++) {
+                    template_table[i + template_table_last_index].index 
= 0;
+                }
+            }
+
+            cgroup_dbg("Reload cache: copying templates to template 
table from %s.\n", pathname);
+            for (i = 0; i < config_template_table_index; i++) {
+                    int ti = i + template_table_last_index;
+                    cgroup_copy_cgroup(&template_table[ti],
+                            &config_template_table[i]);
+                    strcpy((template_table[ti]).name,
+                            (config_template_table[i]).name);
+                    template_table[ti].tasks_uid =
+                            config_template_table[i].tasks_uid;
+                    template_table[ti].tasks_gid =
+                            config_template_table[i].tasks_gid;
+                    template_table[ti].task_fperm =
+                            config_template_table[i].task_fperm;
+                    template_table[ti].control_uid =
+                            config_template_table[i].control_uid;
+                    template_table[ti].control_gid =
+                            config_template_table[i].control_gid;
+                    template_table[ti].control_fperm =
+                            config_template_table[i].control_fperm;
+                    template_table[ti].control_dperm =
+                            config_template_table[i].control_dperm;
+            }
+            cgroup_dbg("Reload cache: Templates to template table 
copied\n");
+        }
+
+    return ret;
+}
+
  /*
   * Create a given cgroup, based on template configuration if it is present
   * if the template is not present cgroup is creted using 
cgroup_create_cgroup
@@ -1593,13 +1789,14 @@ int cgroup_config_create_template_group(struct 
cgroup *cgroup,
       * use CGCONFIG_CONF_FILE by default
       */
      if (!(flags & CGFLAG_USE_TEMPLATE_CACHE)) {
+                int fileindex;
          if (template_table_index == 0)
              /* the rules cache is empty */
-            ret = cgroup_init_templates_cache(CGCONFIG_CONF_FILE);
+                        ret = 
cgroup_init_templates_cache_from_files(&fileindex);
+
          else
              /* cache is not empty */
-            ret = cgroup_reload_cached_templates(
-                CGCONFIG_CONF_FILE);
+                        ret = 
cgroup_reload_cached_templates_from_file(&fileindex);
          if (ret != 0) {
              cgroup_dbg("Failed initialize templates cache.\n");
              return ret;
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index f3100ed..abbbe30 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -1,9 +1,9 @@
-INCLUDES = -I $(top_srcdir)/include
+INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/include

  if WITH_DAEMON

  sbin_PROGRAMS = cgrulesengd
-cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h
+cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h 
../tools/tools-common.h ../tools/tools-common.c
  cgrulesengd_LDADD = $(top_builddir)/src/.libs/libcgroup.la -lrt
  cgrulesengd_LDFLAGS = -L$(top_builddir)/src/.libs

diff --git a/src/daemon/Makefile.in b/src/daemon/Makefile.in
index 76f7e07..f3efc65 100644
--- a/src/daemon/Makefile.in
+++ b/src/daemon/Makefile.in
@@ -92,8 +92,10 @@ CONFIG_CLEAN_FILES =
  CONFIG_CLEAN_VPATH_FILES =
  am__installdirs = "$(DESTDIR)$(sbindir)"
  PROGRAMS = $(sbin_PROGRAMS)
-am__cgrulesengd_SOURCES_DIST = cgrulesengd.c cgrulesengd.h
-@WITH_DAEMON_TRUE@am_cgrulesengd_OBJECTS = cgrulesengd.$(OBJEXT)
+am__cgrulesengd_SOURCES_DIST = cgrulesengd.c cgrulesengd.h \
+    ../tools/tools-common.h ../tools/tools-common.c
+@WITH_DAEMON_TRUE@am_cgrulesengd_OBJECTS = cgrulesengd.$(OBJEXT) \
+@WITH_DAEMON_TRUE@    tools-common.$(OBJEXT)
  cgrulesengd_OBJECTS = $(am_cgrulesengd_OBJECTS)
  @WITH_DAEMON_TRUE@cgrulesengd_DEPENDENCIES =  \
  @WITH_DAEMON_TRUE@    $(top_builddir)/src/.libs/libcgroup.la
@@ -294,8 +296,8 @@ target_alias = @target_alias@
  top_build_prefix = @top_build_prefix@
  top_builddir = @top_builddir@
  top_srcdir = @top_srcdir@
-INCLUDES = -I $(top_srcdir)/include
-@WITH_DAEMON_TRUE@cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h
+INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/include
+@WITH_DAEMON_TRUE@cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h 
../tools/tools-common.h ../tools/tools-common.c
  @WITH_DAEMON_TRUE@cgrulesengd_LDADD = 
$(top_builddir)/src/.libs/libcgroup.la -lrt
  @WITH_DAEMON_TRUE@cgrulesengd_LDFLAGS = -L$(top_builddir)/src/.libs
  all: all-am
@@ -393,6 +395,7 @@ distclean-compile:
      -rm -f *.tab.c

  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgrulesengd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools-common.Po@am__quote@

  .c.o:
  @am__fastdepCC_TRUE@    $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF 
$(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -415,6 +418,20 @@ distclean-compile:
  @AMDEP_TRUE@@am__fastdepCC_FALSE@    DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
  @am__fastdepCC_FALSE@    $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<

+tools-common.o: ../tools/tools-common.c
+@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) 
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT 
tools-common.o -MD -MP -MF $(DEPDIR)/tools-common.Tpo -c -o 
tools-common.o `test -f '../tools/tools-common.c' || echo 
'$(srcdir)/'`../tools/tools-common.c
+@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/tools-common.Tpo 
$(DEPDIR)/tools-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ 
$(AM_V_CC)source='../tools/tools-common.c' object='tools-common.o' 
libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@    DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@    $(AM_V_CC@am__nodep@)$(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) 
$(CFLAGS) -c -o tools-common.o `test -f '../tools/tools-common.c' || 
echo '$(srcdir)/'`../tools/tools-common.c
+
+tools-common.obj: ../tools/tools-common.c
+@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) 
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT 
tools-common.obj -MD -MP -MF $(DEPDIR)/tools-common.Tpo -c -o 
tools-common.obj `if test -f '../tools/tools-common.c'; then 
$(CYGPATH_W) '../tools/tools-common.c'; else $(CYGPATH_W) 
'$(srcdir)/../tools/tools-common.c'; fi`
+@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/tools-common.Tpo 
$(DEPDIR)/tools-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ 
$(AM_V_CC)source='../tools/tools-common.c' object='tools-common.obj' 
libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@    DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@    $(AM_V_CC@am__nodep@)$(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) 
$(CFLAGS) -c -o tools-common.obj `if test -f '../tools/tools-common.c'; 
then $(CYGPATH_W) '../tools/tools-common.c'; else $(CYGPATH_W) 
'$(srcdir)/../tools/tools-common.c'; fi`
+
  mostlyclean-libtool:
      -rm -f *.lo

diff --git a/src/daemon/cgrulesengd.c b/src/daemon/cgrulesengd.c
index 170837a..d82cbdf 100644
--- a/src/daemon/cgrulesengd.c
+++ b/src/daemon/cgrulesengd.c
@@ -34,6 +34,7 @@
  #include "libcgroup.h"
  #include "cgrulesengd.h"
  #include "../libcgroup-internal.h"
+#include "../tools/tools-common.h"

  #include <errno.h>
  #include <stdarg.h>
@@ -59,6 +60,9 @@

  #define NUM_PER_REALLOCATIOM    (100)

+/* list of config files from /etc/cgconfig.conf and /etc/cgconfig.d/ */
+static struct cgroup_string_list template_files;
+
  /* Log file, NULL if logging to file is disabled */
  FILE* logfile;

@@ -1179,7 +1183,21 @@ int main(int argc, char *argv[])
          goto finished;
      }

-    /* Ask libcgroup to load the configuration rules. */
+        /* Ask libcgroup to load the configuration rules. */
+    ret = cgroup_string_list_init(&template_files, 
CGCONFIG_CONF_FILES_LIST_MINIMUM_SIZE);
+    if (ret)
+        goto finished;
+        /* first add CGCONFIG_CONF_FILE into file list */
+        ret = cgroup_string_list_add_item(&template_files, 
CGCONFIG_CONF_FILE);
+        if (ret) {
+                fprintf(stderr, "%s: cannot add file to list,"\
+                                " out of memory?\n", argv[0]);
+                goto finished;
+        }
+
+        /* then read CGCONFIG_CONF_DIR directory for additional config 
files */
+        cgroup_string_list_add_directory(&template_files, 
CGCONFIG_CONF_DIR, argv[0]);
+
      if ((ret = cgroup_init_rules_cache()) != 0) {
          fprintf(stderr, "Error: libcgroup failed to initialize rules"
                  "cache from %s. %s\n", CGRULES_CONF_FILE,
@@ -1188,6 +1206,20 @@ int main(int argc, char *argv[])
      }

      /* ask libcgroup to load template rules as well */
+ cgroup_templates_cache_set_source_files(&template_files);
+        int fileindex;
+        ret = cgroup_init_templates_cache_from_files(&fileindex);
+    if (ret != 0) {
+                if (fileindex < 0) {
+                        fprintf(stderr, "Error: Template source files 
have not been set\n");
+                } else {
+                        fprintf(stderr, "Error: libcgroup failed to 
initialize template "\
+                "rules from %s. %s\n", template_files.items[fileindex],
+                cgroup_strerror(ret));
+                }
+        goto finished;
+    }
+
      ret = cgroup_init_templates_cache(CGCONFIG_CONF_FILE);
      if (ret != 0) {
          fprintf(stderr, "Error: libcgroup failed to initialize teplate"\
@@ -1262,5 +1294,7 @@ finished:
      if (logfile && logfile != stdout)
          fclose(logfile);

+        cgroup_string_list_free(&template_files);
+
      return ret;
  }
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index 4c0f46c..c128788 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -48,6 +48,9 @@ __BEGIN_DECLS


  #define CGCONFIG_CONF_FILE        "/etc/cgconfig.conf"
+/* Minimum number of file in template file list for cgrulesengd */
+#define CGCONFIG_CONF_FILES_LIST_MINIMUM_SIZE   4
+#define CGCONFIG_CONF_DIR               "/etc/cgconfig.d"

  #define CGRULES_CONF_FILE       "/etc/cgrules.conf"
  #define CGRULES_MAX_FIELDS_PER_LINE        3
diff --git a/src/libcgroup.map b/src/libcgroup.map
index b0c162c..f853af0 100644
--- a/src/libcgroup.map
+++ b/src/libcgroup.map
@@ -117,3 +117,9 @@ CGROUP_0.39 {
      cgroup_log;
      cgroup_parse_log_level_str;
  } CGROUP_0.38;
+
+CGROUP_0.40 {
+    cgroup_init_templates_cache_from_files;
+        cgroup_reload_cached_templates_from_file;
+        cgroup_templates_cache_set_source_files;
+} CGROUP_0.39;
diff --git a/src/tools/tools-common.h b/src/tools/tools-common.h
index e05465f..c723eb4 100644
--- a/src/tools/tools-common.h
+++ b/src/tools/tools-common.h
@@ -20,7 +20,7 @@

  #include "config.h"
  #include <libcgroup.h>
-#include <libcgroup-internal.h>
+#include "../libcgroup-internal.h"

  #define cgroup_err(x...) cgroup_log(CGROUP_LOG_ERROR, x)
  #define cgroup_warn(x...) cgroup_log(CGROUP_LOG_WARNING, x)


------------------------------------------------------------------------------
_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to