Commit 911324ef by Daniel Lezcano Committed by Daniel Lezcano

encapsulate mount point code

Change the code to encapsulate the different mounts point. * mount on the host fs * mount relatively to the rootfs * mount absolutely to the rootfs (broken) That will make the code cleaner to fix the latter. Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent d330fe7b
...@@ -874,16 +874,18 @@ static void parse_mntopt(char *opt, unsigned long *flags, char **data) ...@@ -874,16 +874,18 @@ static void parse_mntopt(char *opt, unsigned long *flags, char **data)
strcat(*data, opt); strcat(*data, opt);
} }
static int parse_mntopts(struct mntent *mntent, unsigned long *mntflags, static int parse_mntopts(const char *mntopts, unsigned long *mntflags,
char **mntdata) char **mntdata)
{ {
char *s, *data; char *s, *data;
char *p, *saveptr = NULL; char *p, *saveptr = NULL;
if (!mntent->mnt_opts) *mntdata = NULL;
if (!mntopts)
return 0; return 0;
s = strdup(mntent->mnt_opts); s = strdup(mntopts);
if (!s) { if (!s) {
SYSERROR("failed to allocate memory"); SYSERROR("failed to allocate memory");
return -1; return -1;
...@@ -910,83 +912,126 @@ static int parse_mntopts(struct mntent *mntent, unsigned long *mntflags, ...@@ -910,83 +912,126 @@ static int parse_mntopts(struct mntent *mntent, unsigned long *mntflags,
return 0; return 0;
} }
static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file) static int mount_entry(const char *fsname, const char *target,
const char *fstype, unsigned long mountflags,
const char *data)
{
if (mount(fsname, target, fstype, mountflags & ~MS_REMOUNT, data)) {
SYSERROR("failed to mount '%s' on '%s'", fsname, target);
return -1;
}
if ((mountflags & MS_REMOUNT) || (mountflags & MS_BIND)) {
DEBUG("remounting %s on %s to respect bind or remount options",
fsname, target);
if (mount(fsname, target, fstype,
mountflags | MS_REMOUNT, data)) {
SYSERROR("failed to mount '%s' on '%s'",
fsname, target);
return -1;
}
}
DEBUG("mounted '%s' on '%s', type '%s'", fsname, target, fstype);
return 0;
}
static inline int mount_entry_on_systemfs(struct mntent *mntent)
{ {
struct mntent *mntent;
int ret = -1;
unsigned long mntflags; unsigned long mntflags;
char *mntdata; char *mntdata;
int ret;
if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
return -1;
}
ret = mount_entry(mntent->mnt_fsname, mntent->mnt_dir,
mntent->mnt_type, mntflags, mntdata);
free(mntdata);
return ret;
}
static int mount_entry_on_absolute_rootfs(struct mntent *mntent,
const char *rootfs)
{
char path[MAXPATHLEN]; char path[MAXPATHLEN];
const char *mntdir, *mntroot; unsigned long mntflags;
char *mntdata;
int ret;
while ((mntent = getmntent(file))) { if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
return -1;
}
mntflags = 0; if (strncmp(mntent->mnt_dir, rootfs, strlen(rootfs)))
mntdata = NULL; WARN("mount target directory '%s' is outside "
"container root", mntent->mnt_dir);
else
WARN("mount target directory '%s' is not "
"relative to container root", mntent->mnt_dir);
if (parse_mntopts(mntent, &mntflags, &mntdata) < 0) { ret = mount_entry(mntent->mnt_fsname, mntent->mnt_dir, mntent->mnt_type,
ERROR("failed to parse mount option '%s'", mntflags, mntdata);
mntent->mnt_opts);
goto out;
}
/* now figure out where to mount it to. */ free(mntdata);
mntdir = mntent->mnt_dir; return ret;
mntroot = NULL; }
if (!rootfs->path) { static int mount_entry_on_relative_rootfs(struct mntent *mntent,
/* if we use system root fs, the mount is relative to '/' const char *rootfs)
* and can be absolute */ {
if (mntdir[0] != '/') char path[MAXPATHLEN];
mntroot = ""; /* this is '/' */ unsigned long mntflags;
} else { char *mntdata;
/* else we have a separate root, mounts are int ret;
* relative to it, and absolute paths are risky */
if (mntdir[0] != '/')
/* relative to root mount point */
mntroot = rootfs->mount;
else if (strncmp(mntdir, rootfs->mount,
strlen(rootfs->mount)))
WARN("mount target directory '%s' is outside "
"container root", mntdir);
else
WARN("mount target directory '%s' is not "
"relative to container root", mntdir);
}
if (mntroot) { if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
/* make it relative to mntroot */ ERROR("failed to parse mount option '%s'", mntent->mnt_opts);
snprintf(path, sizeof(path), "%s/%s", mntroot, mntdir); return -1;
mntdir = path; }
}
if (mount(mntent->mnt_fsname, mntdir, /* relative to root mount point */
mntent->mnt_type, mntflags & ~MS_REMOUNT, mntdata)) { snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir);
SYSERROR("failed to mount '%s' on '%s'",
mntent->mnt_fsname, mntent->mnt_dir); ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
goto out; mntflags, mntdata);
}
free(mntdata);
if ((mntflags & MS_REMOUNT) == MS_REMOUNT || return ret;
((mntflags & MS_BIND) == MS_BIND)) { }
static int mount_file_entries(const struct lxc_rootfs *rootfs, FILE *file)
{
struct mntent *mntent;
int ret = -1;
DEBUG ("remounting %s on %s to respect bind " \ while ((mntent = getmntent(file))) {
"or remount options",
mntent->mnt_fsname, mntent->mnt_dir);
if (mount(mntent->mnt_fsname, mntent->mnt_dir, if (!rootfs->path) {
mntent->mnt_type, if (mount_entry_on_systemfs(mntent))
mntflags | MS_REMOUNT, mntdata)) {
SYSERROR("failed to mount '%s' on '%s'",
mntent->mnt_fsname, mntent->mnt_dir);
goto out; goto out;
} continue;
} }
DEBUG("mounted %s on %s, type %s", mntent->mnt_fsname, /* We have a separate root, mounts are relative to it */
mntent->mnt_dir, mntent->mnt_type); if (mntent->mnt_dir[0] != '/') {
if (mount_entry_on_relative_rootfs(mntent,
rootfs->mount))
goto out;
continue;
}
free(mntdata); if (mount_entry_on_absolute_rootfs(mntent, rootfs->path))
goto out;
} }
ret = 0; ret = 0;
......
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