]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Add support for new create=(dir,file) mount option
authorStéphane Graber <stgraber@ubuntu.com>
Thu, 5 Dec 2013 20:37:56 +0000 (15:37 -0500)
committerStéphane Graber <stgraber@ubuntu.com>
Fri, 6 Dec 2013 16:21:38 +0000 (11:21 -0500)
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 <stgraber@ubuntu.com>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
src/lxc/conf.c

index 6542ce1257fa03d1fc6e06ead3dff2ea867d417e..0beb12bb26244b840f287ca1312f6f45891b169f 100644 (file)
@@ -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;