[CRIU] [PATCH 08/11] link-remap: open link-remap files from correct mountpoints

Pavel Emelyanov xemul at parallels.com
Tue Aug 5 09:53:58 PDT 2014


On 08/05/2014 04:57 PM, Andrew Vagin wrote:
> On Tue, Aug 05, 2014 at 04:39:26PM +0400, Pavel Emelyanov wrote:
>> On 08/03/2014 10:31 PM, Andrey Vagin wrote:
>>> Here is a problem with ghost files. Links are created on restore, but
>>> they can't be created on any mount point, because a mount point can be
>>> non-root bind-mount of another one. So we need to find the root mount
>>> and create all links there.
>>>
>>> v2: clean up
>>> Signed-off-by: Andrey Vagin <avagin at openvz.org>
>>> ---
>>>  files-reg.c         | 62 ++++++++++++++++++++++++++++++++++++++++++++++-------
>>>  include/files-reg.h |  1 +
>>>  2 files changed, 55 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/files-reg.c b/files-reg.c
>>> index 00eef60..b72c821 100644
>>> --- a/files-reg.c
>>> +++ b/files-reg.c
>>> @@ -154,6 +154,7 @@ static int open_remap_ghost(struct reg_file_info *rfi,
>>>  	if (!gf)
>>>  		return -1;
>>>  	gf->remap.path = xmalloc(PATH_MAX);
>>> +	gf->remap.mnt_id = rfi->rfe->mnt_id;
>>>  	if (!gf->remap.path)
>>>  		goto err;
>>>  
>>> @@ -221,6 +222,7 @@ static int open_remap_linked(struct reg_file_info *rfi,
>>>  	rm->path = rrfi->path;
>>>  	rm->users = 0;
>>>  	rm->is_dir = false;
>>> +	rm->mnt_id = rfi->rfe->mnt_id;
>>>  	rfi->remap = rm;
>>>  	return 0;
>>>  }
>>> @@ -313,8 +315,12 @@ void remap_put(struct file_remap *remap)
>>>  {
>>>  	mutex_lock(ghost_file_mutex);
>>>  	if (--remap->users == 0) {
>>> +		int mntns_root;
>>> +
>>>  		pr_info("Unlink the ghost %s\n", remap->path);
>>> -		unlink(remap->path);
>>> +
>>> +		mntns_root = mntns_get_root_by_mnt_id(remap->mnt_id);
>>> +		unlinkat(mntns_root, remap->path, 0);
>>>  	}
>>>  	mutex_unlock(ghost_file_mutex);
>>>  }
>>> @@ -669,7 +675,48 @@ const struct fdtype_ops regfile_dump_ops = {
>>>  
>>>  static inline int rfi_remap(struct reg_file_info *rfi)
>>>  {
>>> -	return link(rfi->remap->path, rfi->path);
>>> +	struct mount_info *mi, *rmi, *tmi;
>>> +	int off, roff;
>>> +	char path[PATH_MAX], rpath[PATH_MAX];
>>> +	int mntns_root;
>>> +
>>> +	mi = lookup_mnt_id(rfi->rfe->mnt_id);
>>> +
>>> +	if (mi == NULL) {
>>> +		mntns_root = mntns_get_root_by_mnt_id(-1);
>>> +		return linkat(mntns_root, rfi->remap->path, mntns_root, rfi->path, 0);
>>> +	}
>>> +
>>> +	/*
>>> +	 * mi->mountpoint	./zdtm/live/static/mntns_link_ghost.test/1
>>> +	 * + mi->rst_off	/zdtm/live/static/mntns_link_ghost.test/1
>>> +	 * rfi->path		zdtm/live/static/mntns_link_ghost.test/1/F (deleted)
>>> +	 */
>>> +	rmi = lookup_mnt_id(rfi->remap->mnt_id);
>>> +	off = strlen(mi->mountpoint + mi->rst_off + 1);
>>> +	roff = strlen(rmi->mountpoint + rmi->rst_off + 1);
>>> +
>>> +	/* Find the lowest common bind-mount */
>>> +	for (tmi = mi; tmi->bind; tmi = tmi->bind);
>>> +
>>> +	/* Create paths relative to this mount.
>>> +	 * Absolute path to the mount point + difference between source
>>> +	 * and destination roots + path relative to the mountpoint.
>>> +	 */
> 
> ^^^^ it's explained here
>>> +	snprintf(path, sizeof(path), "%s/%s/%s",
>>> +				tmi->mountpoint + tmi->rst_off + 1,
> Absolute path to the mount point
>>> +				mi->root + strlen(tmi->root),
> difference between source and destination roots
>>> +				rfi->path + off);
> path relative to the mountpoint

The origin file name and link name differs in the last component only.
Why changing link(name, link_name) into linkat(mnt_fd, name + off, mnt_fd, link_name + off)
where off properly cuts the basename, doesn't work?

>>> +	snprintf(rpath, sizeof(rpath), "%s/%s/%s",
>>> +				tmi->mountpoint + tmi->rst_off + 1,
>>> +				rmi->root + strlen(tmi->root),
>>> +				rfi->remap->path + roff);
>>
>> What the above path-tossing mean? Would you explain, please.
>>
>>> +
>>> +	pr_debug("%d: Link %s -> %s\n", tmi->mnt_id, path, rpath);
>>> +
>>> +	mntns_root = mntns_get_root_by_mnt_id(tmi->mnt_id);
>>> +
>>> +	return linkat(mntns_root, rpath, mntns_root, path, 0);
>>>  }
>>>  
>>>  int open_path(struct file_desc *d,
>>> @@ -752,16 +799,15 @@ int open_path(struct file_desc *d,
>>>  	}
>>>  
>>>  	if (rfi->remap) {
>>> -		if (!rfi->remap->is_dir)
>>> -			unlink(rfi->path);
>>> +		if (!rfi->remap->is_dir) {
>>> +			unlinkat(mntns_root, rfi->path, 0);
>>> +		}
>>>  
>>>  		BUG_ON(!rfi->remap->users);
>>>  		if (--rfi->remap->users == 0) {
>>>  			pr_info("Unlink the ghost %s\n", rfi->remap->path);
>>> -			if (rfi->remap->is_dir)
>>> -				rmdir(rfi->remap->path);
>>> -			else
>>> -				unlink(rfi->remap->path);
>>> +			mntns_root = mntns_get_root_by_mnt_id(rfi->remap->mnt_id);
>>> +			unlinkat(mntns_root, rfi->remap->path, rfi->remap->is_dir ? AT_REMOVEDIR : 0);
>>>  		}
>>>  
>>>  		if (orig_path)
>>> diff --git a/include/files-reg.h b/include/files-reg.h
>>> index b4a7367..bc5f5a7 100644
>>> --- a/include/files-reg.h
>>> +++ b/include/files-reg.h
>>> @@ -14,6 +14,7 @@ struct fd_parms;
>>>  struct file_remap {
>>>  	char *path;
>>>  	bool is_dir;
>>> +	int  mnt_id;
>>>  	unsigned int users;
>>>  };
>>>  
>>>
>>
> .
> 



More information about the CRIU mailing list