[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