[CRIU] [PATCH 2/3] file: add a general approach for external files

Pavel Emelyanov xemul at virtuozzo.com
Wed Feb 3 03:08:34 PST 2016


On 01/27/2016 08:58 PM, Andrew Vagin wrote:
> On Wed, Jan 27, 2016 at 04:40:44PM +0300, Pavel Emelyanov wrote:
>> On 01/21/2016 05:07 AM, Andrey Vagin wrote:
>>> From: Andrew Vagin <avagin at virtuozzo.com>
>>>
>>> The idea is to call open_cb for /proc/self/fd/X,
>>> where X is an externa file descriptor.
> 
> where X is an inherit file descriptor
> 
>>>
>>> This approach works for files and fifo.
>>
>> Plz, describe how this is supposed to be used and how this correlates
>> with the --inherit-fd one.
> 
> This patch is about inherit-fd.
> 
> The idea is that we use an inherit file descriptor to get a path to a
> file. We open /proc/self/fd/X instead of using the inherit file
> descriptor directly. In this case we don't need to worry about access
> mode flags, what is significant in a case when we have a few users for
> one file.

So you change the behavior of --inherit-fd option, don't you?

> I know that this method works for files and fifos. You can find a test
> in the third patch.
> 
> Thanks,
> Andrew
> 
>>
>>> Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
>>> ---
>>>  crtools.c   |  2 ++
>>>  files-reg.c | 29 +++++++++++++++++++++++++----
>>>  2 files changed, 27 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/crtools.c b/crtools.c
>>> index 039b7a0..fa27622 100644
>>> --- a/crtools.c
>>> +++ b/crtools.c
>>> @@ -781,6 +781,7 @@ usage:
>>>  "  --external RES        dump objects from this list as external resources:\n"
>>>  "                        Formats of RES:\n"
>>>  "                            tty[rdev:dev]\n"
>>> +"                            files[mnt_id:inode]\n"
>>>  "  --inherit-fd fd[<num>]:<existing>\n"
>>>  "                        Inherit file descriptors. This allows to treat file descriptor\n"
>>>  "                        <num> as being already opened via <existing> one and instead of\n"
>>> @@ -788,6 +789,7 @@ usage:
>>>  "                            tty[rdev:dev]\n"
>>>  "                            pipe[inode]\n"
>>>  "                            socket[inode]\n"
>>> +"                            files[mnt_id:inode]\n"
>>>  "\n"
>>>  "* Logging:\n"
>>>  "  -o|--log-file FILE    log file name\n"
>>> diff --git a/files-reg.c b/files-reg.c
>>> index ea66af0..ec74272 100644
>>> --- a/files-reg.c
>>> +++ b/files-reg.c
>>> @@ -1021,6 +1021,7 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
>>>  	struct fd_link _link, *link;
>>>  	struct ns_id *nsid;
>>>  	struct cr_img *rimg;
>>> +	char ext_id[64];
>>>  
>>>  	RegFileEntry rfe = REG_FILE_ENTRY__INIT;
>>>  
>>> @@ -1031,6 +1032,14 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
>>>  	} else
>>>  		link = p->link;
>>>  
>>> +
>>> +	snprintf(ext_id, sizeof(ext_id), "@file[%x:%"PRIx64"]", p->mnt_id, p->stat.st_ino);
>>> +	if (external_lookup_id(ext_id + 1)) {
>>> +		/* the first symbol will be cut on restore to get an relative path*/
>>> +		rfe.name = xstrdup(ext_id);
>>> +		goto ext;
>>> +	}
>>> +
>>>  	nsid = lookup_nsid_by_mnt_id(p->mnt_id);
>>>  	if (nsid == NULL) {
>>>  		pr_err("Can't lookup mount=%d for fd=%d path=%s\n",
>>> @@ -1056,12 +1065,12 @@ int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
>>>  
>>>  	if (check_path_remap(link, p, lfd, id, nsid))
>>>  		return -1;
>>> -
>>> +	rfe.name	= &link->name[1];
>>> +ext:
>>>  	rfe.id		= id;
>>>  	rfe.flags	= p->flags;
>>>  	rfe.pos		= p->pos;
>>>  	rfe.fown	= (FownEntry *)&p->fown;
>>> -	rfe.name	= &link->name[1];
>>>  
>>>  	if (S_ISREG(p->stat.st_mode) && should_check_size(rfe.flags)) {
>>>  		rfe.has_size = true;
>>> @@ -1216,11 +1225,22 @@ int open_path(struct file_desc *d,
>>>  	struct reg_file_info *rfi;
>>>  	int tmp, mntns_root;
>>>  	char *orig_path = NULL;
>>> +	char path[PATH_MAX];
>>>  
>>>  	if (inherited_fd(d, &tmp))
>>>  		return tmp;
>>>  
>>>  	rfi = container_of(d, struct reg_file_info, d);
>>> +
>>> +	tmp = inherit_fd_lookup_id(rfi->path);
>>> +	if (tmp >= 0) {
>>> +		mntns_root = open_pid_proc(PROC_SELF);
>>> +		snprintf(path, sizeof(path), "fd/%d", tmp);
>>> +		orig_path = rfi->path;
>>> +		rfi->path = path;
>>> +		goto ext;
>>> +	}
>>> +
>>>  	if (rfi->remap) {
>>>  		mutex_lock(ghost_file_mutex);
>>>  		if (rfi->remap->is_dir) {
>>> @@ -1262,6 +1282,7 @@ int open_path(struct file_desc *d,
>>>  	}
>>>  
>>>  	mntns_root = mntns_get_root_by_mnt_id(rfi->rfe->mnt_id);
>>> +ext:
>>>  	tmp = open_cb(mntns_root, rfi, arg);
>>>  	if (tmp < 0) {
>>>  		pr_perror("Can't open file %s", rfi->path);
>>> @@ -1303,10 +1324,10 @@ int open_path(struct file_desc *d,
>>>  			unlinkat(mntns_root, rfi->remap->rpath, rfi->remap->is_dir ? AT_REMOVEDIR : 0);
>>>  		}
>>>  
>>> -		if (orig_path)
>>> -			rfi->path = orig_path;
>>>  		mutex_unlock(ghost_file_mutex);
>>>  	}
>>> +	if (orig_path)
>>> +		rfi->path = orig_path;
>>>  
>>>  	if (restore_fown(tmp, rfi->rfe->fown))
>>>  		return -1;
>>>
>>
> .
> 



More information about the CRIU mailing list