Skip to content

Commit

Permalink
shmem: Check if we can seek over VMA holes first
Browse files Browse the repository at this point in the history
Using seek() to skip past holes in VM may not be possible. Check if it's
supported before attempting to do it.

Co-authored-by: Ivanq <[email protected]>
Signed-off-by: Younes Manton <[email protected]>
  • Loading branch information
ymanton and purplesyringa committed Dec 12, 2022
1 parent a59c7f6 commit 7ec3028
Showing 1 changed file with 42 additions and 12 deletions.
54 changes: 42 additions & 12 deletions criu/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ static int next_data_segment(int fd, unsigned long pfn, unsigned long *next_data
return 0;
}

static int do_dump_one_shmem(int fd, void *addr, struct shmem_info *si)
static int do_dump_one_shmem(int fd, void *addr, struct shmem_info *si, bool seek_data_supported)
{
struct page_pipe *pp;
struct page_xfer xfer;
Expand All @@ -750,7 +750,8 @@ static int do_dump_one_shmem(int fd, void *addr, struct shmem_info *si)
unsigned long pgaddr;
int st = -1;

if (pfn >= next_hole_pfn && next_data_segment(fd, pfn, &next_data_pnf, &next_hole_pfn))
if (seek_data_supported && pfn >= next_hole_pfn &&
next_data_segment(fd, pfn, &next_data_pnf, &next_hole_pfn))
goto err_xfer;

if (si->pstate_map && is_shmem_tracking_en()) {
Expand Down Expand Up @@ -808,20 +809,49 @@ static int dump_one_shmem(struct shmem_info *si)
{
int fd, ret = -1;
void *addr;
bool seek_data_supported;

pr_info("Dumping shared memory %ld\n", si->shmid);

fd = open_proc(si->pid, "map_files/%lx-%lx", si->start, si->end);
if (fd < 0)
goto err;
fd = __open_proc(si->pid, EPERM, O_RDONLY, "map_files/%lx-%lx", si->start, si->end);
if (fd >= 0) {
addr = mmap(NULL, si->size, PROT_READ, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
pr_err("Can't map shmem 0x%lx (0x%lx-0x%lx)\n", si->shmid, si->start, si->end);
goto errc;
}

addr = mmap(NULL, si->size, PROT_READ, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
pr_err("Can't map shmem 0x%lx (0x%lx-0x%lx)\n", si->shmid, si->start, si->end);
goto errc;
seek_data_supported = true;
} else {
if (errno != EPERM) {
goto err;
}

fd = open_proc(si->pid, "mem");
if (fd < 0) {
goto err;
}

addr = mmap(NULL, si->size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (addr == MAP_FAILED) {
pr_err("Can't map empty space for shmem 0x%lx (0x%lx-0x%lx)\n", si->shmid, si->start, si->end);
goto errc;
}

if (lseek(fd, si->start, SEEK_SET) < 0) {
pr_perror("Can't seek virtual memory");
return -1;
}

if (read(fd, addr, si->size) < si->size) {
pr_perror("Can't read virtual memory");
return -1;
}

seek_data_supported = false;
}

ret = do_dump_one_shmem(fd, addr, si);
ret = do_dump_one_shmem(fd, addr, si, seek_data_supported);

munmap(addr, si->size);
errc:
Expand Down Expand Up @@ -849,7 +879,7 @@ int dump_one_memfd_shmem(int fd, unsigned long shmid, unsigned long size)
goto err;
}

ret = do_dump_one_shmem(fd, addr, &si);
ret = do_dump_one_shmem(fd, addr, &si, true);

munmap(addr, size);
err:
Expand All @@ -875,7 +905,7 @@ int dump_one_sysv_shmem(void *addr, unsigned long size, unsigned long shmid)
if (fd < 0)
return -1;

ret = do_dump_one_shmem(fd, addr, si);
ret = do_dump_one_shmem(fd, addr, si, true);
close(fd);
return ret;
}
Expand Down

0 comments on commit 7ec3028

Please sign in to comment.