[lxc-devel] [PATCH] implement lxc.include for directories

Serge Hallyn serge.hallyn at ubuntu.com
Fri Jan 16 20:22:46 UTC 2015


Quoting Stéphane Graber (stgraber at ubuntu.com):
> On Fri, Jan 16, 2015 at 07:22:17PM +0000, Serge Hallyn wrote:
> > If you have 'lxc.include = /some/dir' and /some/dir is a directory, then any
> > '*.conf" files under /some/dir will be read.
> > 
> > Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
> 
> Some comments below.
> 
> Also, I'm wondering, what happens when you save_config(), does the save
> config retain the lxc.include = /path/to/dir or is that expanded to
> individual includes for each dir?

It retains the /path/to/dir:

# Template used to create this container: /usr/share/lxc/templates/lxc-download
# Parameters passed to the template: -d ubuntu -r trusty -a amd64
# For additional config options, please look at lxc.container.conf(5)
# Distribution configuration
lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.arch = x86_64
# Container specific configuration
lxc.rootfs = /var/lib/lxc/t1/rootfs
lxc.utsname = t1
# Network configuration
lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
lxc.include = /var/lib/lxc/t1/x

(/var/lib/lxc/t1/x is a directory)

Comments removed in below patch;

Subject: [PATCH 1/1] implement lxc.include for directories

If you have 'lxc.include = /some/dir' and /some/dir is a directory, then any
'*.conf" files under /some/dir will be read.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/bdev.c    |  9 ---------
 src/lxc/confile.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/utils.c   |  9 +++++++++
 src/lxc/utils.h   |  1 +
 4 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
index 5c6b00a..c0cc050 100644
--- a/src/lxc/bdev.c
+++ b/src/lxc/bdev.c
@@ -357,15 +357,6 @@ struct bdev_type {
 	const struct bdev_ops *ops;
 };
 
-static int is_dir(const char *path)
-{
-	struct stat statbuf;
-	int ret = stat(path, &statbuf);
-	if (ret == 0 && S_ISDIR(statbuf.st_mode))
-		return 1;
-	return 0;
-}
-
 static int dir_detect(const char *path)
 {
 	if (strncmp(path, "dir:", 4) == 0)
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 0366959..1d42941 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -37,6 +37,7 @@
 #include <netinet/in.h>
 #include <net/if.h>
 #include <time.h>
+#include <dirent.h>
 
 #include "parse.h"
 #include "config.h"
@@ -1663,9 +1664,60 @@ int append_unexp_config_line(const char *line, struct lxc_conf *conf)
 	return 0;
 }
 
+static int do_includedir(const char *dirp, struct lxc_conf *lxc_conf)
+{
+	struct dirent dirent, *direntp;
+	DIR *dir;
+	char path[MAXPATHLEN];
+	int ret = -1, len;
+
+	dir = opendir(dirp);
+	if (!dir) {
+		SYSERROR("failed to open '%s'", dirp);
+		return -1;
+	}
+
+	while (!readdir_r(dir, &dirent, &direntp)) {
+		const char *fnam;
+		if (!direntp)
+			break;
+
+		fnam = direntp->d_name;
+		if (!strcmp(fnam, "."))
+			continue;
+
+		if (!strcmp(fnam, ".."))
+			continue;
+
+		len = strlen(fnam);
+		if (len < 6 || strncmp(fnam+len-5, ".conf", 5) != 0)
+			continue;
+		len = snprintf(path, MAXPATHLEN, "%s/%s", dirp, fnam);
+		if (len < 0 || len >= MAXPATHLEN) {
+			ERROR("lxc.include filename too long under '%s'", dirp);
+			ret = -1;
+			goto out;
+		}
+
+		ret = lxc_config_read(path, lxc_conf, true);
+		if (ret < 0)
+			goto out;
+	}
+	ret = 0;
+
+out:
+	if (closedir(dir))
+		WARN("lxc.include dir: failed to close directory");
+
+	return ret;
+}
+
 static int config_includefile(const char *key, const char *value,
 			  struct lxc_conf *lxc_conf)
 {
+	if (is_dir(value))
+		return do_includedir(value, lxc_conf);
+
 	return lxc_config_read(value, lxc_conf, true);
 }
 
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 2037ef0..23b1b11 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -1497,3 +1497,12 @@ int print_to_file(const char *file, const char *content)
 	fclose(f);
 	return ret;
 }
+
+int is_dir(const char *path)
+{
+	struct stat statbuf;
+	int ret = stat(path, &statbuf);
+	if (ret == 0 && S_ISDIR(statbuf.st_mode))
+		return 1;
+	return 0;
+}
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 5ffafca..ae2c851 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -284,3 +284,4 @@ bool file_exists(const char *f);
 char *choose_init(const char *rootfs);
 int print_to_file(const char *file, const char *content);
 bool switch_to_ns(pid_t pid, const char *ns);
+int is_dir(const char *path);
-- 
2.1.0



More information about the lxc-devel mailing list