Just like we already had "optional", this adds two new LXC-specific
mount flags:
 - create=dir (will do a mkdir_p on the path)
 - create=file (will do a mkdir_p on the dirname + a fopen on the path)

This was motivated by some of the needed bind-mounts for the
unprivileged containers.

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 src/lxc/conf.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 6542ce1..0beb12b 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1906,18 +1906,41 @@ static inline int mount_entry_on_systemfs(struct mntent 
*mntent)
        unsigned long mntflags;
        char *mntdata;
        int ret;
+       FILE *pathfile = NULL;
+       char* pathdirname = NULL;
 
        if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
                ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
                return -1;
        }
 
+       if (hasmntopt(mntent, "create=dir")) {
+               if (!mkdir_p(mntent->mnt_dir, 0755)) {
+                       WARN("Failed to create mount target '%s'", 
mntent->mnt_dir);
+                       ret = -1;
+               }
+       }
+
+       if (hasmntopt(mntent, "create=file") && access(mntent->mnt_dir, F_OK)) {
+               pathdirname = strdup(mntent->mnt_dir);
+               pathdirname = dirname(pathdirname);
+               mkdir_p(pathdirname, 0755);
+               pathfile = fopen(mntent->mnt_dir, "wb");
+               if (!pathfile) {
+                       WARN("Failed to create mount target '%s'", 
mntent->mnt_dir);
+                       ret = -1;
+               }
+               else
+                       fclose(pathfile);
+       }
+
        ret = mount_entry(mntent->mnt_fsname, mntent->mnt_dir,
                          mntent->mnt_type, mntflags, mntdata);
 
        if (hasmntopt(mntent, "optional") != NULL)
                ret = 0;
 
+       free(pathdirname);
        free(mntdata);
 
        return ret;
@@ -1933,6 +1956,8 @@ static int mount_entry_on_absolute_rootfs(struct mntent 
*mntent,
        char *mntdata;
        int r, ret = 0, offset;
        const char *lxcpath;
+       FILE *pathfile = NULL;
+       char *pathdirname = NULL;
 
        if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
                ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
@@ -1975,6 +2000,25 @@ skipabs:
                goto out;
        }
 
+       if (hasmntopt(mntent, "create=dir")) {
+               if (!mkdir_p(path, 0755)) {
+                       WARN("Failed to create mount target '%s'", path);
+                       ret = -1;
+               }
+       }
+
+       if (hasmntopt(mntent, "create=file") && access(path, F_OK)) {
+               pathdirname = strdup(path);
+               pathdirname = dirname(pathdirname);
+               mkdir_p(pathdirname, 0755);
+               pathfile = fopen(path, "wb");
+               if (!pathfile) {
+                       WARN("Failed to create mount target '%s'", path);
+                       ret = -1;
+               }
+               else
+                       fclose(pathfile);
+       }
 
        ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
                          mntflags, mntdata);
@@ -1983,6 +2027,7 @@ skipabs:
                ret = 0;
 
 out:
+       free(pathdirname);
        free(mntdata);
        return ret;
 }
@@ -1994,25 +2039,48 @@ static int mount_entry_on_relative_rootfs(struct mntent 
*mntent,
        unsigned long mntflags;
        char *mntdata;
        int ret;
+       FILE *pathfile = NULL;
+       char *pathdirname = NULL;
 
        if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
                ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
                return -1;
        }
 
-        /* relative to root mount point */
+       /* relative to root mount point */
        ret = snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir);
        if (ret >= sizeof(path)) {
                ERROR("path name too long");
                return -1;
        }
 
+       if (hasmntopt(mntent, "create=dir")) {
+               if (!mkdir_p(path, 0755)) {
+                       WARN("Failed to create mount target '%s'", path);
+                       ret = -1;
+               }
+       }
+
+       if (hasmntopt(mntent, "create=file") && access(path, F_OK)) {
+               pathdirname = strdup(path);
+               pathdirname = dirname(pathdirname);
+               mkdir_p(pathdirname, 0755);
+               pathfile = fopen(path, "wb");
+               if (!pathfile) {
+                       WARN("Failed to create mount target '%s'", path);
+                       ret = -1;
+               }
+               else
+                       fclose(pathfile);
+       }
+
        ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
                          mntflags, mntdata);
 
        if (hasmntopt(mntent, "optional") != NULL)
                ret = 0;
 
+       free(pathdirname);
        free(mntdata);
 
        return ret;
-- 
1.8.5.1


------------------------------------------------------------------------------
Sponsored by Intel(R) XDK 
Develop, test and display web and hybrid apps with a single code base.
Download it for free now!
http://pubads.g.doubleclick.net/gampad/clk?id=111408631&iu=/4140/ostg.clktrk
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to