[lxc-devel] [RFC] Fix for parsing various mount options
Ryousei Takano
takano-ryousei at aist.go.jp
Fri Apr 3 03:25:38 UTC 2009
Hi Daniel and all,
I am trying a fast container cloning using aufs (advanced multi layered
unification filesystem). That means a container rootfs is overlaid on top of
the template rootfs in a copy-on-write manner.
lxc-start setups the rootfs according to $LXCPATH/test/fstab:
none /opt/lxc.root/rootfs.test aufs br=/opt/lxc.root/cowfs.test:/opt/lxc.root/rootfs.debian.tmpl=ro 0 0
/opt/lxc.root/rootfs.test /usr/local/var/lib/lxc/test/rootfs none rbind 0 0
To do that, we need to pass the aufs specific mount option to mount(2).
But setup_mount() ignores this option.
This patch fixes setup_mount() for parsing these kind of options.
As far as I know hasmntopt(3) cannot parse non literal options, so it adds
a new function called parse_mntopts() instead of using hasmntopt(3).
Any comments and suggestions will be appreciated.
Signed-off-by: Ryousei Takano <takano-ryousei at aist.go.jp>
---
src/lxc/conf.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 81 insertions(+), 12 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 6c3476a..5da9660 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1026,13 +1026,82 @@ static int setup_cgroup(const char *name)
line, MAXPATHLEN, (void *)name);
}
+static int parse_mntopts(struct mntent *mntent, unsigned long *mntflags,
+ char **mntopts)
+{
+#if 1
+ char *s, *opts;
+ char *p, *saveptr = NULL;
+
+ if (!mntent->mnt_opts)
+ return 0;
+
+ s = strdup(mntent->mnt_opts);
+ if (!s) {
+ lxc_log_syserror("failed to allocate memory");
+ return -1;
+ }
+
+ opts = malloc(strlen(s) + 1);
+ if (!opts) {
+ lxc_log_syserror("failed to allocate memory");
+ free(s);
+ return -1;
+ }
+ *opts = 0;
+
+ for (p = strtok_r(s, ",", &saveptr); p != NULL;
+ p = strtok_r(NULL, ",", &saveptr)) {
+ if (!strncmp(p, "bind", strlen("bind"))) {
+ *mntflags |= MS_BIND;
+ continue;
+ }
+ if (!strncmp(p, "rbind", strlen("rbind"))) {
+ *mntflags |= MS_BIND|MS_REC;
+ continue;
+ }
+ if (!strncmp(p, "ro", strlen("ro"))) {
+ *mntflags |= MS_RDONLY;
+ continue;
+ }
+ if (!strncmp(p, "noexec", strlen("noexec"))) {
+ *mntflags |= MS_NOEXEC;
+ continue;
+ }
+
+ if (*opts == 0)
+ strcat(opts, p);
+ else {
+ strcat(opts, ",");
+ strcat(opts, p);
+ }
+ }
+
+ if (*opts)
+ *mntopts = opts;
+ free(s);
+#else
+ if (hasmntopt(mntent, "bind"))
+ *mntflags |= MS_BIND;
+ if (hasmntopt(mntent, "rbind"))
+ *mntflags |= MS_BIND|MS_REC;
+ if (hasmntopt(mntent, "ro"))
+ *mntflags |= MS_RDONLY;
+ if (hasmntopt(mntent, "noexec"))
+ *mntflags |= MS_NOEXEC;
+#endif
+
+ return 0;
+}
+
static int setup_mount(const char *name)
{
char path[MAXPATHLEN];
struct mntent *mntent;
FILE *file;
int ret = -1;
- unsigned long mntflags = 0;
+ unsigned long mntflags;
+ char *mntopts;
snprintf(path, MAXPATHLEN, LXCPATH "/%s/fstab", name);
@@ -1044,23 +1113,23 @@ static int setup_mount(const char *name)
goto out;
}
- while((mntent = getmntent(file))) {
-
- if (hasmntopt(mntent, "bind"))
- mntflags |= MS_BIND;
- if (hasmntopt(mntent, "rbind"))
- mntflags |= MS_BIND|MS_REC;
- if (hasmntopt(mntent, "ro"))
- mntflags |= MS_RDONLY;
- if (hasmntopt(mntent, "noexec"))
- mntflags |= MS_NOEXEC;
+ while ((mntent = getmntent(file))) {
+ mntflags = 0;
+ mntopts = NULL;
+ if (parse_mntopts(mntent, &mntflags, &mntopts) < 0) {
+ lxc_log_error("failed to parse mount option '%s'",
+ mntent->mnt_opts);
+ goto out;
+ }
if (mount(mntent->mnt_fsname, mntent->mnt_dir,
- mntent->mnt_type, mntflags, NULL)) {
+ mntent->mnt_type, mntflags, mntopts)) {
lxc_log_syserror("failed to mount '%s' on '%s'",
mntent->mnt_fsname, mntent->mnt_dir);
goto out;
}
+
+ free(mntopts);
}
ret = 0;
out:
--
1.5.6.3
More information about the lxc-devel
mailing list