[lxc-devel] [PATCH] Implement lxc.rootfs.options (V2)

Stéphane Graber stgraber at ubuntu.com
Fri Jan 31 11:30:50 UTC 2014


Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/lxc.container.conf.sgml.in |  11 ++++
 src/lxc/bdev.c                 | 114 ++++++++++++++++++++++++++++++++---------
 src/lxc/bdev.h                 |   2 +-
 src/lxc/conf.c                 |  94 +++++++++++++++++++++------------
 src/lxc/conf.h                 |   3 ++
 src/lxc/confile.c              |  12 +++++
 6 files changed, 177 insertions(+), 59 deletions(-)

diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in
index aee5451..5313b97 100644
--- a/doc/lxc.container.conf.sgml.in
+++ b/doc/lxc.container.conf.sgml.in
@@ -864,6 +864,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 	<varlistentry>
 	  <term>
+	    <option>lxc.rootfs.options</option>
+	  </term>
+	  <listitem>
+	    <para>
+	      extra mount options to use when mounting the rootfs.
+	    </para>
+	  </listitem>
+	</varlistentry>
+
+	<varlistentry>
+	  <term>
 	    <option>lxc.pivotdir</option>
 	  </term>
 	  <listitem>
diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
index c4e5121..4cfa984 100644
--- a/src/lxc/bdev.c
+++ b/src/lxc/bdev.c
@@ -121,9 +121,11 @@ static int find_fstype_cb(char* buffer, void *data)
 	struct cbarg {
 		const char *rootfs;
 		const char *target;
-		int mntopt;
+		const char *options;
 	} *cbarg = data;
 
+	unsigned long mntflags;
+	char *mntdata;
 	char *fstype;
 
 	/* we don't try 'nodev' entries */
@@ -137,29 +139,38 @@ static int find_fstype_cb(char* buffer, void *data)
 	DEBUG("trying to mount '%s'->'%s' with fstype '%s'",
 	      cbarg->rootfs, cbarg->target, fstype);
 
-	if (mount(cbarg->rootfs, cbarg->target, fstype, cbarg->mntopt, NULL)) {
+	if (parse_mntopts(cbarg->options, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return 0;
+	}
+
+	if (mount(cbarg->rootfs, cbarg->target, fstype, mntflags, mntdata)) {
 		DEBUG("mount failed with error: %s", strerror(errno));
+		free(mntdata);
 		return 0;
 	}
 
+	free(mntdata);
+
 	INFO("mounted '%s' on '%s', with fstype '%s'",
 	     cbarg->rootfs, cbarg->target, fstype);
 
 	return 1;
 }
 
-static int mount_unknown_fs(const char *rootfs, const char *target, int mntopt)
+static int mount_unknown_fs(const char *rootfs, const char *target,
+			                const char *options)
 {
 	int i;
 
 	struct cbarg {
 		const char *rootfs;
 		const char *target;
-		int mntopt;
+		const char *options;
 	} cbarg = {
 		.rootfs = rootfs,
 		.target = target,
-		.mntopt = mntopt,
+		.options = options,
 	};
 
 	/*
@@ -291,7 +302,7 @@ static int detect_fs(struct bdev *bdev, char *type, int len)
 	if (unshare(CLONE_NEWNS) < 0)
 		exit(1);
 
-	ret = mount_unknown_fs(srcdev, bdev->dest, 0);
+	ret = mount_unknown_fs(srcdev, bdev->dest, bdev->mntopts);
 	if (ret < 0) {
 		ERROR("failed mounting %s onto %s to detect fstype", srcdev, bdev->dest);
 		exit(1);
@@ -355,11 +366,23 @@ static int dir_detect(const char *path)
 //
 static int dir_mount(struct bdev *bdev)
 {
+	unsigned long mntflags;
+	char *mntdata;
+	int ret;
+
 	if (strcmp(bdev->type, "dir"))
 		return -22;
 	if (!bdev->src || !bdev->dest)
 		return -22;
-	return mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC, NULL);
+
+	if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -22;
+	}
+
+	ret = mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags, mntdata);
+	free(mntdata);
+	return ret;
 }
 
 static int dir_umount(struct bdev *bdev)
@@ -532,11 +555,23 @@ static int zfs_detect(const char *path)
 
 static int zfs_mount(struct bdev *bdev)
 {
+	unsigned long mntflags;
+	char *mntdata;
+	int ret;
+
 	if (strcmp(bdev->type, "zfs"))
 		return -22;
 	if (!bdev->src || !bdev->dest)
 		return -22;
-	return mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC, NULL);
+
+	if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -22;
+	}
+
+	ret = mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags, mntdata);
+	free(mntdata);
+	return ret;
 }
 
 static int zfs_umount(struct bdev *bdev)
@@ -783,7 +818,7 @@ static int lvm_mount(struct bdev *bdev)
 		return -22;
 	/* if we might pass in data sometime, then we'll have to enrich
 	 * mount_unknown_fs */
-	return mount_unknown_fs(bdev->src, bdev->dest, 0);
+	return mount_unknown_fs(bdev->src, bdev->dest, bdev->mntopts);
 }
 
 static int lvm_umount(struct bdev *bdev)
@@ -996,9 +1031,9 @@ static int lvm_clonepaths(struct bdev *orig, struct bdev *new, const char *oldna
 			return -1;
 	}
 
-	if (orig->data) {
-		new->data = strdup(orig->data);
-		if (!new->data)
+	if (orig->mntopts) {
+		new->mntopts = strdup(orig->mntopts);
+		if (!new->mntopts)
 			return -1;
 	}
 
@@ -1191,11 +1226,23 @@ static int btrfs_detect(const char *path)
 
 static int btrfs_mount(struct bdev *bdev)
 {
+	unsigned long mntflags;
+	char *mntdata;
+	int ret;
+
 	if (strcmp(bdev->type, "btrfs"))
 		return -22;
 	if (!bdev->src || !bdev->dest)
 		return -22;
-	return mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC, NULL);
+
+	if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -22;
+	}
+
+	ret = mount(bdev->src, bdev->dest, "bind", MS_BIND | MS_REC | mntflags, mntdata);
+	free(mntdata);
+	return ret;
 }
 
 static int btrfs_umount(struct bdev *bdev)
@@ -1356,7 +1403,7 @@ static int btrfs_clonepaths(struct bdev *orig, struct bdev *new, const char *old
 	if ((new->dest = strdup(new->src)) == NULL)
 		return -1;
 
-	if (orig->data && (new->data = strdup(orig->data)) == NULL)
+	if (orig->mntopts && (new->mntopts = strdup(orig->mntopts)) == NULL)
 		return -1;
 
 	if (snap)
@@ -1508,7 +1555,7 @@ static int loop_mount(struct bdev *bdev)
 		goto out;
 	}
 
-	ret = mount_unknown_fs(loname, bdev->dest, 0);
+	ret = mount_unknown_fs(loname, bdev->dest, bdev->mntopts);
 	if (ret < 0)
 		ERROR("Error mounting %s\n", bdev->src);
 	else
@@ -1717,6 +1764,8 @@ static int overlayfs_mount(struct bdev *bdev)
 {
 	char *options, *dup, *lower, *upper;
 	int len;
+	unsigned long mntflags;
+	char *mntdata;
 	int ret;
 
 	if (strcmp(bdev->type, "overlayfs"))
@@ -1735,15 +1784,30 @@ static int overlayfs_mount(struct bdev *bdev)
 	*upper = '\0';
 	upper++;
 
+	if (parse_mntopts(bdev->mntopts, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -22;
+	}
+
 	// TODO We should check whether bdev->src is a blockdev, and if so
 	// but for now, only support overlays of a basic directory
 
-	len = strlen(lower) + strlen(upper) + strlen("upperdir=,lowerdir=") + 1;
-	options = alloca(len);
-	ret = snprintf(options, len, "upperdir=%s,lowerdir=%s", upper, lower);
-	if (ret < 0 || ret >= len)
+	if (mntdata) {
+		len = strlen(lower) + strlen(upper) + strlen("upperdir=,lowerdir=") + strlen(mntdata) + 1;
+		options = alloca(len);
+		ret = snprintf(options, len, "upperdir=%s,lowerdir=%s,%s", upper, lower, mntdata);
+	}
+	else {
+		len = strlen(lower) + strlen(upper) + strlen("upperdir=,lowerdir=") + 1;
+		options = alloca(len);
+		ret = snprintf(options, len, "upperdir=%s,lowerdir=%s", upper, lower);
+	}
+	if (ret < 0 || ret >= len) {
+		free(mntdata);
 		return -1;
-	ret = mount(lower, bdev->dest, "overlayfs", MS_MGC_VAL, options);
+	}
+
+	ret = mount(lower, bdev->dest, "overlayfs", MS_MGC_VAL | mntflags, options);
 	if (ret < 0)
 		SYSERROR("overlayfs: error mounting %s onto %s options %s",
 			lower, bdev->dest, options);
@@ -1946,8 +2010,8 @@ static const size_t numbdevs = sizeof(bdevs) / sizeof(struct bdev_type);
 
 void bdev_put(struct bdev *bdev)
 {
-	if (bdev->data)
-		free(bdev->data);
+	if (bdev->mntopts)
+		free(bdev->mntopts);
 	if (bdev->src)
 		free(bdev->src);
 	if (bdev->dest)
@@ -1975,7 +2039,7 @@ struct bdev *bdev_get(const char *type)
 	return bdev;
 }
 
-struct bdev *bdev_init(const char *src, const char *dst, const char *data)
+struct bdev *bdev_init(const char *src, const char *dst, const char *mntopts)
 {
 	int i;
 	struct bdev *bdev;
@@ -1995,8 +2059,8 @@ struct bdev *bdev_init(const char *src, const char *dst, const char *data)
 	memset(bdev, 0, sizeof(struct bdev));
 	bdev->ops = bdevs[i].ops;
 	bdev->type = bdevs[i].name;
-	if (data)
-		bdev->data = strdup(data);
+	if (mntopts)
+		bdev->mntopts = strdup(mntopts);
 	if (src)
 		bdev->src = strdup(src);
 	if (dst)
diff --git a/src/lxc/bdev.h b/src/lxc/bdev.h
index cc7b59e..f2d6dc0 100644
--- a/src/lxc/bdev.h
+++ b/src/lxc/bdev.h
@@ -78,7 +78,7 @@ struct bdev {
 	const char *type;
 	char *src;
 	char *dest;
-	char *data;
+	char *mntopts;
 	// turn the following into a union if need be
 	// lofd is the open fd for the mounted loopback file
 	int lofd;
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 8b790a2..d4578f3 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -424,9 +424,11 @@ static int find_fstype_cb(char* buffer, void *data)
 	struct cbarg {
 		const char *rootfs;
 		const char *target;
-		int mntopt;
+		const char *options;
 	} *cbarg = data;
 
+	unsigned long mntflags;
+	char *mntdata;
 	char *fstype;
 
 	/* we don't try 'nodev' entries */
@@ -440,10 +442,17 @@ static int find_fstype_cb(char* buffer, void *data)
 	DEBUG("trying to mount '%s'->'%s' with fstype '%s'",
 	      cbarg->rootfs, cbarg->target, fstype);
 
-	if (mount(cbarg->rootfs, cbarg->target, fstype, cbarg->mntopt, NULL)) {
+	if (parse_mntopts(cbarg->options, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -1;
+	}
+
+	if (mount(cbarg->rootfs, cbarg->target, fstype, mntflags, mntdata)) {
 		DEBUG("mount failed with error: %s", strerror(errno));
+		free(mntdata);
 		return 0;
 	}
+	free(mntdata);
 
 	INFO("mounted '%s' on '%s', with fstype '%s'",
 	     cbarg->rootfs, cbarg->target, fstype);
@@ -451,18 +460,19 @@ static int find_fstype_cb(char* buffer, void *data)
 	return 1;
 }
 
-static int mount_unknown_fs(const char *rootfs, const char *target, int mntopt)
+static int mount_unknown_fs(const char *rootfs, const char *target,
+			                const char *options)
 {
 	int i;
 
 	struct cbarg {
 		const char *rootfs;
 		const char *target;
-		int mntopt;
+		const char *options;
 	} cbarg = {
 		.rootfs = rootfs,
 		.target = target,
-		.mntopt = mntopt,
+		.options = options,
 	};
 
 	/*
@@ -496,9 +506,22 @@ static int mount_unknown_fs(const char *rootfs, const char *target, int mntopt)
 	return -1;
 }
 
-static int mount_rootfs_dir(const char *rootfs, const char *target)
+static int mount_rootfs_dir(const char *rootfs, const char *target,
+			                const char *options)
 {
-	return mount(rootfs, target, "none", MS_BIND | MS_REC, NULL);
+	unsigned long mntflags;
+	char *mntdata;
+	int ret;
+
+	if (parse_mntopts(options, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -1;
+	}
+
+	ret = mount(rootfs, target, "none", MS_BIND | MS_REC | mntflags, mntdata);
+	free(mntdata);
+
+	return ret;
 }
 
 static int setup_lodev(const char *rootfs, int fd, struct loop_info64 *loinfo)
@@ -533,7 +556,8 @@ out:
 	return ret;
 }
 
-static int mount_rootfs_file(const char *rootfs, const char *target)
+static int mount_rootfs_file(const char *rootfs, const char *target,
+				             const char *options)
 {
 	struct dirent dirent, *direntp;
 	struct loop_info64 loinfo;
@@ -585,7 +609,7 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
 
 		ret = setup_lodev(rootfs, fd, &loinfo);
 		if (!ret)
-			ret = mount_unknown_fs(path, target, 0);
+			ret = mount_unknown_fs(path, target, options);
 		close(fd);
 
 		break;
@@ -597,9 +621,10 @@ static int mount_rootfs_file(const char *rootfs, const char *target)
 	return ret;
 }
 
-static int mount_rootfs_block(const char *rootfs, const char *target)
+static int mount_rootfs_block(const char *rootfs, const char *target,
+			                  const char *options)
 {
-	return mount_unknown_fs(rootfs, target, 0);
+	return mount_unknown_fs(rootfs, target, options);
 }
 
 /*
@@ -729,13 +754,13 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_cg
 	return 0;
 }
 
-static int mount_rootfs(const char *rootfs, const char *target)
+static int mount_rootfs(const char *rootfs, const char *target, const char *options)
 {
 	char absrootfs[MAXPATHLEN];
 	struct stat s;
 	int i;
 
-	typedef int (*rootfs_cb)(const char *, const char *);
+	typedef int (*rootfs_cb)(const char *, const char *, const char *);
 
 	struct rootfs_type {
 		int type;
@@ -766,7 +791,7 @@ static int mount_rootfs(const char *rootfs, const char *target)
 		if (!__S_ISTYPE(s.st_mode, rtfs_type[i].type))
 			continue;
 
-		return rtfs_type[i].cb(absrootfs, target);
+		return rtfs_type[i].cb(absrootfs, target, options);
 	}
 
 	ERROR("unsupported rootfs type for '%s'", absrootfs);
@@ -1530,7 +1555,7 @@ static int setup_rootfs(struct lxc_conf *conf)
 	}
 
 	// First try mounting rootfs using a bdev
-	struct bdev *bdev = bdev_init(rootfs->path, rootfs->mount, NULL);
+	struct bdev *bdev = bdev_init(rootfs->path, rootfs->mount, rootfs->options);
 	if (bdev && bdev->ops->mount(bdev) == 0) {
 		bdev_put(bdev);
 		DEBUG("mounted '%s' on '%s'", rootfs->path, rootfs->mount);
@@ -1538,7 +1563,7 @@ static int setup_rootfs(struct lxc_conf *conf)
 	}
 	if (bdev)
 		bdev_put(bdev);
-	if (mount_rootfs(rootfs->path, rootfs->mount)) {
+	if (mount_rootfs(rootfs->path, rootfs->mount, rootfs->options)) {
 		ERROR("failed to mount rootfs");
 		return -1;
 	}
@@ -1791,7 +1816,7 @@ static void parse_mntopt(char *opt, unsigned long *flags, char **data)
 	strcat(*data, opt);
 }
 
-static int parse_mntopts(const char *mntopts, unsigned long *mntflags,
+int parse_mntopts(const char *mntopts, unsigned long *mntflags,
 			 char **mntdata)
 {
 	char *s, *data;
@@ -1865,11 +1890,6 @@ static inline int mount_entry_on_systemfs(const struct mntent *mntent)
 	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);
@@ -1890,6 +1910,11 @@ static inline int mount_entry_on_systemfs(const struct mntent *mntent)
 			fclose(pathfile);
 	}
 
+	if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -1;
+	}
+
 	ret = mount_entry(mntent->mnt_fsname, mntent->mnt_dir,
 			  mntent->mnt_type, mntflags, mntdata);
 
@@ -1915,11 +1940,6 @@ static int mount_entry_on_absolute_rootfs(const struct mntent *mntent,
 	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;
-	}
-
 	lxcpath = lxc_global_config_value("lxc.lxcpath");
 	if (!lxcpath) {
 		ERROR("Out of memory");
@@ -1976,15 +1996,21 @@ skipabs:
 			fclose(pathfile);
 	}
 
+	if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -1;
+	}
+
 	ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
 			  mntflags, mntdata);
 
+	free(mntdata);
+
 	if (hasmntopt(mntent, "optional") != NULL)
 		ret = 0;
 
 out:
 	free(pathdirname);
-	free(mntdata);
 	return ret;
 }
 
@@ -1998,11 +2024,6 @@ static int mount_entry_on_relative_rootfs(const struct mntent *mntent,
 	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 */
 	ret = snprintf(path, sizeof(path), "%s/%s", rootfs, mntent->mnt_dir);
 	if (ret >= sizeof(path)) {
@@ -2030,6 +2051,11 @@ static int mount_entry_on_relative_rootfs(const struct mntent *mntent,
 			fclose(pathfile);
 	}
 
+	if (parse_mntopts(mntent->mnt_opts, &mntflags, &mntdata) < 0) {
+		free(mntdata);
+		return -1;
+	}
+
 	ret = mount_entry(mntent->mnt_fsname, path, mntent->mnt_type,
 			  mntflags, mntdata);
 
@@ -3906,6 +3932,8 @@ void lxc_conf_free(struct lxc_conf *conf)
 		free(conf->console.path);
 	if (conf->rootfs.mount)
 		free(conf->rootfs.mount);
+	if (conf->rootfs.options)
+		free(conf->rootfs.options);
 	if (conf->rootfs.path)
 		free(conf->rootfs.path);
 	if (conf->rootfs.pivot)
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index cd4b115..e5a23ec 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -219,6 +219,7 @@ struct lxc_rootfs {
 	char *path;
 	char *mount;
 	char *pivot;
+	char *options;
 };
 
 /*
@@ -375,4 +376,6 @@ extern int mapped_hostid(int id, struct lxc_conf *conf);
 extern int chown_mapped_root(char *path, struct lxc_conf *conf);
 extern int ttys_shift_ids(struct lxc_conf *c);
 extern int userns_exec_1(struct lxc_conf *conf, int (*fn)(void *), void *data);
+extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
+			 char **mntdata);
 #endif
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 8a027cc..03a42c5 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -65,6 +65,7 @@ static int config_logfile(const char *, const char *, struct lxc_conf *);
 static int config_mount(const char *, const char *, struct lxc_conf *);
 static int config_rootfs(const char *, const char *, struct lxc_conf *);
 static int config_rootfs_mount(const char *, const char *, struct lxc_conf *);
+static int config_rootfs_options(const char *, const char *, struct lxc_conf *);
 static int config_pivotdir(const char *, const char *, struct lxc_conf *);
 static int config_utsname(const char *, const char *, struct lxc_conf *);
 static int config_hook(const char *, const char *, struct lxc_conf *lxc_conf);
@@ -110,6 +111,7 @@ static struct lxc_config_t config[] = {
 	{ "lxc.logfile",              config_logfile              },
 	{ "lxc.mount",                config_mount                },
 	{ "lxc.rootfs.mount",         config_rootfs_mount         },
+	{ "lxc.rootfs.options",       config_rootfs_options       },
 	{ "lxc.rootfs",               config_rootfs               },
 	{ "lxc.pivotdir",             config_pivotdir             },
 	{ "lxc.utsname",              config_utsname              },
@@ -1566,6 +1568,12 @@ static int config_rootfs_mount(const char *key, const char *value,
 	return config_path_item(&lxc_conf->rootfs.mount, value);
 }
 
+static int config_rootfs_options(const char *key, const char *value,
+			       struct lxc_conf *lxc_conf)
+{
+	return config_string_item(&lxc_conf->rootfs.options, value);
+}
+
 static int config_pivotdir(const char *key, const char *value,
 			   struct lxc_conf *lxc_conf)
 {
@@ -2096,6 +2104,8 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv,
 		v = c->console.path;
 	else if (strcmp(key, "lxc.rootfs.mount") == 0)
 		v = c->rootfs.mount;
+	else if (strcmp(key, "lxc.rootfs.options") == 0)
+		v = c->rootfs.options;
 	else if (strcmp(key, "lxc.rootfs") == 0)
 		v = c->rootfs.path;
 	else if (strcmp(key, "lxc.pivotdir") == 0)
@@ -2313,6 +2323,8 @@ void write_config(FILE *fout, struct lxc_conf *c)
 		fprintf(fout, "lxc.rootfs = %s\n", c->rootfs.path);
 	if (c->rootfs.mount && strcmp(c->rootfs.mount, LXCROOTFSMOUNT) != 0)
 		fprintf(fout, "lxc.rootfs.mount = %s\n", c->rootfs.mount);
+	if (c->rootfs.options)
+		fprintf(fout, "lxc.rootfs.options = %s\n", c->rootfs.options);
 	if (c->rootfs.pivot)
 		fprintf(fout, "lxc.pivotdir = %s\n", c->rootfs.pivot);
 	if (c->start_auto)
-- 
1.9.rc1



More information about the lxc-devel mailing list