Commit 34cfffb3 by Stéphane Graber

Add support for new create=(dir,file) mount option

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: 's avatarStéphane Graber <stgraber@ubuntu.com> Acked-by: 's avatarSerge E. Hallyn <serge.hallyn@ubuntu.com>
parent d6eca240
...@@ -1906,18 +1906,41 @@ static inline int mount_entry_on_systemfs(struct mntent *mntent) ...@@ -1906,18 +1906,41 @@ static inline int mount_entry_on_systemfs(struct mntent *mntent)
unsigned long mntflags; unsigned long mntflags;
char *mntdata; char *mntdata;
int ret; int ret;
FILE *pathfile = NULL;
char* pathdirname = NULL;
if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) { if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
ERROR("failed to parse mount option '%s'", mntent->mnt_opts); ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
return -1; 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, ret = mount_entry(mntent->mnt_fsname, mntent->mnt_dir,
mntent->mnt_type, mntflags, mntdata); mntent->mnt_type, mntflags, mntdata);
if (hasmntopt(mntent, "optional") != NULL) if (hasmntopt(mntent, "optional") != NULL)
ret = 0; ret = 0;
free(pathdirname);
free(mntdata); free(mntdata);
return ret; return ret;
...@@ -1933,6 +1956,8 @@ static int mount_entry_on_absolute_rootfs(struct mntent *mntent, ...@@ -1933,6 +1956,8 @@ static int mount_entry_on_absolute_rootfs(struct mntent *mntent,
char *mntdata; char *mntdata;
int r, ret = 0, offset; int r, ret = 0, offset;
const char *lxcpath; const char *lxcpath;
FILE *pathfile = NULL;
char *pathdirname = NULL;
if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) { if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
ERROR("failed to parse mount option '%s'", mntent->mnt_opts); ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
...@@ -1975,6 +2000,25 @@ skipabs: ...@@ -1975,6 +2000,25 @@ skipabs:
goto out; 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, ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
mntflags, mntdata); mntflags, mntdata);
...@@ -1983,6 +2027,7 @@ skipabs: ...@@ -1983,6 +2027,7 @@ skipabs:
ret = 0; ret = 0;
out: out:
free(pathdirname);
free(mntdata); free(mntdata);
return ret; return ret;
} }
...@@ -1994,25 +2039,48 @@ static int mount_entry_on_relative_rootfs(struct mntent *mntent, ...@@ -1994,25 +2039,48 @@ static int mount_entry_on_relative_rootfs(struct mntent *mntent,
unsigned long mntflags; unsigned long mntflags;
char *mntdata; char *mntdata;
int ret; int ret;
FILE *pathfile = NULL;
char *pathdirname = NULL;
if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) { if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
ERROR("failed to parse mount option '%s'", mntent->mnt_opts); ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
return -1; return -1;
} }
/* relative to root mount point */ /* relative to root mount point */
ret = snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir); ret = snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir);
if (ret >= sizeof(path)) { if (ret >= sizeof(path)) {
ERROR("path name too long"); ERROR("path name too long");
return -1; 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, ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
mntflags, mntdata); mntflags, mntdata);
if (hasmntopt(mntent, "optional") != NULL) if (hasmntopt(mntent, "optional") != NULL)
ret = 0; ret = 0;
free(pathdirname);
free(mntdata); free(mntdata);
return ret; return ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment