[CRIU] [PATCH 2/7] files: Add fill_fdlink helper

Pavel Emelyanov xemul at parallels.com
Thu May 9 13:51:51 EDT 2013


On 05/08/2013 05:00 PM, Cyrill Gorcunov wrote:
> When we dump a regular file it might be a link
> to opened proc/ns entry so we need to read link
> first and then analyze it. But to make it in step
> byt step way we at first use fill_fdlink helper
> which fills the link contents for us and modify
> dump_one_reg_file to escape double link reading.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  files-reg.c | 22 +++++++++++++++++-----
>  files.c     | 31 ++++++++++++++++++++++++++++++-
>  2 files changed, 47 insertions(+), 6 deletions(-)
> 
> diff --git a/files-reg.c b/files-reg.c
> index 684cfd3..1e441a8 100644
> --- a/files-reg.c
> +++ b/files-reg.c
> @@ -432,15 +432,27 @@ static int check_path_remap(char *rpath, int plen, const struct stat *ost, int l
>  
>  int dump_one_reg_file(int lfd, u32 id, const struct fd_parms *p)
>  {
> -	char rpath[PATH_MAX + 1] = ".", *path = rpath + 1;
> +	char buf[PATH_MAX + 1];
> +	char *rpath, *path;
>  	int len, rfd;
>  
>  	RegFileEntry rfe = REG_FILE_ENTRY__INIT;
>  
> -	len = read_fd_link(lfd, path, sizeof(rpath) - 1);
> -	if (len < 0) {
> -		pr_err("Can't read link\n");
> -		return len;
> +	if (!p->nmlink) {
> +		path = buf + 1;
> +		rpath = buf;
> +
> +		len = read_fd_link(lfd, path, sizeof(buf) - 1);
> +		if (len < 0) {
> +			pr_err("Can't read link\n");
> +			return len;
> +		}
> +
> +		rpath[0] = '.';
> +	} else {
> +		path = p->nmlink + 1;
> +		rpath = p->nmlink;
> +		len = p->nmlen;
>  	}
>  
>  	pr_info("Dumping path for %d fd via self %d [%s]\n",
> diff --git a/files.c b/files.c
> index 786eca7..edaaa0e 100644
> --- a/files.c
> +++ b/files.c
> @@ -135,6 +135,24 @@ int do_dump_gen_file(struct fd_parms *p, int lfd,
>  	return pb_write_one(fdinfo, &e, PB_FDINFO);
>  }
>  
> +static int fill_fdlink(int lfd, struct fd_parms *p)
> +{
> +	char *path = &p->nmlink[1];
> +	size_t len;
> +
> +	BUG_ON(!p->nmlink || p->nmsize < 1);
> +	p->nmlink[0] = '.';
> +
> +	len = read_fd_link(lfd, path, p->nmsize - 1);
> +	if (len < 0) {
> +		pr_err("Can't read link for pid %d fd %d\n", p->pid, p->fd);
> +		return -1;
> +	}
> +
> +	p->nmlen = len + 1;
> +	return 0;
> +}
> +
>  static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd,
>  				struct fd_opts *opts, struct fd_parms *p)
>  {
> @@ -244,8 +262,19 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op
>  			return dump_unsupp_fd(&p);
>  	}
>  
> -	if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode))
> +	if (S_ISREG(p.stat.st_mode) || S_ISDIR(p.stat.st_mode)) {
> +		char path[PATH_MAX + 1];
> +
> +		p.nmlink = path;
> +		p.nmsize = sizeof(path);
> +
> +		if (fill_fdlink(lfd, &p)) {
> +			pr_err("Can't fill fdlink params\n");
> +			return -1;
> +		}
> +
>  		return dump_reg_file(&p, lfd, fdinfo);

dump_reg_file will end up calling dump_one_reg_file, which in turn, will
call read_fd_link, so why calling one here via a wrapper?

> +	}
>  
>  	if (S_ISFIFO(p.stat.st_mode)) {
>  		if (statfs.f_type == PIPEFS_MAGIC)
> 




More information about the CRIU mailing list