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

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