[lxc-devel] [PATCH] Add support for new create=(dir, file) mount option
Stéphane Graber
stgraber at ubuntu.com
Thu Dec 5 22:45:23 UTC 2013
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 at 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
More information about the lxc-devel
mailing list