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

Stéphane Graber stgraber at ubuntu.com
Fri Jan 16 20:25:20 UTC 2015


On Fri, Jan 16, 2015 at 08:22:46PM +0000, Serge Hallyn wrote:
> 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>

Acked-by: Stéphane Graber <stgraber 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
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20150116/5b7ae709/attachment.sig>


More information about the lxc-devel mailing list