[CRIU] [PATCH 2/4] unix: link a socket to its peer

Pavel Emelyanov xemul at parallels.com
Mon Dec 2 02:26:47 PST 2013


On 11/30/2013 09:43 PM, Andrey Vagin wrote:
> We are going to add callback-s for dumping external sockets.
> All external sockets are added into unix_list, but for dumping we need
> to know all peers.
> 
> And one more thing is that a socket is not closed before its peer is
> not be dumped. We are going to transfer the socket decriptor in the
> callback.
> 
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
>  sk-unix.c | 29 +++++++++++++++++++++++------
>  1 file changed, 23 insertions(+), 6 deletions(-)
> 
> diff --git a/sk-unix.c b/sk-unix.c
> index b6255ba..7e0bea7 100644
> --- a/sk-unix.c
> +++ b/sk-unix.c
> @@ -45,6 +45,10 @@ struct unix_sk_desc {
>  	gid_t			gid;
>  
>  	struct list_head	list;
> +
> +	int			fd;
> +	struct list_head	peer_list;
> +	struct list_head	peer_node;
>  };
>  
>  static LIST_HEAD(unix_sockets);
> @@ -121,7 +125,7 @@ static int can_dump_unix_sk(const struct unix_sk_desc *sk)
>  
>  static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
>  {
> -	struct unix_sk_desc *sk;
> +	struct unix_sk_desc *sk, *peer;
>  	UnixSkEntry ue = UNIX_SK_ENTRY__INIT;
>  	SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
>  	FilePermsEntry perms = FILE_PERMS_ENTRY__INIT;
> @@ -172,8 +176,6 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
>  	sk_encode_shutdown(&ue, sk->shutdown);
>  
>  	if (ue.peer) {
> -		struct unix_sk_desc *peer;
> -
>  		peer = (struct unix_sk_desc *)lookup_socket(ue.peer, PF_UNIX, 0);
>  		if (IS_ERR_OR_NULL(peer)) {
>  			pr_err("Unix socket %#x without peer %#x\n",
> @@ -197,9 +199,18 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
>  		 * It can be external socket, so we defer dumping
>  		 * until all sockets the program owns are processed.
>  		 */
> -		if (!peer->sd.already_dumped && list_empty(&peer->list)) {
> -			show_one_unix("Add a peer", peer);
> -			list_add_tail(&peer->list, &unix_sockets);
> +		if (!peer->sd.already_dumped) {
> +			if (list_empty(&peer->list)) {
> +				show_one_unix("Add a peer", peer);
> +				list_add_tail(&peer->list, &unix_sockets);
> +			}
> +
> +			list_add(&sk->peer_node, &peer->peer_list);
> +			sk->fd = dup(lfd);
> +			if (sk->fd < 0) {
> +				pr_perror("Unable to dup(%d)", lfd);
> +				goto err;
> +			}
>  		}
>  
>  		if ((ue.type != SOCK_DGRAM) && (
> @@ -284,6 +295,9 @@ dump:
>  	list_del_init(&sk->list);
>  	sk->sd.already_dumped = 1;
>  
> +	list_for_each_entry(peer, &sk->peer_list, peer_node)

Remove from list?

> +		close_safe(&peer->fd);
> +
>  	return 0;
>  
>  err:
> @@ -311,6 +325,9 @@ static int unix_collect_one(const struct unix_diag_msg *m,
>  	d->state = m->udiag_state;
>  	INIT_LIST_HEAD(&d->list);
>  
> +	INIT_LIST_HEAD(&d->peer_list);
> +	d->fd = -1;
> +
>  	if (tb[UNIX_DIAG_SHUTDOWN])
>  		d->shutdown = *(u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]);
>  	else
> 




More information about the CRIU mailing list