[CRIU] [PATCH v5 25/33] files: Make recv_fd_from_peer() non-block
Kirill Tkhai
ktkhai at virtuozzo.com
Mon Dec 26 06:29:07 PST 2016
This breaks everything, because files.c can't have
a deal with this yet. But next patch will teach it.
v5: Use hard-coded 0, -1 and 1 for successful return,
error and "again" request.
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 f996d29f0..28090c476 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -925,13 +925,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 0;
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 -1;
+ } else if (count == 0)
+ return 1;
+
ret = recv_fds(tsock, &fd, 1, (void *)&tmp, sizeof(struct fdinfo_list_entry *));
if (ret)
return -1;
@@ -951,7 +957,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 0;
}
int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle)
@@ -1003,7 +1009,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) != 0) {
pr_err("Can't receive\n");
return -1;
}
@@ -1072,18 +1078,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 != 0) {
+ if (ret != 1)
+ 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 6eaabeb4b..7be1d5f04 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 != 0) {
+ if (ret != 1)
+ 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 27badb857..845d90fba 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 != 0) {
+ if (ret != 1)
+ 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 8b342a95d..d367421dc 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 != 0) {
+ if (ret != 1)
+ 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 -1;
+ }
- return fd;
+ *new_fd = fd;
+ return 0;
}
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