[CRIU] [PATCH RFC 05/30] files: Send/receive fds with pointers on their struct fdinfo_list_entry in receiver

Andrei Vagin avagin at virtuozzo.com
Wed Nov 2 07:16:49 PDT 2016


On Wed, Nov 02, 2016 at 01:51:59PM +0300, Kirill Tkhai wrote:
> On 02.11.2016 08:18, Andrei Vagin wrote:
> > On Tue, Nov 01, 2016 at 05:31:09PM +0300, Kirill Tkhai wrote:
> >> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> >> ---
> >>  criu/files.c         |   21 +++++++++++++++++++--
> >>  criu/include/files.h |    1 +
> >>  criu/pipes.c         |    2 +-
> >>  criu/sk-unix.c       |    2 +-
> >>  criu/tty.c           |    2 +-
> >>  5 files changed, 23 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/criu/files.c b/criu/files.c
> >> index 97b4e95..348f2c7 100644
> >> --- a/criu/files.c
> >> +++ b/criu/files.c
> >> @@ -957,6 +957,23 @@ static int open_transport_fd(int pid, struct fdinfo_list_entry *fle)
> >>  	return -1;
> >>  }
> >>  
> >> +int recv_fd_from_peer(struct fdinfo_list_entry *fle)
> >> +{
> >> +	struct fdinfo_list_entry *tmp;
> >> +	int fd, ret;
> >> +
> >> +	ret = recv_fds(fle->fe->fd, &fd, 1, NULL, (unsigned long *)&tmp);
> >> +	if (ret)
> >> +		return -1;
> >> +
> >> +	if (tmp != fle) {
> >> +		pr_err("Received wrong fle\n");
> > 
> > How do you guarantee the order of receiving file descriptors?
> > Descriptors are sent from different processes, how do you synchronize
> > them?
> 
> The thing is this patch does not change logic. It even does not break tests.
> We still have receive stage, and the patch is a preparation to a moment
> when order is changed.
> 
> Order processing is in other patch: "[09/30] files: Allow to receive further fds".
> It prepares recv_fd_from_peer() to make a deal with multiply received fles. But even there
> it's unused, it's a preparation.
> 
> Real use of single transport_fd for sending and receiving is in "[10/30] files: Make sending fds to peers async".
> Per-fd transport fds are killed there.

Yesterday I applied all patches and understood the idea. I think it
should work.

Thank you for the explanation.

> 
> >> +		return -1;
> >> +	}
> >> +
> >> +	return fd;
> >> +}
> >> +
> >>  int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle, int sock)
> >>  {
> >>  	struct sockaddr_un saddr;
> >> @@ -968,7 +985,7 @@ int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle, int sock)
> >>  	transport_name_gen(&saddr, &len,
> >>  			futex_get(&fle->real_pid), fle->fe->fd);
> >>  	pr_info("\t\tSend fd %d to %s\n", fd, saddr.sun_path + 1);
> >> -	return send_fd(sock, &saddr, len, fd);
> >> +	return send_fds(sock, &saddr, len, &fd, 1, false, (unsigned long *)&fle);
> >>  }
> >>  
> >>  static int send_fd_to_self(int fd, struct fdinfo_list_entry *fle, int sock)
> >> @@ -1078,7 +1095,7 @@ static int receive_fd(int pid, struct fdinfo_list_entry *fle)
> >>  
> >>  	pr_info("\tReceive fd for %d\n", fle->fe->fd);
> >>  
> >> -	tmp = recv_fd(fle->fe->fd);
> >> +	tmp = recv_fd_from_peer(fle);
> >>  	if (tmp < 0) {
> >>  		pr_err("Can't get fd %d\n", tmp);
> >>  		return -1;
> >> diff --git a/criu/include/files.h b/criu/include/files.h
> >> index 2cd1a67..457cc46 100644
> >> --- a/criu/include/files.h
> >> +++ b/criu/include/files.h
> >> @@ -148,6 +148,7 @@ extern int file_desc_add(struct file_desc *d, u32 id, struct file_desc_ops *ops)
> >>  extern struct fdinfo_list_entry *file_master(struct file_desc *d);
> >>  extern struct file_desc *find_file_desc_raw(int type, u32 id);
> >>  
> >> +extern int recv_fd_from_peer(struct fdinfo_list_entry *fle);
> >>  extern int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle, int sock);
> >>  extern int restore_fown(int fd, FownEntry *fown);
> >>  extern int rst_file_params(int fd, FownEntry *fown, int flags);
> >> diff --git a/criu/pipes.c b/criu/pipes.c
> >> index 9fc87bd..31f436e 100644
> >> --- a/criu/pipes.c
> >> +++ b/criu/pipes.c
> >> @@ -237,7 +237,7 @@ static int recv_pipe_fd(struct pipe_info *pi)
> >>  
> >>  	pr_info("\tWaiting fd for %d\n", fd);
> >>  
> >> -	tmp = recv_fd(fd);
> >> +	tmp = recv_fd_from_peer(fle);
> >>  	if (tmp < 0) {
> >>  		pr_err("Can't get fd %d\n", tmp);
> >>  		return -1;
> >> diff --git a/criu/sk-unix.c b/criu/sk-unix.c
> >> index 6a1a532..7d9728a 100644
> >> --- a/criu/sk-unix.c
> >> +++ b/criu/sk-unix.c
> >> @@ -1096,7 +1096,7 @@ static int open_unixsk_pair_slave(struct unix_sk_info *ui)
> >>  	pr_info("Opening pair slave (id %#x ino %#x peer %#x) on %d\n",
> >>  			ui->ue->id, ui->ue->ino, ui->ue->peer, fle->fe->fd);
> >>  
> >> -	sk = recv_fd(fle->fe->fd);
> >> +	sk = recv_fd_from_peer(fle);
> >>  	if (sk < 0) {
> >>  		pr_err("Can't recv pair slave\n");
> >>  		return -1;
> >> diff --git a/criu/tty.c b/criu/tty.c
> >> index 7ec5b1f..3dc60cd 100644
> >> --- a/criu/tty.c
> >> +++ b/criu/tty.c
> >> @@ -923,7 +923,7 @@ static int receive_tty(struct tty_info *info)
> >>  	fle = file_master(&info->d);
> >>  	pr_info("\tWaiting tty fd %d (pid %d)\n", fle->fe->fd, fle->pid);
> >>  
> >> -	fd = recv_fd(fle->fe->fd);
> >> +	fd = recv_fd_from_peer(fle);
> >>  	close(fle->fe->fd);
> >>  	if (fd < 0) {
> >>  		pr_err("Can't get fd %d\n", fd);
> >>


More information about the CRIU mailing list