[CRIU] [PATCH] Resolve file descriptor clashes with inherit fds

Andrew Vagin avagin at parallels.com
Wed Nov 26 23:49:20 PST 2014


On Tue, Nov 25, 2014 at 02:54:05PM -0800, Saied Kazemi wrote:
> Since with --inherit-fd option criu's caller can set any fd to be
> inheritied, there is a chance of fd clash during restore.  Resolve such
> cases by moving the inherit fd to a different descriptor.

I have another idea how we can do this functionality and avoid
current problems.

We can create a new type for inherit_fd-s with own file_desc_ops. All
processes opens a transport sockets for descripts, which should be
restored from inherit_fd-s. The criu process sends inherit_fd
descriptors.

In this case we don't need to enumirate all inherit_fd-s in
reopen_fd_as_safe(). We have source inherit_fd-s only in the criu
process. The overhead is near zero.

I'm going to prepare a draft today.

> 
> Signed-off-by: Saied Kazemi <saied at google.com>
> ---
>  files-reg.c     |  1 -
>  files.c         | 25 ++++++++++++++++++++++---
>  include/files.h |  3 ++-
>  util.c          |  3 +++
>  4 files changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/files-reg.c b/files-reg.c
> index bfd1896..2d2328c 100644
> --- a/files-reg.c
> +++ b/files-reg.c
> @@ -963,7 +963,6 @@ int open_path(struct file_desc *d,
>  
>  	mntns_root = mntns_get_root_by_mnt_id(rfi->rfe->mnt_id);
>  
> -pr_debug(">>> open_path(): rfi->path=(%s)\n", rfi->path);
>  	tmp = inherit_fd_lookup_id(rfi->path, true);
>  	if (tmp >= 0) {
>  		pr_info("File %s will be restored from fd %d\n", rfi->path, tmp);
> diff --git a/files.c b/files.c
> index 7bace3a..a074be5 100644
> --- a/files.c
> +++ b/files.c
> @@ -1346,16 +1346,35 @@ int inherit_fd_lookup_id(char *id, bool need_fd)
>  /*
>   * Look up the inherit fd list by a file descriptor.
>   */
> -bool inherit_fd_lookup_fd(int fd)
> +struct inherit_fd *inherit_fd_lookup_fd(int fd)
>  {
>  	struct inherit_fd *inh;
>  
>  	list_for_each_entry(inh, &opts.inherit_fds, l) {
>  		if (inh->inh_fd == fd) {
>  			pr_info("File descriptor %d in inherit fd list\n", fd);
> -			return true;
> +			return inh;
>  		}
>  	}
>  
> -	return false;
> +	return NULL;
> +}
> +
> +/*
> + * If the specified fd clashes with an inherit fd,
> + * move the inherit fd.
> + */
> +int inherit_fd_resolve_clash(int fd)
> +{
> +	struct inherit_fd *inh;
> +
> +	if ((inh = inherit_fd_lookup_fd(fd)) == NULL)
> +		return 0;
> +
> +	if ((inh->inh_fd = dup(fd)) == -1 || close(fd) == -1) {
> +		pr_perror("Can't resolve inherit fd clash on %d", fd);
> +		return -1;
> +	}
> +	pr_debug("Resolved clash on inherit fd %d -> %d\n", fd, inh->inh_fd);
> +	return 0;
>  }
> diff --git a/include/files.h b/include/files.h
> index e4e304f..aa0e502 100644
> --- a/include/files.h
> +++ b/include/files.h
> @@ -174,6 +174,7 @@ extern int inherit_fd_add(char *optarg);
>  extern void inherit_fd_log(void);
>  extern int inherit_fd_validate_fds(void);
>  extern int inherit_fd_lookup_id(char *id, bool need_fd);
> -extern bool inherit_fd_lookup_fd(int fd);
> +extern struct inherit_fd *inherit_fd_lookup_fd(int fd);
> +extern int inherit_fd_resolve_clash(int fd);
>  
>  #endif /* __CR_FILES_H__ */
> diff --git a/util.c b/util.c
> index 3b468f2..4d2ef17 100644
> --- a/util.c
> +++ b/util.c
> @@ -118,6 +118,9 @@ int reopen_fd_as_safe(char *file, int line, int new_fd, int old_fd, bool allow_r
>  	int tmp;
>  
>  	if (old_fd != new_fd) {
> +		/* make sure we won't clash with an inherit fd */
> +		if (inherit_fd_resolve_clash(new_fd) < 0)
> +			return -1;
>  
>  		if (!allow_reuse_fd) {
>  			if (fcntl(new_fd, F_GETFD) != -1 || errno != EBADF) {
> -- 
> 2.2.0.rc0.207.ga3a616c
> 


More information about the CRIU mailing list