mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 14:25:49 +00:00
pagemap-cache: Use greedy mode if pagemap inaccessible
If criu is running in unprivileged mode and we can't access dumpee's pagemap file -- simply switch to greedy mode where all pages are gonna be dumped regardless of their presence in memory. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Looks-good-to-me: Andrew Vagin <avagin@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
d1db4faf9b
commit
a4edef8e1c
@@ -39,20 +39,29 @@ int pmc_init(pmc_t *pmc, pid_t pid, const struct list_head *vma_head, size_t siz
|
||||
BUG_ON(!vma_head);
|
||||
|
||||
pmc->pid = pid;
|
||||
pmc->fd = open_proc(pid, "pagemap");
|
||||
pmc->map_len = PAGEMAP_LEN(map_size);
|
||||
pmc->map = xmalloc(pmc->map_len);
|
||||
pmc->vma_head = vma_head;
|
||||
|
||||
if (!pmc->map || pmc->fd < 0) {
|
||||
pr_err("Failed to init pagemap for %d\n", pid);
|
||||
pmc_fini(pmc);
|
||||
return -1;
|
||||
pmc->map = xmalloc(pmc->map_len);
|
||||
if (!pmc->map)
|
||||
goto err;
|
||||
|
||||
pmc->fd = __open_proc(pid, EPERM, O_RDONLY, "pagemap");
|
||||
if (pmc->fd < 0) {
|
||||
if (errno != EPERM)
|
||||
goto err;
|
||||
|
||||
pr_warn("No pagemap for %d available, "
|
||||
"switching to greedy mode\n", pid);
|
||||
}
|
||||
|
||||
pr_debug("created for pid %d (takes %zu bytes)\n", pid, pmc->map_len);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pr_err("Failed to init pagemap for %d\n", pid);
|
||||
pmc_fini(pmc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline u64 *__pmc_get_map(pmc_t *pmc, unsigned long addr)
|
||||
@@ -120,11 +129,20 @@ static int pmc_fill_cache(pmc_t *pmc, const struct vma_area *vma)
|
||||
size_map = PAGEMAP_LEN(pmc->end - pmc->start);
|
||||
BUG_ON(pmc->map_len < size_map);
|
||||
|
||||
if (unlikely(pmc->fd < 0)) {
|
||||
/*
|
||||
* We don't have access to the dumpee pagemap so fill
|
||||
* everything as present. It's better than refuse
|
||||
* to dump because it simply disables optimisation.
|
||||
*/
|
||||
memset(pmc->map, 1, size_map);
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user