From 7b1b0409f5fc1828f0feb2086fe5b8184f7eb2c6 Mon Sep 17 00:00:00 2001 From: Jan Chaloupka Date: Sat, 20 Sep 2014 20:02:13 +0200 Subject: [PATCH] loading configuration files from /etc/cgconfig.d/ directory --- Makefile.in | 2 +- doc/man/cgconfig.conf.5 | 7 +- doc/man/cgrulesengd.8 | 8 +- include/libcgroup/config.h | 21 ++++++ src/config.c | 181 +++++++++++++++++++++++++++++++++++++++++++-- src/daemon/Makefile.am | 4 +- src/daemon/Makefile.in | 25 ++++++- src/daemon/cgrulesengd.c | 51 +++++++++++-- src/libcgroup-internal.h | 3 + src/libcgroup.map | 5 ++ src/tools/tools-common.h | 2 +- 11 files changed, 286 insertions(+), 23 deletions(-) diff --git a/Makefile.in b/Makefile.in index af6e89c..0349c93 100644 --- a/Makefile.in +++ b/Makefile.in @@ -84,7 +84,7 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/config.h.in $(top_srcdir)/scripts/init.d/cgconfig.in \ $(top_srcdir)/scripts/init.d/cgred.in \ $(srcdir)/libcgroup.pc.in COPYING INSTALL README config.guess \ - config.sub install-sh missing ltmain.sh + config.sub depcomp install-sh missing ylwrap ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ diff --git a/doc/man/cgconfig.conf.5 b/doc/man/cgconfig.conf.5 index be80e4e..a7d9935 100644 --- a/doc/man/cgconfig.conf.5 +++ b/doc/man/cgconfig.conf.5 @@ -251,6 +251,9 @@ Templates does not use .B default section settings. +.I /etc/cgconfig.d/ +directory can be used for additional configuration files. cgrulesengd searches this directory for additional templates. + .\"********************************************" .SH EXAMPLES .LP @@ -783,10 +786,12 @@ related to them. .SH FILES .LP .PD .1v -.TP 20 +.TP .B /etc/cgconfig.conf .TP default libcgroup configuration file +.B /etc/cgconfig.d/ +default libcgroup configuration files directory .PD .SH SEE ALSO diff --git a/doc/man/cgrulesengd.8 b/doc/man/cgrulesengd.8 index 2e89c5b..749b6fc 100644 --- a/doc/man/cgrulesengd.8 +++ b/doc/man/cgrulesengd.8 @@ -65,10 +65,16 @@ controls verbosity of the tool. Allowed values are \fBDEBUG\fR, .SH FILES .LP .PD .1v -.TP 20 +.TP .B /etc/cgrules.conf .TP the default libcgroup configuration file +.TP +.B /etc/cgconfig.conf +the default templates file +.TP +.B /etc/cgconfig.d/ +the default templates directory .SH SEE ALSO cgrules.conf (5) diff --git a/include/libcgroup/config.h b/include/libcgroup/config.h index 43568e1..9aaa390 100644 --- a/include/libcgroup/config.h +++ b/include/libcgroup/config.h @@ -84,11 +84,32 @@ int cgroup_init_templates_cache(char *pathname); int cgroup_reload_cached_templates(char *pathname); /** + * Load the templates cache from files. Before calling this function, + * cgroup_templates_cache_set_source_files has to be called first. + * @param file_index index of file which was unable to be parsed + * @return 0 on success, > 0 on error + */ +int cgroup_load_templates_cache_from_files(int *file_index); + +/** + * Setting source files of templates. This function has to be called before + * any call of cgroup_load_templates_cache_from_files. + * @param tmpl_files + */ +struct cgroup_string_list; +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 * using cgroup_create_cgroup() function * + * Templates are loaded using cgroup_load_templates_cache_from_files + * function, which must be preceded by cgroup_templates_cache_set_source_files + * call. + * * The flags can alter the behavior of this function: * CGFLAG_USE_TEMPLATE_CACHE: Use cached templates instead of * parsing the config file diff --git a/src/config.c b/src/config.c index e1ee0a8..1c5fc14 100644 --- a/src/config.c +++ b/src/config.c @@ -41,6 +41,8 @@ #include #include +#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; /* @@ -1572,6 +1575,161 @@ int cgroup_init_templates_cache(char *pathname) } +/** + * Setting source files of templates. This function has to be called before + * any call of cgroup_load_templates_cache_from_files. + * @param tmpl_files + */ +void cgroup_templates_cache_set_source_files( + struct cgroup_string_list *tmpl_files) +{ + template_files = tmpl_files; +} + +/** + * Appending cgroup templates parsed by parser to template_table + * @param offset number of templates already in the table + */ +int cgroup_add_cgroup_templates(int offset) +{ + int i, ti, ret; + + for (i = 0; i < config_template_table_index; i++) { + ti = i + offset; + ret = cgroup_copy_cgroup(&template_table[ti], + &config_template_table[i]); + if (ret) + return ret; + + 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; + } + + return 0; +} + +/** + * Expand template table based on new number of parsed templates, i.e. + * on value of config_template_table_index. + * Change value of template_table_index. + * @return 0 on success, < 0 on error + */ +int cgroup_expand_template_table(void) +{ + int i; + + template_table = realloc(template_table, + (template_table_index + config_template_table_index) + *sizeof(struct cgroup)); + + if (template_table == NULL) + return -ECGOTHER; + + for (i = 0; i < config_template_table_index; i++) + template_table[i + template_table_index].index = 0; + + template_table_index += config_template_table_index; + + return 0; +} + +/** + * Load the templates cache from files. Before calling this function, + * cgroup_templates_cache_set_source_files has to be called first. + * @param file_index index of file which was unable to be parsed + * @return 0 on success, > 0 on error + */ +int cgroup_load_templates_cache_from_files(int *file_index) +{ + int ret; + int i, j; + int template_table_last_index; + char *pathname; + + if (!template_files) { + /* source files has not been set */ + cgroup_dbg("Template source files have not been set. "); + cgroup_dbg("Using only %s\n", CGCONFIG_CONF_FILE); + + if (template_table_index == 0) + /* the rules cache is empty */ + return cgroup_init_templates_cache( + CGCONFIG_CONF_FILE); + else + /* cache is not empty */ + return cgroup_reload_cached_templates( + CGCONFIG_CONF_FILE); + } + + 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 before parsing */ + cgroup_free_config(); + } + + for (j = 0; j < template_files->count; j++) { + pathname = template_files->items[j]; + + cgroup_dbg("Parsing 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, "); + cgroup_dbg("error was: %d\n", ret); + *file_index = j; + return ret; + } + + if (config_template_table_index > 0) { + template_table_last_index = template_table_index; + ret = cgroup_expand_template_table(); + if (ret) { + cgroup_dbg("Could not expand template table, "); + cgroup_dbg("error was: %d\n", -ret); + *file_index = j; + return -ret; + } + + /* copy template data to templates cache structures */ + cgroup_dbg("Copying templates to template table "); + cgroup_dbg("from %s.\n", pathname); + ret = cgroup_add_cgroup_templates( + template_table_last_index); + if (ret) { + cgroup_dbg("Unable to copy cgroup\n"); + *file_index = j; + return ret; + } + cgroup_dbg("Templates to template table copied\n"); + } + } + + return 0; +} + /* * 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 +1751,22 @@ int cgroup_config_create_template_group(struct cgroup *cgroup, * use CGCONFIG_CONF_FILE by default */ if (!(flags & CGFLAG_USE_TEMPLATE_CACHE)) { - if (template_table_index == 0) - /* the rules cache is empty */ - ret = cgroup_init_templates_cache(CGCONFIG_CONF_FILE); - else - /* cache is not empty */ - ret = cgroup_reload_cached_templates( - CGCONFIG_CONF_FILE); + int fileindex; + + /* the rules cache is empty */ + ret = cgroup_load_templates_cache_from_files( + &fileindex); + if (ret != 0) { + if (fileindex < 0) { + cgroup_dbg("Error: Template source files "); + cgroup_dbg("have not been set\n"); + } else { + cgroup_dbg("Error: Failed to load template"); + cgroup_dbg("rules from %s. ", + template_files->items[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..d959eff 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 #include @@ -59,6 +60,9 @@ #define NUM_PER_REALLOCATIOM (100) +/* list of config files from CGCONFIG_CONF_FILE and CGCONFIG_CONF_DIR */ +static struct cgroup_string_list template_files; + /* Log file, NULL if logging to file is disabled */ FILE* logfile; @@ -936,6 +940,8 @@ void cgre_flash_rules(int signum) /* Current time */ time_t tm = time(0); + int fileindex; + flog(LOG_INFO, "Reloading rules configuration\n"); flog(LOG_DEBUG, "Current time: %s\n", ctime(&tm)); @@ -949,7 +955,7 @@ void cgre_flash_rules(int signum) } /* Ask libcgroup to reload the template rules table. */ - cgroup_reload_cached_templates(CGCONFIG_CONF_FILE); + cgroup_load_templates_cache_from_files(&fileindex); } /** @@ -962,11 +968,13 @@ void cgre_flash_templates(int signum) /* Current time */ time_t tm = time(0); + int fileindex; + flog(LOG_INFO, "Reloading templates configuration.\n"); flog(LOG_DEBUG, "Current time: %s\n", ctime(&tm)); /* Ask libcgroup to reload the templates table. */ - cgroup_reload_cached_templates(CGCONFIG_CONF_FILE); + cgroup_load_templates_cache_from_files(&fileindex); } /** @@ -1069,6 +1077,8 @@ int main(int argc, char *argv[]) {NULL, 0, NULL, 0} }; + int fileindex; + /* Make sure the user is root. */ if (getuid() != 0) { fprintf(stderr, "Error: Only root can start/stop the control" @@ -1180,6 +1190,25 @@ int main(int argc, char *argv[]) } /* Ask libcgroup to load the configuration rules. */ + ret = cgroup_string_list_init(&template_files, + CGCONFIG_CONF_FILES_LIST_MINIMUM_SIZE); + if (ret) { + fprintf(stderr, "%s: cannot init file list, out of memory?\n", + argv[0]); + goto finished_without_temp_files; + } + /* 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,11 +1217,18 @@ int main(int argc, char *argv[]) } /* ask libcgroup to load template rules as well */ - ret = cgroup_init_templates_cache(CGCONFIG_CONF_FILE); + cgroup_templates_cache_set_source_files(&template_files); + ret = cgroup_load_templates_cache_from_files(&fileindex); if (ret != 0) { - fprintf(stderr, "Error: libcgroup failed to initialize teplate"\ - "rules from %s. %s\n", CGCONFIG_CONF_FILE, - cgroup_strerror(ret)); + if (fileindex < 0) { + fprintf(stderr, "Error: Template source files "); + fprintf(stderr, "have not been set\n"); + } else { + fprintf(stderr, "Error: Failed to initialize template"); + fprintf(stderr, "rules from %s. ", + template_files.items[fileindex]); + fprintf(stderr, "%s\n", cgroup_strerror(-ret)); + } goto finished; } @@ -1259,6 +1295,9 @@ int main(int argc, char *argv[]) ret = cgre_create_netlink_socket_process_msg(); finished: + cgroup_string_list_free(&template_files); + +finished_without_temp_files: if (logfile && logfile != stdout) fclose(logfile); 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..f8b0fb9 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -117,3 +117,8 @@ CGROUP_0.39 { cgroup_log; cgroup_parse_log_level_str; } CGROUP_0.38; + +CGROUP_0.40 { + cgroup_templates_cache_set_source_files; + cgroup_load_templates_cache_from_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 -#include +#include "../libcgroup-internal.h" #define cgroup_err(x...) cgroup_log(CGROUP_LOG_ERROR, x) #define cgroup_warn(x...) cgroup_log(CGROUP_LOG_WARNING, x) -- 1.9.3