[CRIU] [PATCH v4 07/33] files: Make sending fds to peers async
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Dec 13 07:05:10 PST 2016
Don't wait for "prepare" stage of every peer's fd. Just
send everything to a peer's global transport socket, and
the peer will find appropriate fd, it needs at the moment.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/files.c | 85 ++++----------------------------------------------
criu/include/files.h | 2 -
2 files changed, 7 insertions(+), 80 deletions(-)
diff --git a/criu/files.c b/criu/files.c
index d4d0845..63190ec 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -869,20 +869,17 @@ struct fd_open_state {
bool required;
};
-static int open_transport_fd(int pid, struct fdinfo_list_entry *fle);
static int open_fd(int pid, struct fdinfo_list_entry *fle);
static int receive_fd(int pid, struct fdinfo_list_entry *fle);
static int post_open_fd(int pid, struct fdinfo_list_entry *fle);
static struct fd_open_state states[] = {
- { "prepare", open_transport_fd, true,},
{ "create", open_fd, true,},
- { "receive", receive_fd, false,},
+ { "receive", receive_fd, true,},
{ "post_create", post_open_fd, false,},
};
-#define want_recv_stage() do { states[2].required = true; } while (0)
-#define want_post_open_stage() do { states[3].required = true; } while (0)
+#define want_post_open_stage() do { states[2].required = true; } while (0)
static void transport_name_gen(struct sockaddr_un *addr, int *len,
int pid, int fd)
@@ -893,68 +890,6 @@ static void transport_name_gen(struct sockaddr_un *addr, int *len,
*addr->sun_path = '\0';
}
-static int should_open_transport(FdinfoEntry *fe, struct file_desc *fd)
-{
- if (fd->ops->want_transport)
- return fd->ops->want_transport(fe, fd);
- else
- return 0;
-}
-
-static int open_transport_fd(int pid, struct fdinfo_list_entry *fle)
-{
- struct fdinfo_list_entry *flem;
- struct sockaddr_un saddr;
- int sock;
- int ret, sun_len;
-
- flem = file_master(fle->desc);
-
- if (flem->pid == pid) {
- if (flem->fe->fd != fle->fe->fd)
- /* dup-ed file. Will be opened in the open_fd */
- return 0;
-
- if (!should_open_transport(fle->fe, fle->desc))
- /* pure master file */
- return 0;
-
- /*
- * some master file, that wants a transport, e.g.
- * a pipe or unix socket pair 'slave' end
- */
- }
-
- transport_name_gen(&saddr, &sun_len, getpid(), fle->fe->fd);
-
- pr_info("\t\tCreate transport fd %s\n", saddr.sun_path + 1);
-
-
- sock = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (sock < 0) {
- pr_perror("Can't create socket");
- return -1;
- }
- ret = bind(sock, (struct sockaddr *)&saddr, sun_len);
- if (ret < 0) {
- pr_perror("Can't bind unix socket %s", saddr.sun_path + 1);
- goto err;
- }
-
- ret = reopen_fd_as(fle->fe->fd, sock);
- if (ret < 0)
- goto err;
-
- pr_info("\t\tWake up fdinfo pid=%d fd=%d\n", fle->pid, fle->fe->fd);
- futex_set_and_wake(&fle->real_pid, getpid());
- want_recv_stage();
-
- return 0;
-err:
- close(sock);
- return -1;
-}
-
static bool task_fle(struct pstree_item *task, struct fdinfo_list_entry *fle)
{
struct fdinfo_list_entry *tmp;
@@ -969,22 +904,20 @@ static int keep_fd_for_future(struct fdinfo_list_entry *fle, int fd)
{
BUG_ON(fle->received);
fle->received = 1;
- if (close(fle->fe->fd) < 0) {
- pr_perror("Can't close transport fd\n");
- return -1;
- }
return reopen_fd_as(fle->fe->fd, fd);
}
int recv_fd_from_peer(struct fdinfo_list_entry *fle)
{
struct fdinfo_list_entry *tmp;
- int fd, ret;
+ int fd, ret, tsock;
if (fle->received)
return fle->fe->fd;
+
+ tsock = get_service_fd(TRANSPORT_FD_OFF);
again:
- ret = recv_fds(fle->fe->fd, &fd, 1, (void *)&tmp, sizeof(struct fdinfo_list_entry *));
+ ret = recv_fds(tsock, &fd, 1, (void *)&tmp, sizeof(struct fdinfo_list_entry *));
if (ret)
return -1;
@@ -998,7 +931,6 @@ int recv_fd_from_peer(struct fdinfo_list_entry *fle)
return -1;
goto again;
}
- close(fle->fe->fd);
fle->received = 1;
return fd;
@@ -1011,10 +943,7 @@ int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle)
sock = get_service_fd(TRANSPORT_FD_OFF);
- pr_info("\t\tWait fdinfo pid=%d fd=%d\n", fle->pid, fle->fe->fd);
- futex_wait_while(&fle->real_pid, 0);
- transport_name_gen(&saddr, &len,
- futex_get(&fle->real_pid), fle->fe->fd);
+ transport_name_gen(&saddr, &len, fle->pid, -1);
pr_info("\t\tSend fd %d to %s\n", fd, saddr.sun_path + 1);
return send_fds(sock, &saddr, len, &fd, 1, (void *)&fle, sizeof(struct fdinfo_list_entry *));
}
diff --git a/criu/include/files.h b/criu/include/files.h
index 8c86eb2..07d6f94 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -70,14 +70,12 @@ struct fdinfo_list_entry {
struct list_head ps_list; /* To chain per-task files */
struct list_head used_list; /* To chain per-task used fds */
int pid;
- futex_t real_pid;
FdinfoEntry *fe;
u8 received:1;
};
static inline void fle_init(struct fdinfo_list_entry *fle, int pid, FdinfoEntry *fe)
{
- futex_init(&fle->real_pid);
fle->pid = pid;
fle->fe = fe;
fle->received = 0;
More information about the CRIU
mailing list