mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
page-xfer: Fix page-server descriptor cleanup
Page-server cleanup can run after partial setup and more than once. Partially initialized pipe arrays can still contain fd 0, while a retained destination ID can close descriptors again after their numbers have been reused. Setup failures and completed sessions can also leave transfer pipes open. Initialize pipe descriptors to -1 and clear the destination ID before closing its image. Check pipe initialization and size queries, and close transfer pipes when setup fails or a session completes. Assisted-by: Codex:GPT-5 Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
This commit is contained in:
parent
f9dd4c31ec
commit
d2f02fa1d0
1 changed files with 28 additions and 8 deletions
|
|
@ -1069,21 +1069,24 @@ struct page_xfer_job {
|
|||
|
||||
static struct page_xfer_job cxfer = {
|
||||
.dst_id = ~0,
|
||||
.p = { -1, -1 },
|
||||
};
|
||||
|
||||
static struct pipe_read_dest pipe_read_dest = {
|
||||
.p = { -1, -1 },
|
||||
.sink_fd = -1,
|
||||
};
|
||||
|
||||
static void page_server_close(void)
|
||||
{
|
||||
if (cxfer.dst_id != ~0)
|
||||
if (cxfer.dst_id != ~0ULL) {
|
||||
/* Make repeated/error-path cleanup harmless before closing resources. */
|
||||
cxfer.dst_id = ~0ULL;
|
||||
cxfer.loc_xfer.close(&cxfer.loc_xfer);
|
||||
if (pipe_read_dest.sink_fd != -1) {
|
||||
close(pipe_read_dest.sink_fd);
|
||||
close(pipe_read_dest.p[0]);
|
||||
close(pipe_read_dest.p[1]);
|
||||
}
|
||||
close_safe(&pipe_read_dest.sink_fd);
|
||||
close_safe(&pipe_read_dest.p[0]);
|
||||
close_safe(&pipe_read_dest.p[1]);
|
||||
}
|
||||
|
||||
static int page_server_open(int sk, struct page_server_iov *pi)
|
||||
|
|
@ -1110,7 +1113,7 @@ static int page_server_open(int sk, struct page_server_iov *pi)
|
|||
char has_parent = !!cxfer.loc_xfer.parent;
|
||||
if (__send(sk, &has_parent, 1, 0) != 1) {
|
||||
pr_perror("Unable to send response");
|
||||
close_page_xfer(&cxfer.loc_xfer);
|
||||
page_server_close();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1247,6 +1250,7 @@ static int page_server_get_pages(int sk, struct page_server_iov *pi)
|
|||
static int page_server_serve(int sk)
|
||||
{
|
||||
int ret = -1;
|
||||
int pipe_size;
|
||||
bool flushed = false;
|
||||
bool receiving_pages = !opts.lazy_pages;
|
||||
|
||||
|
|
@ -1264,10 +1268,22 @@ static int page_server_serve(int sk)
|
|||
return -1;
|
||||
}
|
||||
|
||||
cxfer.pipe_size = fcntl(cxfer.p[0], F_GETPIPE_SZ, 0);
|
||||
pipe_size = fcntl(cxfer.p[0], F_GETPIPE_SZ, 0);
|
||||
if (pipe_size < 0) {
|
||||
pr_perror("Can't get page-server transfer pipe size");
|
||||
close_safe(&cxfer.p[0]);
|
||||
close_safe(&cxfer.p[1]);
|
||||
close(sk);
|
||||
return -1;
|
||||
}
|
||||
cxfer.pipe_size = pipe_size;
|
||||
pr_debug("Created xfer pipe size %u\n", cxfer.pipe_size);
|
||||
} else {
|
||||
pipe_read_dest_init(&pipe_read_dest);
|
||||
if (pipe_read_dest_init(&pipe_read_dest)) {
|
||||
page_server_close();
|
||||
close(sk);
|
||||
return -1;
|
||||
}
|
||||
tcp_cork(sk, true);
|
||||
}
|
||||
|
||||
|
|
@ -1367,6 +1383,10 @@ static int page_server_serve(int sk)
|
|||
}
|
||||
|
||||
page_server_close();
|
||||
if (receiving_pages) {
|
||||
close_safe(&cxfer.p[0]);
|
||||
close_safe(&cxfer.p[1]);
|
||||
}
|
||||
|
||||
pr_info("Session over\n");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue