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

Serge Hallyn serge.hallyn at ubuntu.com
Fri Jan 31 11:45:18 UTC 2014


Quoting Stéphane Graber (stgraber at ubuntu.com):
> Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>

(Ideally there would be a changelog since V1 :)

Minus the off by one length calculation as discussed, looks good,
thank you.

Acked-by: Serge E. Hallyn <serge.hallyn 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
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel


More information about the lxc-devel mailing list