From e7276cf63b5d531eaeefdeebd02d6da0898caafa Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 23 May 2024 14:21:17 +0100 Subject: [PATCH] pagemap-cache: handle short reads It is possible for pread() to return fewer number of bytes than requested. In such case, we need to repeat the read operation with appropriate offset. Signed-off-by: Andrei Vagin Signed-off-by: Radostin Stoyanov --- criu/pagemap-cache.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/criu/pagemap-cache.c b/criu/pagemap-cache.c index 978a6b1ac..f04a517de 100644 --- a/criu/pagemap-cache.c +++ b/criu/pagemap-cache.c @@ -165,7 +165,7 @@ static int pmc_fill_cache(pmc_t *pmc, const struct vma_area *vma) int pmc_fill(pmc_t *pmc, u64 start, u64 end) { - size_t size_map; + size_t size_map, off; pmc->start = start; pmc->end = end; @@ -204,10 +204,17 @@ int pmc_fill(pmc_t *pmc, u64 start, u64 end) pmc->regs_idx = 0; pmc->end = args.walk_end; } else { - if (pread(pmc->fd, pmc->map, size_map, PAGEMAP_PFN_OFF(pmc->start)) != size_map) { - pmc_zap(pmc); - pr_perror("Can't read %d's pagemap file", pmc->pid); - return -1; + for (off = 0; off != size_map;) { + ssize_t ret; + char *ptr = (char *)pmc->map; + + ret = pread(pmc->fd, ptr + off, size_map - off, PAGEMAP_PFN_OFF(pmc->start) + off); + if (ret == -1) { + pmc_zap(pmc); + pr_perror("Can't read %d's pagemap file", pmc->pid); + return -1; + } + off += ret; } }