Blame SOURCES/libcgroup-0.41-loading-configuration-files-from-etc-cgconfig.d-dire.patch

4b3140
From 7b1b0409f5fc1828f0feb2086fe5b8184f7eb2c6 Mon Sep 17 00:00:00 2001
4b3140
From: Jan Chaloupka <jchaloup@redhat.com>
4b3140
Date: Sat, 20 Sep 2014 20:02:13 +0200
4b3140
Subject: [PATCH] loading configuration files from /etc/cgconfig.d/ directory
4b3140
4b3140
---
4b3140
 Makefile.in                |   2 +-
4b3140
 doc/man/cgconfig.conf.5    |   7 +-
4b3140
 doc/man/cgrulesengd.8      |   8 +-
4b3140
 include/libcgroup/config.h |  21 ++++++
4b3140
 src/config.c               | 181 +++++++++++++++++++++++++++++++++++++++++++--
4b3140
 src/daemon/Makefile.am     |   4 +-
4b3140
 src/daemon/Makefile.in     |  25 ++++++-
4b3140
 src/daemon/cgrulesengd.c   |  51 +++++++++++--
4b3140
 src/libcgroup-internal.h   |   3 +
4b3140
 src/libcgroup.map          |   5 ++
4b3140
 src/tools/tools-common.h   |   2 +-
4b3140
 11 files changed, 286 insertions(+), 23 deletions(-)
4b3140
4b3140
diff --git a/Makefile.in b/Makefile.in
4b3140
index af6e89c..0349c93 100644
4b3140
--- a/Makefile.in
4b3140
+++ b/Makefile.in
4b3140
@@ -84,7 +84,7 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
4b3140
 	$(srcdir)/config.h.in $(top_srcdir)/scripts/init.d/cgconfig.in \
4b3140
 	$(top_srcdir)/scripts/init.d/cgred.in \
4b3140
 	$(srcdir)/libcgroup.pc.in COPYING INSTALL README config.guess \
4b3140
-	config.sub install-sh missing ltmain.sh
4b3140
+	config.sub depcomp install-sh missing ylwrap ltmain.sh
4b3140
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
4b3140
 am__aclocal_m4_deps = $(top_srcdir)/configure.in
4b3140
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
4b3140
diff --git a/doc/man/cgconfig.conf.5 b/doc/man/cgconfig.conf.5
4b3140
index be80e4e..a7d9935 100644
4b3140
--- a/doc/man/cgconfig.conf.5
4b3140
+++ b/doc/man/cgconfig.conf.5
4b3140
@@ -251,6 +251,9 @@ Templates does not use
4b3140
 .B default
4b3140
 section settings.
4b3140
 
4b3140
+.I /etc/cgconfig.d/
4b3140
+directory can be used for additional configuration files. cgrulesengd searches this directory for additional templates.
4b3140
+
4b3140
 .\"********************************************"
4b3140
 .SH EXAMPLES
4b3140
 .LP
4b3140
@@ -783,10 +786,12 @@ related to them.
4b3140
 .SH FILES
4b3140
 .LP
4b3140
 .PD .1v
4b3140
-.TP 20
4b3140
+.TP
4b3140
 .B /etc/cgconfig.conf
4b3140
 .TP
4b3140
 default libcgroup configuration file
4b3140
+.B /etc/cgconfig.d/
4b3140
+default libcgroup configuration files directory
4b3140
 .PD 
4b3140
 
4b3140
 .SH SEE ALSO
4b3140
diff --git a/doc/man/cgrulesengd.8 b/doc/man/cgrulesengd.8
4b3140
index 2e89c5b..749b6fc 100644
4b3140
--- a/doc/man/cgrulesengd.8
4b3140
+++ b/doc/man/cgrulesengd.8
4b3140
@@ -65,10 +65,16 @@ controls verbosity of the tool. Allowed values are \fBDEBUG\fR,
4b3140
 .SH FILES
4b3140
 .LP
4b3140
 .PD .1v
4b3140
-.TP 20
4b3140
+.TP
4b3140
 .B /etc/cgrules.conf
4b3140
 .TP
4b3140
 the default libcgroup configuration file
4b3140
+.TP
4b3140
+.B /etc/cgconfig.conf
4b3140
+the default templates file
4b3140
+.TP
4b3140
+.B /etc/cgconfig.d/
4b3140
+the default templates directory
4b3140
 
4b3140
 .SH SEE ALSO
4b3140
 cgrules.conf (5)
4b3140
diff --git a/include/libcgroup/config.h b/include/libcgroup/config.h
4b3140
index 43568e1..9aaa390 100644
4b3140
--- a/include/libcgroup/config.h
4b3140
+++ b/include/libcgroup/config.h
4b3140
@@ -84,11 +84,32 @@ int cgroup_init_templates_cache(char *pathname);
4b3140
 int cgroup_reload_cached_templates(char *pathname);
4b3140
 
4b3140
 /**
4b3140
+ * Load the templates cache from files. Before calling this function,
4b3140
+ * cgroup_templates_cache_set_source_files has to be called first.
4b3140
+ * @param file_index index of file which was unable to be parsed
4b3140
+ * @return 0 on success, > 0 on error
4b3140
+ */
4b3140
+int cgroup_load_templates_cache_from_files(int *file_index);
4b3140
+
4b3140
+/**
4b3140
+ * Setting source files of templates. This function has to be called before
4b3140
+ * any call of cgroup_load_templates_cache_from_files.
4b3140
+ * @param tmpl_files
4b3140
+ */
4b3140
+struct cgroup_string_list;
4b3140
+void cgroup_templates_cache_set_source_files(
4b3140
+	struct cgroup_string_list *tmpl_files);
4b3140
+
4b3140
+/**
4b3140
  * Physically create a new control group in kernel, based on given control
4b3140
  * group template and configuration file. If given template is not set in
4b3140
  * configuration file, then the procedure works create the control group
4b3140
  * using  cgroup_create_cgroup() function
4b3140
  *
4b3140
+ * Templates are loaded using cgroup_load_templates_cache_from_files
4b3140
+ * function, which must be preceded by cgroup_templates_cache_set_source_files
4b3140
+ * call.
4b3140
+ *
4b3140
  * The flags can alter the behavior of this function:
4b3140
  * CGFLAG_USE_TEMPLATE_CACHE: Use cached templates instead of
4b3140
  * parsing the config file
4b3140
diff --git a/src/config.c b/src/config.c
4b3140
index e1ee0a8..1c5fc14 100644
4b3140
--- a/src/config.c
4b3140
+++ b/src/config.c
4b3140
@@ -41,6 +41,8 @@
4b3140
 #include <sys/stat.h>
4b3140
 #include <sys/types.h>
4b3140
 
4b3140
+#include "tools/tools-common.h"
4b3140
+
4b3140
 unsigned int MAX_CGROUPS = 64;	/* NOTE: This value changes dynamically */
4b3140
 unsigned int MAX_TEMPLATES = 64;
4b3140
 				/* NOTE: This value changes dynamically */
4b3140
@@ -89,6 +91,7 @@ static int config_template_table_index;
4b3140
  */
4b3140
 static struct cgroup *template_table;
4b3140
 static int template_table_index;
4b3140
+static struct cgroup_string_list *template_files;
4b3140
 
4b3140
 
4b3140
 /*
4b3140
@@ -1572,6 +1575,161 @@ int cgroup_init_templates_cache(char *pathname)
4b3140
 
4b3140
 }
4b3140
 
4b3140
+/**
4b3140
+ * Setting source files of templates. This function has to be called before
4b3140
+ * any call of cgroup_load_templates_cache_from_files.
4b3140
+ * @param tmpl_files
4b3140
+ */
4b3140
+void cgroup_templates_cache_set_source_files(
4b3140
+	struct cgroup_string_list *tmpl_files)
4b3140
+{
4b3140
+	template_files = tmpl_files;
4b3140
+}
4b3140
+
4b3140
+/**
4b3140
+ * Appending cgroup templates parsed by parser to template_table
4b3140
+ * @param offset number of templates already in the table
4b3140
+ */
4b3140
+int cgroup_add_cgroup_templates(int offset)
4b3140
+{
4b3140
+	int i, ti, ret;
4b3140
+
4b3140
+	for (i = 0; i < config_template_table_index; i++) {
4b3140
+		ti = i + offset;
4b3140
+		ret = cgroup_copy_cgroup(&template_table[ti],
4b3140
+			&config_template_table[i]);
4b3140
+		if (ret)
4b3140
+			return ret;
4b3140
+
4b3140
+		strcpy((template_table[ti]).name,
4b3140
+			(config_template_table[i]).name);
4b3140
+		template_table[ti].tasks_uid =
4b3140
+			config_template_table[i].tasks_uid;
4b3140
+		template_table[ti].tasks_gid =
4b3140
+			config_template_table[i].tasks_gid;
4b3140
+		template_table[ti].task_fperm =
4b3140
+			config_template_table[i].task_fperm;
4b3140
+		template_table[ti].control_uid =
4b3140
+			config_template_table[i].control_uid;
4b3140
+		template_table[ti].control_gid =
4b3140
+			config_template_table[i].control_gid;
4b3140
+		template_table[ti].control_fperm =
4b3140
+			config_template_table[i].control_fperm;
4b3140
+		template_table[ti].control_dperm =
4b3140
+			config_template_table[i].control_dperm;
4b3140
+	}
4b3140
+
4b3140
+	return 0;
4b3140
+}
4b3140
+
4b3140
+/**
4b3140
+ * Expand template table based on new number of parsed templates, i.e.
4b3140
+ * on value of config_template_table_index.
4b3140
+ * Change value of template_table_index.
4b3140
+ * @return 0 on success, < 0 on error
4b3140
+ */
4b3140
+int cgroup_expand_template_table(void)
4b3140
+{
4b3140
+	int i;
4b3140
+
4b3140
+	template_table = realloc(template_table,
4b3140
+		(template_table_index + config_template_table_index)
4b3140
+		*sizeof(struct cgroup));
4b3140
+
4b3140
+	if (template_table == NULL)
4b3140
+		return -ECGOTHER;
4b3140
+
4b3140
+	for (i = 0; i < config_template_table_index; i++)
4b3140
+		template_table[i + template_table_index].index = 0;
4b3140
+
4b3140
+	template_table_index += config_template_table_index;
4b3140
+
4b3140
+	return 0;
4b3140
+}
4b3140
+
4b3140
+/**
4b3140
+ * Load the templates cache from files. Before calling this function,
4b3140
+ * cgroup_templates_cache_set_source_files has to be called first.
4b3140
+ * @param file_index index of file which was unable to be parsed
4b3140
+ * @return 0 on success, > 0 on error
4b3140
+ */
4b3140
+int cgroup_load_templates_cache_from_files(int *file_index)
4b3140
+{
4b3140
+	int ret;
4b3140
+	int i, j;
4b3140
+	int template_table_last_index;
4b3140
+	char *pathname;
4b3140
+
4b3140
+	if (!template_files) {
4b3140
+		/* source files has not been set */
4b3140
+		cgroup_dbg("Template source files have not been set. ");
4b3140
+		cgroup_dbg("Using only %s\n", CGCONFIG_CONF_FILE);
4b3140
+
4b3140
+		if (template_table_index == 0)
4b3140
+			/* the rules cache is empty */
4b3140
+			return cgroup_init_templates_cache(
4b3140
+				CGCONFIG_CONF_FILE);
4b3140
+		else
4b3140
+			/* cache is not empty */
4b3140
+			return cgroup_reload_cached_templates(
4b3140
+				CGCONFIG_CONF_FILE);
4b3140
+	}
4b3140
+
4b3140
+	if (template_table) {
4b3140
+		/* template structures have to be free */
4b3140
+		for (i = 0; i < template_table_index; i++)
4b3140
+			cgroup_free_controllers(&template_table[i]);
4b3140
+		free(template_table);
4b3140
+		template_table = NULL;
4b3140
+	}
4b3140
+	template_table_index = 0;
4b3140
+
4b3140
+	if ((config_template_table_index != 0) || (config_table_index != 0)) {
4b3140
+		/* config structures have to be clean before parsing */
4b3140
+		cgroup_free_config();
4b3140
+	}
4b3140
+
4b3140
+	for (j = 0; j < template_files->count; j++) {
4b3140
+		pathname = template_files->items[j];
4b3140
+
4b3140
+		cgroup_dbg("Parsing templates from %s.\n", pathname);
4b3140
+		/* Attempt to read the configuration file
4b3140
+		 * and cache the rules. */
4b3140
+		ret = cgroup_parse_config(pathname);
4b3140
+		if (ret) {
4b3140
+			cgroup_dbg("Could not initialize rule cache, ");
4b3140
+			cgroup_dbg("error was: %d\n", ret);
4b3140
+			*file_index = j;
4b3140
+			return ret;
4b3140
+		}
4b3140
+
4b3140
+		if (config_template_table_index > 0) {
4b3140
+			template_table_last_index = template_table_index;
4b3140
+			ret = cgroup_expand_template_table();
4b3140
+			if (ret) {
4b3140
+				cgroup_dbg("Could not expand template table, ");
4b3140
+				cgroup_dbg("error was: %d\n", -ret);
4b3140
+				*file_index = j;
4b3140
+				return -ret;
4b3140
+			}
4b3140
+
4b3140
+			/* copy template data to templates cache structures */
4b3140
+			cgroup_dbg("Copying templates to template table ");
4b3140
+			cgroup_dbg("from %s.\n", pathname);
4b3140
+			ret = cgroup_add_cgroup_templates(
4b3140
+				template_table_last_index);
4b3140
+			if (ret) {
4b3140
+				cgroup_dbg("Unable to copy cgroup\n");
4b3140
+				*file_index = j;
4b3140
+				return ret;
4b3140
+			}
4b3140
+			cgroup_dbg("Templates to template table copied\n");
4b3140
+		}
4b3140
+	}
4b3140
+
4b3140
+	return 0;
4b3140
+}
4b3140
+
4b3140
 /*
4b3140
  * Create a given cgroup, based on template configuration if it is present
4b3140
  * if the template is not present cgroup is creted using cgroup_create_cgroup
4b3140
@@ -1593,13 +1751,22 @@ int cgroup_config_create_template_group(struct cgroup *cgroup,
4b3140
 	 * use CGCONFIG_CONF_FILE by default
4b3140
 	 */
4b3140
 	if (!(flags & CGFLAG_USE_TEMPLATE_CACHE)) {
4b3140
-		if (template_table_index == 0)
4b3140
-			/* the rules cache is empty */
4b3140
-			ret = cgroup_init_templates_cache(CGCONFIG_CONF_FILE);
4b3140
-		else
4b3140
-			/* cache is not empty */
4b3140
-			ret = cgroup_reload_cached_templates(
4b3140
-				CGCONFIG_CONF_FILE);
4b3140
+		int fileindex;
4b3140
+
4b3140
+		/* the rules cache is empty */
4b3140
+		ret = cgroup_load_templates_cache_from_files(
4b3140
+			&fileindex);
4b3140
+		if (ret != 0) {
4b3140
+			if (fileindex < 0) {
4b3140
+				cgroup_dbg("Error: Template source files ");
4b3140
+				cgroup_dbg("have not been set\n");
4b3140
+			} else {
4b3140
+			    cgroup_dbg("Error: Failed to load template");
4b3140
+			    cgroup_dbg("rules from %s. ",
4b3140
+				    template_files->items[fileindex]);
4b3140
+			}
4b3140
+		}
4b3140
+
4b3140
 		if (ret != 0) {
4b3140
 			cgroup_dbg("Failed initialize templates cache.\n");
4b3140
 			return ret;
4b3140
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
4b3140
index f3100ed..abbbe30 100644
4b3140
--- a/src/daemon/Makefile.am
4b3140
+++ b/src/daemon/Makefile.am
4b3140
@@ -1,9 +1,9 @@
4b3140
-INCLUDES = -I $(top_srcdir)/include
4b3140
+INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/include
4b3140
 
4b3140
 if WITH_DAEMON
4b3140
 
4b3140
 sbin_PROGRAMS = cgrulesengd
4b3140
-cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h
4b3140
+cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h ../tools/tools-common.h ../tools/tools-common.c
4b3140
 cgrulesengd_LDADD = $(top_builddir)/src/.libs/libcgroup.la -lrt
4b3140
 cgrulesengd_LDFLAGS = -L$(top_builddir)/src/.libs
4b3140
 
4b3140
diff --git a/src/daemon/Makefile.in b/src/daemon/Makefile.in
4b3140
index 76f7e07..f3efc65 100644
4b3140
--- a/src/daemon/Makefile.in
4b3140
+++ b/src/daemon/Makefile.in
4b3140
@@ -92,8 +92,10 @@ CONFIG_CLEAN_FILES =
4b3140
 CONFIG_CLEAN_VPATH_FILES =
4b3140
 am__installdirs = "$(DESTDIR)$(sbindir)"
4b3140
 PROGRAMS = $(sbin_PROGRAMS)
4b3140
-am__cgrulesengd_SOURCES_DIST = cgrulesengd.c cgrulesengd.h
4b3140
-@WITH_DAEMON_TRUE@am_cgrulesengd_OBJECTS = cgrulesengd.$(OBJEXT)
4b3140
+am__cgrulesengd_SOURCES_DIST = cgrulesengd.c cgrulesengd.h \
4b3140
+	../tools/tools-common.h ../tools/tools-common.c
4b3140
+@WITH_DAEMON_TRUE@am_cgrulesengd_OBJECTS = cgrulesengd.$(OBJEXT) \
4b3140
+@WITH_DAEMON_TRUE@	tools-common.$(OBJEXT)
4b3140
 cgrulesengd_OBJECTS = $(am_cgrulesengd_OBJECTS)
4b3140
 @WITH_DAEMON_TRUE@cgrulesengd_DEPENDENCIES =  \
4b3140
 @WITH_DAEMON_TRUE@	$(top_builddir)/src/.libs/libcgroup.la
4b3140
@@ -294,8 +296,8 @@ target_alias = @target_alias@
4b3140
 top_build_prefix = @top_build_prefix@
4b3140
 top_builddir = @top_builddir@
4b3140
 top_srcdir = @top_srcdir@
4b3140
-INCLUDES = -I $(top_srcdir)/include
4b3140
-@WITH_DAEMON_TRUE@cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h
4b3140
+INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/include
4b3140
+@WITH_DAEMON_TRUE@cgrulesengd_SOURCES = cgrulesengd.c cgrulesengd.h ../tools/tools-common.h ../tools/tools-common.c
4b3140
 @WITH_DAEMON_TRUE@cgrulesengd_LDADD = $(top_builddir)/src/.libs/libcgroup.la -lrt
4b3140
 @WITH_DAEMON_TRUE@cgrulesengd_LDFLAGS = -L$(top_builddir)/src/.libs
4b3140
 all: all-am
4b3140
@@ -393,6 +395,7 @@ distclean-compile:
4b3140
 	-rm -f *.tab.c
4b3140
 
4b3140
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgrulesengd.Po@am__quote@
4b3140
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools-common.Po@am__quote@
4b3140
 
4b3140
 .c.o:
4b3140
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
4b3140
@@ -415,6 +418,20 @@ distclean-compile:
4b3140
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
4b3140
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
4b3140
 
4b3140
+tools-common.o: ../tools/tools-common.c
4b3140
+@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
4b3140
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tools-common.Tpo $(DEPDIR)/tools-common.Po
4b3140
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='../tools/tools-common.c' object='tools-common.o' libtool=no @AMDEPBACKSLASH@
4b3140
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
4b3140
+@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
4b3140
+
4b3140
+tools-common.obj: ../tools/tools-common.c
4b3140
+@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`
4b3140
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/tools-common.Tpo $(DEPDIR)/tools-common.Po
4b3140
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='../tools/tools-common.c' object='tools-common.obj' libtool=no @AMDEPBACKSLASH@
4b3140
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
4b3140
+@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`
4b3140
+
4b3140
 mostlyclean-libtool:
4b3140
 	-rm -f *.lo
4b3140
 
4b3140
diff --git a/src/daemon/cgrulesengd.c b/src/daemon/cgrulesengd.c
4b3140
index 170837a..d959eff 100644
4b3140
--- a/src/daemon/cgrulesengd.c
4b3140
+++ b/src/daemon/cgrulesengd.c
4b3140
@@ -34,6 +34,7 @@
4b3140
 #include "libcgroup.h"
4b3140
 #include "cgrulesengd.h"
4b3140
 #include "../libcgroup-internal.h"
4b3140
+#include "../tools/tools-common.h"
4b3140
 
4b3140
 #include <errno.h>
4b3140
 #include <stdarg.h>
4b3140
@@ -59,6 +60,9 @@
4b3140
 
4b3140
 #define NUM_PER_REALLOCATIOM	(100)
4b3140
 
4b3140
+/* list of config files from CGCONFIG_CONF_FILE and CGCONFIG_CONF_DIR */
4b3140
+static struct cgroup_string_list template_files;
4b3140
+
4b3140
 /* Log file, NULL if logging to file is disabled */
4b3140
 FILE* logfile;
4b3140
 
4b3140
@@ -936,6 +940,8 @@ void cgre_flash_rules(int signum)
4b3140
 	/* Current time */
4b3140
 	time_t tm = time(0);
4b3140
 
4b3140
+	int fileindex;
4b3140
+
4b3140
 	flog(LOG_INFO, "Reloading rules configuration\n");
4b3140
 	flog(LOG_DEBUG, "Current time: %s\n", ctime(&tm));
4b3140
 
4b3140
@@ -949,7 +955,7 @@ void cgre_flash_rules(int signum)
4b3140
 	}
4b3140
 
4b3140
 	/* Ask libcgroup to reload the template rules table. */
4b3140
-	cgroup_reload_cached_templates(CGCONFIG_CONF_FILE);
4b3140
+	cgroup_load_templates_cache_from_files(&fileindex);
4b3140
 }
4b3140
 
4b3140
 /**
4b3140
@@ -962,11 +968,13 @@ void cgre_flash_templates(int signum)
4b3140
 	/* Current time */
4b3140
 	time_t tm = time(0);
4b3140
 
4b3140
+	int fileindex;
4b3140
+
4b3140
 	flog(LOG_INFO, "Reloading templates configuration.\n");
4b3140
 	flog(LOG_DEBUG, "Current time: %s\n", ctime(&tm));
4b3140
 
4b3140
 	/* Ask libcgroup to reload the templates table. */
4b3140
-	cgroup_reload_cached_templates(CGCONFIG_CONF_FILE);
4b3140
+	cgroup_load_templates_cache_from_files(&fileindex);
4b3140
 }
4b3140
 
4b3140
 /**
4b3140
@@ -1069,6 +1077,8 @@ int main(int argc, char *argv[])
4b3140
 		{NULL, 0, NULL, 0}
4b3140
 	};
4b3140
 
4b3140
+	int fileindex;
4b3140
+
4b3140
 	/* Make sure the user is root. */
4b3140
 	if (getuid() != 0) {
4b3140
 		fprintf(stderr, "Error: Only root can start/stop the control"
4b3140
@@ -1180,6 +1190,25 @@ int main(int argc, char *argv[])
4b3140
 	}
4b3140
 
4b3140
 	/* Ask libcgroup to load the configuration rules. */
4b3140
+	ret = cgroup_string_list_init(&template_files,
4b3140
+		CGCONFIG_CONF_FILES_LIST_MINIMUM_SIZE);
4b3140
+	if (ret) {
4b3140
+		fprintf(stderr, "%s: cannot init file list, out of memory?\n",
4b3140
+			argv[0]);
4b3140
+		goto finished_without_temp_files;
4b3140
+	}
4b3140
+	/* first add CGCONFIG_CONF_FILE into file list */
4b3140
+	ret = cgroup_string_list_add_item(&template_files, CGCONFIG_CONF_FILE);
4b3140
+	if (ret) {
4b3140
+		fprintf(stderr, "%s: cannot add file to list, out of memory?\n"
4b3140
+			, argv[0]);
4b3140
+		goto finished;
4b3140
+	}
4b3140
+
4b3140
+	/* then read CGCONFIG_CONF_DIR directory for additional config files */
4b3140
+	cgroup_string_list_add_directory(&template_files, CGCONFIG_CONF_DIR,
4b3140
+		argv[0]);
4b3140
+
4b3140
 	if ((ret = cgroup_init_rules_cache()) != 0) {
4b3140
 		fprintf(stderr, "Error: libcgroup failed to initialize rules"
4b3140
 				"cache from %s. %s\n", CGRULES_CONF_FILE,
4b3140
@@ -1188,11 +1217,18 @@ int main(int argc, char *argv[])
4b3140
 	}
4b3140
 
4b3140
 	/* ask libcgroup to load template rules as well */
4b3140
-	ret = cgroup_init_templates_cache(CGCONFIG_CONF_FILE);
4b3140
+	cgroup_templates_cache_set_source_files(&template_files);
4b3140
+	ret = cgroup_load_templates_cache_from_files(&fileindex);
4b3140
 	if (ret != 0) {
4b3140
-		fprintf(stderr, "Error: libcgroup failed to initialize teplate"\
4b3140
-				"rules from %s. %s\n", CGCONFIG_CONF_FILE,
4b3140
-				cgroup_strerror(ret));
4b3140
+		if (fileindex < 0) {
4b3140
+			fprintf(stderr, "Error: Template source files ");
4b3140
+			fprintf(stderr, "have not been set\n");
4b3140
+		} else {
4b3140
+			fprintf(stderr, "Error: Failed to initialize template");
4b3140
+			fprintf(stderr, "rules from %s. ",
4b3140
+				template_files.items[fileindex]);
4b3140
+			fprintf(stderr, "%s\n", cgroup_strerror(-ret));
4b3140
+		}
4b3140
 		goto finished;
4b3140
 	}
4b3140
 
4b3140
@@ -1259,6 +1295,9 @@ int main(int argc, char *argv[])
4b3140
 	ret =  cgre_create_netlink_socket_process_msg();
4b3140
 
4b3140
 finished:
4b3140
+	cgroup_string_list_free(&template_files);
4b3140
+
4b3140
+finished_without_temp_files:
4b3140
 	if (logfile && logfile != stdout)
4b3140
 		fclose(logfile);
4b3140
 
4b3140
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
4b3140
index 4c0f46c..c128788 100644
4b3140
--- a/src/libcgroup-internal.h
4b3140
+++ b/src/libcgroup-internal.h
4b3140
@@ -48,6 +48,9 @@ __BEGIN_DECLS
4b3140
 
4b3140
 
4b3140
 #define CGCONFIG_CONF_FILE		"/etc/cgconfig.conf"
4b3140
+/* Minimum number of file in template file list for cgrulesengd */
4b3140
+#define CGCONFIG_CONF_FILES_LIST_MINIMUM_SIZE   4
4b3140
+#define CGCONFIG_CONF_DIR               "/etc/cgconfig.d"
4b3140
 
4b3140
 #define CGRULES_CONF_FILE       "/etc/cgrules.conf"
4b3140
 #define CGRULES_MAX_FIELDS_PER_LINE		3
4b3140
diff --git a/src/libcgroup.map b/src/libcgroup.map
4b3140
index b0c162c..f8b0fb9 100644
4b3140
--- a/src/libcgroup.map
4b3140
+++ b/src/libcgroup.map
4b3140
@@ -117,3 +117,8 @@ CGROUP_0.39 {
4b3140
 	cgroup_log;
4b3140
 	cgroup_parse_log_level_str;
4b3140
 } CGROUP_0.38;
4b3140
+
4b3140
+CGROUP_0.40 {
4b3140
+	cgroup_templates_cache_set_source_files;
4b3140
+	cgroup_load_templates_cache_from_files;
4b3140
+} CGROUP_0.39;
4b3140
diff --git a/src/tools/tools-common.h b/src/tools/tools-common.h
4b3140
index e05465f..c723eb4 100644
4b3140
--- a/src/tools/tools-common.h
4b3140
+++ b/src/tools/tools-common.h
4b3140
@@ -20,7 +20,7 @@
4b3140
 
4b3140
 #include "config.h"
4b3140
 #include <libcgroup.h>
4b3140
-#include <libcgroup-internal.h>
4b3140
+#include "../libcgroup-internal.h"
4b3140
 
4b3140
 #define cgroup_err(x...) cgroup_log(CGROUP_LOG_ERROR, x)
4b3140
 #define cgroup_warn(x...) cgroup_log(CGROUP_LOG_WARNING, x)
4b3140
-- 
4b3140
1.9.3
4b3140