[lxc-devel] [patch 2/2] Add config.include support

Andrian Nord nightnord at gmail.com
Mon Nov 16 22:49:55 UTC 2009


> Why not "lxc.include" ?

Because lxc in 'linux container' (for me), and this option do nothing
with container itself. It's pure configuration value, so probably it
should be prefixed in some other way (that's why prefixes are used, or
not?)

> Aren't you including the same configuration file as the one you are 
> parsing here ?

It could be recursion, yes. But probably it's up to user to prevent it
(it's rather simple, imo), as implementation of recursion check whould
require to have some list that will keep all parsed configs and every
new config will check this list for itself, and still this could have
problems, as relative config could be specified in infinite count of
ways, so only solution that I see - to stat config file and remember
it's inode. Not very cheap task for fool-protection, but if you
insisting, i'll implement it.

> missing free:
>     ret = lxc_config_read(path, lxc_conf);
>     free(path);
>     return ret;

Memory leaks =). Fixed, sorry.

This is variant without fool-protection:
Signed-off-by: Andrian Nord <NightNord at gmail.com>

diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 5e0081c..7c0cf80 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -20,6 +20,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -32,6 +33,7 @@
 #include <netinet/in.h>
 #include <net/if.h>
 
+#include "config.h"
 #include "parse.h"
 
 #include <lxc/lxc.h>
@@ -39,6 +41,9 @@
 
 lxc_log_define(lxc_confile, lxc);
 
+int lxc_config_read(const char *file, struct lxc_conf *conf);
+
+static int config_include(const char *, char *, struct lxc_conf *);
 static int config_pts(const char *, char *, struct lxc_conf *);
 static int config_tty(const char *, char *, struct lxc_conf *);
 static int config_cgroup(const char *, char *, struct lxc_conf *);
@@ -56,13 +61,18 @@ static int config_network_ipv6(const char *, char *, struct lxc_conf *);
 
 typedef int (*config_cb)(const char *, char *, struct lxc_conf *);
 
+struct parsing_state {
+	const char *file;
+	struct lxc_conf *lxc_conf;
+};
+
 struct config {
 	char *name;
 	config_cb cb;
 };
 
 static struct config config[] = {
-
+	{ "config.include",     config_include        },
 	{ "lxc.pts",            config_pts            },
 	{ "lxc.tty",            config_tty            },
 	{ "lxc.cgroup",         config_cgroup         },
@@ -92,6 +102,30 @@ static struct config *getconfig(const char *key)
 	return NULL;
 }
 
+static int config_include(const char *key, char *value, struct lxc_conf *lxc_conf)
+{
+	char *path;
+	int ret;
+
+	DEBUG("including config %s", value);
+
+	if (value[0] == '/')
+		return lxc_config_read(value, lxc_conf);
+
+	if(!asprintf(&path, LXCPATH "/%s/%s", lxc_conf->name, value)) {
+		SYSERROR("failed to allocate memory");
+		return -1;
+	}
+
+	DEBUG("guessed absolute include path as %s", path);
+
+	ret = lxc_config_read(path, lxc_conf);
+
+	free(path);
+
+	return ret;
+}
+
 static int config_network_type(const char *key, char *value, struct lxc_conf *lxc_conf)
 {
 	struct lxc_list *network = &lxc_conf->network;
@@ -532,6 +566,7 @@ static int config_utsname(const char *key, char *value, struct lxc_conf *lxc_con
 static int parse_line(void *buffer, void *data)
 {
 	struct config *config;
+	struct parsing_state *state = data;
 	char *line = buffer;
 	char *dot;
 	char *key;
@@ -546,7 +581,7 @@ static int parse_line(void *buffer, void *data)
 
 	dot = strstr(line, "=");
 	if (!dot) {
-		ERROR("invalid configuration line: %s", line);
+		ERROR("%s: syntax error in line: %s", state->file, line);
 		return -1;
 	}
 
@@ -561,17 +596,21 @@ static int parse_line(void *buffer, void *data)
 
 	config = getconfig(key);
 	if (!config) {
-		ERROR("unknow key %s", key);
+		ERROR("%s: unknow key %s", state->file, key);
 		return -1;
 	}
 
-	return config->cb(key, value, data);
+	return config->cb(key, value, state->lxc_conf);
 }
 
 int lxc_config_read(const char *file, struct lxc_conf *conf)
 {
 	char buffer[MAXPATHLEN];
+	struct parsing_state state = {
+		.file = file,
+		.lxc_conf = conf
+	};
 
 	return lxc_file_for_each_line(file, parse_line, buffer,
-				      sizeof(buffer), conf);
+				      sizeof(buffer), &state);
 }




More information about the lxc-devel mailing list