[Devel] [PATCH rhel6 2/3] cpt: dump dentry alias path for UNIX socket

Vasily Averin vvs at virtuozzo.com
Mon Sep 28 08:57:31 PDT 2015


Stas,
please see my comment below.

On 28.09.2015 16:16, Stanislav Kinsburskiy wrote:
> From: Stanislav Kinsburskiy <skinsbursky at parallels.com>
> 
> There could be a unix socket (thanks to supervisord), which was unlinked, but
> also a hardlink to it was created prior to unlink.
> This basically means, that unlinked socket and it's hardlink points to the
> same inode.
> In such a case we can't just recreate unlinked socket in /tmp directory, like
> we did before. Becuase it this case connect to linked dentry will fail becuase
> of different inode.
> We have to try to find another dentry, poiting to this inode and dump it's
> path, which will be used to recreate unlinked socket on restore.
> We need also to dump dentry mount, so we can lookup it on restore. BTW, in
> this case socket will be restored via unix_bind_to_mntref() instead of
> unix_bind_to_path().
> 
> Signed-off-by: Stanislav Kinsburskiy <skinsbursky at parallels.com>
> ---
>  include/linux/cpt_image.h |    5 ++++
>  kernel/cpt/cpt_socket.c   |   52 +++++++++++++++++++++++++++++++--------------
>  2 files changed, 41 insertions(+), 16 deletions(-)
> 
> diff --git a/include/linux/cpt_image.h b/include/linux/cpt_image.h
> index 30a625d..75fa878 100644
> --- a/include/linux/cpt_image.h
> +++ b/include/linux/cpt_image.h
> @@ -963,6 +963,11 @@ struct cpt_sock_image
>  
>  	__u32	cpt_i_uid;
>  	__u32	cpt_i_gid;
> +
> +	__u32	cpt_d_alias[128/4];
> +
> +	__u32	cpt_d_aliaslen;
> +	__u32	__cpt_pad15;
>  } __attribute__ ((aligned (8)));

size of this structure increases ==> CPT image version should be increased ==> it's impossible to migrate from new kernels to old ones.
Am I missed something?

>  struct cpt_sockmc_image {
> diff --git a/kernel/cpt/cpt_socket.c b/kernel/cpt/cpt_socket.c
> index 863aefe..88b4bd7 100644
> --- a/kernel/cpt/cpt_socket.c
> +++ b/kernel/cpt/cpt_socket.c
> @@ -543,28 +543,47 @@ static int cpt_dump_unix_socket(struct sock *sk, struct cpt_sock_image *v, cpt_c
>  
>  	if (unix_sk(sk)->dentry) {
>  		struct dentry *d = unix_sk(sk)->dentry;
> +		unsigned long pg = __get_free_page(GFP_KERNEL);
> +		struct path p;
> +		char *path, *cpt_path;
> +		int err = 0;
> +		__u32 *path_len;
> +
> +		if (!pg)
> +			return -ENOMEM;
> +
>  		v->cpt_i_uid = d->d_inode->i_uid;
>  		v->cpt_i_gid = d->d_inode->i_gid;
>  
>  		if (IS_ROOT(d) || !d_unhashed(d)) {
> -			int err = 0;
> -			struct path p = {unix_sk(sk)->mnt, d};
> -			char *path;
> -			unsigned long pg = __get_free_page(GFP_KERNEL);
> +			p.dentry = dget(d);
> +			cpt_path = ((char*)v->cpt_laddr) + 2;
> +			path_len = &v->cpt_laddrlen;
> +		} else {
> +			v->cpt_sockflags |= CPT_SOCK_DELETED;
> +			v->cpt_d_aliaslen = 0;
> +			p.dentry = NULL;
>  
> -			if (!pg)
> -				return -ENOMEM;
> +			if (d->d_inode->i_nlink != 0) {
> +				p.dentry = get_linked_dentry(d, unix_sk(sk)->mnt, ctx);
> +				cpt_path = (char *)v->cpt_d_alias;
> +				path_len = &v->cpt_d_aliaslen;
> +			}
> +		}
> +
> +		if (!IS_ERR_OR_NULL(p.dentry)) {
> +			p.mnt = unix_sk(sk)->mnt;
>  
>  			path = d_path(&p, (char *)pg, PAGE_SIZE);
>  
>  			if (!IS_ERR(path)) {
>  				int len = strlen(path);
>  				if (len < 126) {
> -					strcpy(((char*)v->cpt_laddr)+2, path); 
> -					v->cpt_laddrlen = len + 2;
> -				} else {
> -					wprintk_ctx("af_unix path is too long: %s (%s)\n", path, ((char*)v->cpt_laddr)+2);
> -				}
> +					strcpy(cpt_path, path);
> +					*path_len = len + 2;
> +				} else
> +					wprintk_ctx("af_unix path is too long: %s (%s)\n", path, cpt_path);
> +
>  				if (cpt_need_delayfs(unix_sk(sk)->mnt))
>  					v->cpt_sockflags |= CPT_SOCK_DELAYED;
>  
> @@ -575,11 +594,12 @@ static int cpt_dump_unix_socket(struct sock *sk, struct cpt_sock_image *v, cpt_c
>  				eprintk_ctx("cannot get path of an af_unix socket\n");
>  				err = PTR_ERR(path);
>  			}
> -			free_page(pg);
> -			if (err)
> -				return err;
> -		} else
> -			v->cpt_sockflags |= CPT_SOCK_DELETED;
> +			dput(p.dentry);
> +		}
> +
> +		free_page(pg);
> +		if (err)
> +			return err;
>  	}
>  
>  	/* If the socket is connected, find its peer. If peer is not
> 
> _______________________________________________
> Devel mailing list
> Devel at openvz.org
> https://lists.openvz.org/mailman/listinfo/devel
> 



More information about the Devel mailing list