2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 06:15:24 +00:00

pagemap: fix reading pages from socket for --remote case

When --remote option is specified, read_local_page tries to pread from a
socket, and fails with "Illegal seek" error.
Restore single pread call for regular image files case and introduce
maybe_read_page_img_cache version of maybe_read_page method.

Generally-approved-by: Rodrigo Bruno <rbruno@gsd.inesc-id.pt>
Acked-by: Pavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Mike Rapoport
2017-04-25 13:38:01 +03:00
committed by Andrei Vagin
parent 0e245fca75
commit b7d1ea24cd

View File

@@ -245,7 +245,6 @@ static int read_local_page(struct page_read *pr, unsigned long vaddr,
{
int fd = img_raw_fd(pr->pi);
int ret;
size_t curr = 0;
/*
* Flush any pending async requests if any not to break the
@@ -255,15 +254,10 @@ static int read_local_page(struct page_read *pr, unsigned long vaddr,
return -1;
pr_debug("\tpr%lu-%u Read page from self %lx/%"PRIx64"\n", pr->img_id, pr->id, pr->cvaddr, pr->pi_off);
while (1) {
ret = pread(fd, buf + curr, len - curr, pr->pi_off + curr);
if (ret < 1) {
pr_perror("Can't read mapping page %d", ret);
return -1;
}
curr += ret;
if (curr == len)
break;
ret = pread(fd, buf, len, pr->pi_off);
if (ret != len) {
pr_perror("Can't read mapping page %d", ret);
return -1;
}
if (opts.auto_dedup) {
@@ -407,6 +401,40 @@ static int maybe_read_page_local(struct page_read *pr, unsigned long vaddr,
return ret;
}
static int maybe_read_page_img_cache(struct page_read *pr, unsigned long vaddr,
int nr, void *buf, unsigned flags)
{
unsigned long len = nr * PAGE_SIZE;
int fd = img_raw_fd(pr->pi);
int ret;
size_t curr = 0;
pr_debug("\tpr%lu-%u Read page from self %lx/%"PRIx64"\n", pr->img_id, pr->id, pr->cvaddr, pr->pi_off);
while (1) {
ret = read(fd, buf + curr, len - curr);
if (ret < 0) {
pr_perror("Can't read mapping page %d", ret);
return -1;
}
curr += ret;
if (curr == len)
break;
}
if (opts.auto_dedup) {
ret = punch_hole(pr, pr->pi_off, len, false);
if (ret == -1)
return -1;
}
if (ret == 0 && pr->io_complete)
ret = pr->io_complete(pr, vaddr, nr);
pr->pi_off += len;
return ret;
}
static int read_page_complete(unsigned long img_id, unsigned long vaddr, int nr_pages, void *priv)
{
int ret = 0;
@@ -805,7 +833,9 @@ int open_page_read_at(int dfd, unsigned long img_id, struct page_read *pr, int p
pr->id = ids++;
pr->img_id = img_id;
if (remote)
if (opts.remote)
pr->maybe_read_page = maybe_read_page_img_cache;
else if (remote)
pr->maybe_read_page = maybe_read_page_remote;
else {
pr->maybe_read_page = maybe_read_page_local;