[lxc-devel] [PATCH 1/1] mount_entry: use statvfs

Stéphane Graber stgraber at ubuntu.com
Fri Aug 22 19:04:45 UTC 2014


On Wed, Aug 20, 2014 at 10:51:43PM +0000, Serge Hallyn wrote:
> Use statvfs instead of parsing /proc/self/mountinfo to check for the
> flags we need to and into the msbind mount flags.  This will be faster
> and the code is cleaner.
> 
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

Acked-by: Stéphane Graber <stgraber at ubuntu.com>

> ---
>  src/lxc/conf.c | 82 +++++++++++++++++++++-------------------------------------
>  1 file changed, 30 insertions(+), 52 deletions(-)
> 
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index 037be1d..f75f5ca 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -36,6 +36,7 @@
>  #include <pwd.h>
>  #include <grp.h>
>  #include <time.h>
> +#include <sys/statvfs.h>
>  
>  #if HAVE_PTY_H
>  #include <pty.h>
> @@ -1952,49 +1953,12 @@ static char *get_field(char *src, int nfields)
>  	return p;
>  }
>  
> -static unsigned long get_mount_flags(const char *path)
> -{
> -	FILE *f = fopen("/proc/self/mountinfo", "r");
> -	char *line = NULL;
> -	size_t len = 0;
> -	unsigned long flags = 0;
> -
> -	if (!f) {
> -		WARN("Failed to open /proc/self/mountinfo");
> -		return 0;
> -	}
> -	while (getline(&line, &len, f) != -1) {
> -		char *target, *opts, *p, *saveptr = NULL;
> -		target = get_field(line, 4);
> -		if (!target)
> -			continue;
> -		opts = get_field(target, 2);
> -		if (!opts)
> -			continue;
> -		null_endofword(opts);
> -		for (p = strtok_r(opts, ",", &saveptr); p;
> -			p = strtok_r(NULL, ",", &saveptr)) {
> -			if (strcmp(p, "ro") == 0)
> -				flags |= MS_RDONLY;
> -			else if (strcmp(p, "nodev") == 0)
> -				flags |= MS_NODEV;
> -			else if (strcmp(p, "nosuid") == 0)
> -				flags |= MS_NOSUID;
> -			else if (strcmp(p, "noexec") == 0)
> -				flags |= MS_NOEXEC;
> -			/* XXX todo - we'll have to deal with atime? */
> -		}
> -	}
> -	free(line);
> -	fclose(f);
> -	return flags;
> -}
> -
>  static int mount_entry(const char *fsname, const char *target,
>  		       const char *fstype, unsigned long mountflags,
>  		       const char *data, int optional)
>  {
> -	unsigned long extraflags;
> +	struct statvfs sb;
> +
>  	if (mount(fsname, target, fstype, mountflags & ~MS_REMOUNT, data)) {
>  		if (optional) {
>  			INFO("failed to mount '%s' on '%s' (optional): %s", fsname,
> @@ -2008,20 +1972,34 @@ static int mount_entry(const char *fsname, const char *target,
>  	}
>  
>  	if ((mountflags & MS_REMOUNT) || (mountflags & MS_BIND)) {
> -		extraflags = get_mount_flags(target);
> -		DEBUG("flags was %lu, extraflags set to %lu", mountflags, extraflags);
> -		if (!(mountflags & MS_REMOUNT) && (mountflags & MS_BIND)) {
> -			if (!(extraflags & ~mountflags))
> -				DEBUG("all mount flags match, skipping remount");
> -				goto skipremount;
> +		DEBUG("remounting %s on %s to respect bind or remount options",
> +		      fsname ? fsname : "(none)", target ? target : "(none)");
> +
> +		if (statvfs(fsname, &sb) == 0) {
> +			unsigned long required_flags = 0;
> +			if (sb.f_flag & MS_NOSUID)
> +				required_flags |= MS_NOSUID;
> +			if (sb.f_flag & MS_NODEV)
> +				required_flags |= MS_NODEV;
> +			if (sb.f_flag & MS_RDONLY)
> +				required_flags |= MS_RDONLY;
> +			if (sb.f_flag & MS_NOEXEC)
> +				required_flags |= MS_NOEXEC;
> +			DEBUG("(at remount) flags for %s was %lu, required extra flags are %lu", fsname, sb.f_flag, required_flags);
> +			/*
> +			 * If this was a bind mount request, and required_flags
> +			 * does not have any flags which are not already in
> +			 * mountflags, then skip the remount
> +			 */
> +			if (!(mountflags & MS_REMOUNT)) {
> +				if (!(required_flags & ~mountflags)) {
> +					DEBUG("mountflags already was %lu, skipping remount",
> +						mountflags);
> +					goto skipremount;
> +				}
> +			}
> +			mountflags |= required_flags;
>  		}
> -		mountflags |= extraflags;
> -	}
> -
> -	if ((mountflags & MS_REMOUNT) || (mountflags & MS_BIND)) {
> -		DEBUG("remounting %s on %s to respect bind or remount options %lu (extra %lu)",
> -		      fsname ? fsname : "(none)",
> -		      target ? target : "(none)", mountflags, extraflags);
>  
>  		if (mount(fsname, target, fstype,
>  			  mountflags | MS_REMOUNT, data)) {
> -- 
> 2.1.0.rc1
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140822/08f7fef7/attachment.sig>


More information about the lxc-devel mailing list