Commit d5540a2d authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

page-server: check that all data have been accepted

Currently criu sends data to the page server, but it doesn't get any
feedback, so it can't be sure that all data have been accepted.

This patch adds a flush command, which requires an answer from the page
server. This command is sent before disconnecting.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 9556ffb1
......@@ -1608,6 +1608,9 @@ int cr_pre_dump_tasks(pid_t pid)
ret = 0;
err:
if (disconnect_from_page_server())
ret = -1;
pstree_switch_state(root_item,
ret ? TASK_ALIVE : opts.final_state);
free_pstree(root_item);
......@@ -1726,6 +1729,9 @@ int cr_dump_tasks(pid_t pid)
fd_id_show_tree();
err:
if (disconnect_from_page_server())
ret = -1;
close_cr_fdset(&glob_fdset);
if (!ret) {
......
......@@ -30,4 +30,5 @@ struct page_pipe;
int page_xfer_dump_pages(struct page_xfer *, struct page_pipe *,
unsigned long off);
int connect_to_page_server(void);
int disconnect_from_page_server(void);
#endif
......@@ -21,6 +21,8 @@ struct page_server_iov {
#define PS_IOV_HOLE 2
#define PS_IOV_OPEN 3
#define PS_IOV_FLUSH 0x1023
#define PS_TYPE_BITS 8
#define PS_TYPE_MASK ((1 << PS_TYPE_BITS) - 1)
......@@ -145,6 +147,7 @@ static int page_server_hole(int sk, struct page_server_iov *pi)
static int page_server_serve(int sk)
{
int ret = -1;
bool flushed = false;
if (pipe(cxfer.p)) {
pr_perror("Can't make pipe for xfer");
......@@ -168,6 +171,8 @@ static int page_server_serve(int sk)
break;
}
flushed = false;
switch (pi.cmd) {
case PS_IOV_OPEN:
ret = page_server_open(&pi);
......@@ -178,6 +183,22 @@ static int page_server_serve(int sk)
case PS_IOV_HOLE:
ret = page_server_hole(sk, &pi);
break;
case PS_IOV_FLUSH:
{
int32_t status = 0;
/*
* An answer must be sent back to inform another side,
* that all data were received
*/
if (write(sk, &status, sizeof(status)) != sizeof(status)) {
pr_perror("Can't send the final package");
ret = -1;
}
flushed = true;
break;
}
default:
pr_err("Unknown command %u\n", pi.cmd);
ret = -1;
......@@ -188,6 +209,11 @@ static int page_server_serve(int sk)
break;
}
if (!flushed) {
pr_err("The data were not flushed");
ret = -1;
}
page_server_close();
pr_info("Session over\n");
......@@ -273,6 +299,37 @@ int connect_to_page_server(void)
return 0;
}
int disconnect_from_page_server(void)
{
struct page_server_iov pi = { .cmd = PS_IOV_FLUSH };
int32_t status = -1;
int ret = -1;
if (!opts.use_page_server)
return 0;
if (page_server_sk == -1)
return 0;
pr_info("Disconnect from the page server %s:%u\n",
inet_ntoa(opts.ps_addr.sin_addr),
(int)ntohs(opts.ps_addr.sin_port));
if (write(page_server_sk, &pi, sizeof(pi)) != sizeof(pi)) {
pr_perror("Can't write the fini command to server");
goto out;
}
if (read(page_server_sk, &status, sizeof(status)) != sizeof(status)) {
pr_perror("The page server doesn't answer");
goto out;
}
ret = 0;
out:
close_safe(&page_server_sk);
return ret ? : status;
}
static int write_pagemap_to_server(struct page_xfer *xfer,
struct iovec *iov)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment