[CRIU] [PATCH v4 25/33] files: Make recv_fd_from_peer() non-block

Kirill Tkhai ktkhai at virtuozzo.com
Tue Dec 13 07:07:52 PST 2016


This breaks everything, because files.c can't have
a deal with this yet. But next patch will teach it.

v4: tty: merge new_fd assignment to receive_tty()
    and return this function result directly.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/files.c   |   27 ++++++++++++++++-----------
 criu/pipes.c   |   12 +++++++-----
 criu/sk-unix.c |   12 +++++++-----
 criu/tty.c     |   23 ++++++++++++++---------
 4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/criu/files.c b/criu/files.c
index e226e71..8e60b49 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -896,13 +896,19 @@ static int keep_fd_for_future(struct fdinfo_list_entry *fle, int fd)
 int recv_fd_from_peer(struct fdinfo_list_entry *fle)
 {
 	struct fdinfo_list_entry *tmp;
-	int fd, ret, tsock;
+	int fd, ret, tsock, count;
 
 	if (fle->received)
-		return fle->fe->fd;
+		return ORV_OK;
 
 	tsock = get_service_fd(TRANSPORT_FD_OFF);
 again:
+	if (ioctl(tsock, FIONREAD, &count) < 0) {
+		pr_perror("Can't do ioctl on transport sock: pid=%d\n", fle->pid);
+		return ORV_ERR;
+	} else if (count == 0)
+		return ORV_AGAIN;
+
 	ret = recv_fds(tsock, &fd, 1, (void *)&tmp, sizeof(struct fdinfo_list_entry *));
 	if (ret)
 		return -1;
@@ -922,7 +928,7 @@ int recv_fd_from_peer(struct fdinfo_list_entry *fle)
 	if (reopen_fd_as(fle->fe->fd, fd) < 0)
 		return -1;
 
-	return fle->fe->fd;
+	return ORV_OK;
 }
 
 int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle)
@@ -974,7 +980,7 @@ static int post_open_fd(int pid, struct fdinfo_list_entry *fle)
 	struct file_desc *d = fle->desc;
 
 	if (fle != file_master(d)) {
-		if (receive_fd(pid, fle) < 0) {
+		if (receive_fd(pid, fle) != ORV_OK) {
 			pr_err("Can't receive\n");
 			return -1;
 		}
@@ -1043,18 +1049,17 @@ static int open_fd(int pid, struct fdinfo_list_entry *fle)
 
 static int receive_fd(int pid, struct fdinfo_list_entry *fle)
 {
-	int fd;
+	int ret;
 
 	pr_info("\tReceive fd for %d\n", fle->fe->fd);
 
-	fd = recv_fd_from_peer(fle);
-	if (fd < 0) {
-		pr_err("Can't get fd=%d, pid=%d\n", fle->fe->fd, fle->pid);
-		return -1;
+	ret = recv_fd_from_peer(fle);
+	if (ret != ORV_OK) {
+		if (ret != ORV_AGAIN)
+			pr_err("Can't get fd=%d, pid=%d\n", fle->fe->fd, fle->pid);
+		return ret;
 	}
 
-	BUG_ON(fd != fle->fe->fd);
-
 	if (fcntl(fle->fe->fd, F_SETFD, fle->fe->flags) == -1) {
 		pr_perror("Unable to set file descriptor flags");
 		return -1;
diff --git a/criu/pipes.c b/criu/pipes.c
index 4aef0c5..3a38821 100644
--- a/criu/pipes.c
+++ b/criu/pipes.c
@@ -230,18 +230,20 @@ static int reopen_pipe(int fd, int flags)
 static int recv_pipe_fd(struct pipe_info *pi, int *new_fd)
 {
 	struct fdinfo_list_entry *fle;
-	int tmp, fd;
+	int tmp, fd, ret;
 
 	fle = file_master(&pi->d);
 	fd = fle->fe->fd;
 
 	pr_info("\tWaiting fd for %d\n", fd);
 
-	tmp = recv_fd_from_peer(fle);
-	if (tmp < 0) {
-		pr_err("Can't get fd %d\n", tmp);
-		return -1;
+	ret = recv_fd_from_peer(fle);
+	if (ret != ORV_OK) {
+		if (ret != ORV_AGAIN)
+			pr_err("Can't get fd %d\n", fd);
+		return ret;
 	}
+	tmp = fd;
 
 	if (pi->reopen)
 		fd = reopen_pipe(tmp, pi->pe->flags);
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index 9791f16..9a04967 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -1100,18 +1100,20 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui, int *new_fd)
 static int open_unixsk_pair_slave(struct unix_sk_info *ui, int *new_fd)
 {
 	struct fdinfo_list_entry *fle;
-	int sk;
+	int sk, ret;
 
 	fle = file_master(&ui->d);
 
 	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_from_peer(fle);
-	if (sk < 0) {
-		pr_err("Can't recv pair slave\n");
-		return -1;
+	ret = recv_fd_from_peer(fle);
+	if (ret != ORV_OK) {
+		if (ret != ORV_AGAIN)
+			pr_err("Can't recv pair slave\n");
+		return ret;
 	}
+	sk = fle->fe->fd;
 
 	if (bind_unix_sk(sk, ui))
 		return -1;
diff --git a/criu/tty.c b/criu/tty.c
index 89a370a..dfa898c 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -913,24 +913,29 @@ static int pty_open_slaves(struct tty_info *info)
 	return ret;
 }
 
-static int receive_tty(struct tty_info *info)
+static int receive_tty(struct tty_info *info, int *new_fd)
 {
 	struct fdinfo_list_entry *fle;
-	int fd;
+	int fd, ret;
 
 	fle = file_master(&info->d);
 	pr_info("\tWaiting tty fd %d (pid %d)\n", fle->fe->fd, fle->pid);
 
-	fd = recv_fd_from_peer(fle);
-	if (fd < 0) {
-		pr_err("Can't get fd %d\n", fd);
-		return -1;
+	fd = fle->fe->fd;
+	ret = recv_fd_from_peer(fle);
+	if (ret != ORV_OK) {
+		if (ret != ORV_AGAIN)
+			pr_err("Can't get fd %d\n", fd);
+		return ret;
 	}
 
-	if (rst_file_params(fd, info->tfe->fown, info->tfe->flags))
+	if (rst_file_params(fd, info->tfe->fown, info->tfe->flags) < 0) {
 		close_safe(&fd);
+		return ORV_ERR;
+	}
 
-	return fd;
+	*new_fd = fd;
+	return ORV_OK;
 }
 
 static int pty_open_unpaired_slave(struct file_desc *d, struct tty_info *slave)
@@ -1101,7 +1106,7 @@ static int tty_open(struct file_desc *d, int *new_fd)
 	tty_show_pty_info("open", info);
 
 	if (!info->create)
-		ret = receive_tty(info);
+		return receive_tty(info, new_fd);
 	else if (is_pty(info->driver) && !tty_is_master(info))
 		ret = pty_open_unpaired_slave(d, info);
 	else



More information about the CRIU mailing list