]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
implement lxc.include for directories
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Fri, 16 Jan 2015 20:22:46 +0000 (20:22 +0000)
committerStéphane Graber <stgraber@ubuntu.com>
Fri, 16 Jan 2015 23:01:58 +0000 (18:01 -0500)
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@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/bdev.c
src/lxc/confile.c
src/lxc/utils.c
src/lxc/utils.h

index 5c6b00a22c93d61568cca5176c447973e104380b..c0cc050d13e65e9da7aea08eec78ba3155f8fe6a 100644 (file)
@@ -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)
index 036695935492d55846f1c06b96710365da1cc04a..1d429415a921a89730f41054323e432c7fc5c0db 100644 (file)
@@ -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);
 }
 
index 2037ef00f2d899a9f9a3cce7b5fdfec030d7563c..23b1b11ef43b5df5f9422ba2409037560276c1ea 100644 (file)
@@ -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;
+}
index 5ffafca50cb9fd70157166c0e7dddda50c14184d..ae2c851e2c5152a3b04022aaea9bf9ede49ef186 100644 (file)
@@ -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);