[CRIU] [PATCH] mount: save relative path in mi->mountpoint

Pavel Emelyanov xemul at parallels.com
Wed Apr 16 04:52:37 PDT 2014


On 04/16/2014 02:48 PM, Andrey Vagin wrote:
> "relative path" is absolute path with dot at the beginning.
> 
> We already use relative paths on restore. In this patch we add "."
> on dump too. It's convinient, because we needed to add dot each time
> when we want to access this mount point.
> Before this patch we had to created a temporary copy.
> 
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
>  include/proc_parse.h |  5 +++++
>  mount.c              | 21 ++++++++++-----------
>  proc_parse.c         | 15 ++++++++++++---
>  3 files changed, 27 insertions(+), 14 deletions(-)
> 
> diff --git a/include/proc_parse.h b/include/proc_parse.h
> index aba4357..651c6a0 100644
> --- a/include/proc_parse.h
> +++ b/include/proc_parse.h
> @@ -104,6 +104,11 @@ struct mount_info {
>  	int		parent_mnt_id;
>  	unsigned int	s_dev;
>  	char		*root;
> +	/*
> +	 * mountpoint contains path with dot at the beginning.
> +	 * It allows to use openat, statat, etc without creating
> +	 * a temporary copy.
> +	 */
>  	char		*mountpoint;
>  	unsigned	flags;
>  	int		master_id;
> diff --git a/mount.c b/mount.c
> index 83fce33..8fb050c 100644
> --- a/mount.c
> +++ b/mount.c
> @@ -48,13 +48,13 @@ static int validate_mounts(struct mount_info *info, bool call_plugins);
>  /* Asolute paths are used on dump and relative paths are used on restore */
>  static inline int is_root(char *p)
>  {
> -	return (!strcmp(p, "/") || !strcmp(p, "./"));
> +	return (!strcmp(p, "/"));
>  }
>  
>  /* True for the root mount (the topmost one) */
>  static inline int is_root_mount(struct mount_info *mi)
>  {
> -	return is_root(mi->mountpoint);
> +	return is_root(mi->mountpoint + 1);

The fsroot_mounted() should be patched the same way too, shouldn't it?

>  }
>  
>  /*
> @@ -155,11 +155,11 @@ static struct mount_info *mount_resolve_path(const char *path)
>  		list_for_each_entry(c, &m->children, siblings) {
>  			size_t n;
>  
> -			n = strlen(c->mountpoint);
> +			n = strlen(c->mountpoint + 1);
>  			if (n > pathlen)
>  				continue;
>  
> -			if (strncmp(c->mountpoint, path, min(n, pathlen)))
> +			if (strncmp(c->mountpoint + 1, path, min(n, pathlen)))
>  				continue;
>  			if (n < pathlen && path[n] != '/')
>  				continue;
> @@ -354,7 +354,7 @@ static int validate_mounts(struct mount_info *info, bool call_plugins)
>  				int ret;
>  
>  				if (call_plugins) {
> -					ret = cr_plugin_dump_ext_mount(m->mountpoint, m->mnt_id);
> +					ret = cr_plugin_dump_ext_mount(m->mountpoint + 1, m->mnt_id);
>  					if (ret == 0)
>  						m->need_plugin = true;
>  				} else if (m->need_plugin)
> @@ -480,7 +480,6 @@ static struct mount_info *mnt_build_tree(struct mount_info *list)
>   */
>  static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
>  {
> -	char path[PATH_MAX + 1];
>  	struct stat st;
>  	DIR *fdir;
>  	int ret;
> @@ -490,8 +489,8 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
>  
>  		mntns_root = get_service_fd(ROOT_FD_OFF);
>  
> -		snprintf(path, sizeof(path), ".%s", pm->mountpoint);
> -		mnt_fd = openat(mntns_root, path, O_RDONLY);
> +		/* paths starts from "." on restore and "/" on dump */

Huh? Obsoleted comment?

> +		mnt_fd = openat(mntns_root, pm->mountpoint, O_RDONLY);
>  		if (mnt_fd < 0) {
>  			pr_perror("Can't open %s", pm->mountpoint);
>  			return NULL;
> @@ -500,7 +499,7 @@ static DIR *__open_mountpoint(struct mount_info *pm, int mnt_fd)
>  
>  	ret = fstat(mnt_fd, &st);
>  	if (ret < 0) {
> -		pr_perror("fstat(%s) failed", path);
> +		pr_perror("fstat(%s) failed", pm->mountpoint);
>  		goto err;
>  	}
>  
> @@ -817,7 +816,7 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd)
>  	me.parent_mnt_id	= pm->parent_mnt_id;
>  	me.flags		= pm->flags;
>  	me.root			= pm->root;
> -	me.mountpoint		= pm->mountpoint;
> +	me.mountpoint		= pm->mountpoint + 1;
>  	me.source		= pm->source;
>  	me.options		= pm->options;
>  	me.shared_id		= pm->shared_id;
> @@ -1519,7 +1518,7 @@ int prepare_mnt_ns(int ns_pid)
>  			return -1;
>  		}
>  
> -		if (mount("none", mi->parent->mountpoint, "none", MS_SLAVE, NULL)) {
> +		if (mount("none", mi->parent->mountpoint + 1, "none", MS_SLAVE, NULL)) {

How about do_new_mount() and others?

>  			pr_perror("Can't remount the parent of the new root with MS_SLAVE");
>  			return -1;
>  		}
> diff --git a/proc_parse.c b/proc_parse.c
> index b90a79d..df1153c 100644
> --- a/proc_parse.c
> +++ b/proc_parse.c
> @@ -857,12 +857,21 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new)
>  	char *opt;
>  	char *fstype;
>  
> -	ret = sscanf(str, "%i %i %u:%u %ms %ms %ms %n",
> +	new->mountpoint = xmalloc(PATH_MAX);
> +	if (new->mountpoint == NULL)
> +		return -1;
> +
> +	new->mountpoint[0] = '.';
> +	ret = sscanf(str, "%i %i %u:%u %ms %s %ms %n",
>  			&new->mnt_id, &new->parent_mnt_id,
> -			&kmaj, &kmin, &new->root, &new->mountpoint,
> +			&kmaj, &kmin, &new->root, new->mountpoint + 1,
>  			&opt, &n);
> -	if (ret != 7)
> +	if (ret != 7) {
> +		xfree(new->mountpoint);
>  		return -1;
> +	}
> +
> +	new->mountpoint = xrealloc(new->mountpoint, strlen(new->mountpoint) + 1);
>  
>  	new->s_dev = MKKDEV(kmaj, kmin);
>  	new->flags = 0;
> 




More information about the CRIU mailing list