mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
page-read: Explicitly mark ENOENT with return code
When page-read fails to open the pagemap image it reports error. One place (stacked page-reads) need to handle the absent images case gracefully, so fix the return codes to make this check work. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
e29c9daec2
commit
45a0cc4234
6 changed files with 55 additions and 37 deletions
|
|
@ -68,7 +68,7 @@ static int cr_dedup_one_pagemap(int pid)
|
|||
struct iovec iov;
|
||||
|
||||
ret = open_page_read(pid, &pr, PR_TASK | PR_MOD);
|
||||
if (ret) {
|
||||
if (ret <= 0) {
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ static int restore_priv_vma_content(pid_t pid)
|
|||
vma = list_first_entry(vmas, struct vma_area, list);
|
||||
|
||||
ret = open_page_read(pid, &pr, PR_TASK);
|
||||
if (ret)
|
||||
if (ret <= 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ struct page_read {
|
|||
#define PR_TYPE_MASK 0x3
|
||||
#define PR_MOD 0x4 /* Will need to modify */
|
||||
|
||||
/*
|
||||
* -1 -- error
|
||||
* 0 -- no images
|
||||
* 1 -- opened
|
||||
*/
|
||||
extern int open_page_read(int pid, struct page_read *, int pr_flags);
|
||||
extern int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags);
|
||||
extern void pagemap2iovec(PagemapEntry *pe, struct iovec *iov);
|
||||
|
|
|
|||
79
page-read.c
79
page-read.c
|
|
@ -192,7 +192,7 @@ static void close_page_read(struct page_read *pr)
|
|||
|
||||
static int try_open_parent(int dfd, int pid, struct page_read *pr, int pr_flags)
|
||||
{
|
||||
int pfd;
|
||||
int pfd, ret;
|
||||
struct page_read *parent = NULL;
|
||||
|
||||
pfd = openat(dfd, CR_PARENT_LINK, O_RDONLY);
|
||||
|
|
@ -203,9 +203,11 @@ static int try_open_parent(int dfd, int pid, struct page_read *pr, int pr_flags)
|
|||
if (!parent)
|
||||
goto err_cl;
|
||||
|
||||
if (open_page_read_at(pfd, pid, parent, pr_flags)) {
|
||||
if (errno != ENOENT)
|
||||
goto err_free;
|
||||
ret = open_page_read_at(pfd, pid, parent, pr_flags);
|
||||
if (ret < 0)
|
||||
goto err_free;
|
||||
|
||||
if (!ret) {
|
||||
xfree(parent);
|
||||
parent = NULL;
|
||||
}
|
||||
|
|
@ -225,6 +227,7 @@ err_cl:
|
|||
int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
|
||||
{
|
||||
int flags, i_typ, i_typ_o;
|
||||
static unsigned ids = 1;
|
||||
|
||||
if (opts.auto_dedup)
|
||||
pr_flags |= PR_MOD;
|
||||
|
|
@ -254,40 +257,50 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
|
|||
|
||||
pr->pmi = open_image_at(dfd, i_typ, O_RSTR, (long)pid);
|
||||
if (!pr->pmi) {
|
||||
pr->pmi = open_image_at(dfd, i_typ_o, flags, pid);
|
||||
if (!pr->pmi)
|
||||
if (errno == ENOENT)
|
||||
goto open_old;
|
||||
else
|
||||
return -1;
|
||||
|
||||
pr->get_pagemap = get_page_vaddr;
|
||||
pr->put_pagemap = NULL;
|
||||
pr->read_page = read_page;
|
||||
pr->pi = NULL;
|
||||
} else {
|
||||
static unsigned ids = 1;
|
||||
|
||||
if ((i_typ != CR_FD_SHMEM_PAGEMAP) && try_open_parent(dfd, pid, pr, pr_flags)) {
|
||||
close_image(pr->pmi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr->pi = open_pages_image_at(dfd, flags, pr->pmi);
|
||||
if (!pr->pi) {
|
||||
close_page_read(pr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr->get_pagemap = get_pagemap;
|
||||
pr->put_pagemap = put_pagemap;
|
||||
pr->read_page = read_pagemap_page;
|
||||
pr->id = ids++;
|
||||
|
||||
pr_debug("Opened page read %u (parent %u)\n",
|
||||
pr->id, pr->parent ? pr->parent->id : 0);
|
||||
}
|
||||
|
||||
if ((i_typ != CR_FD_SHMEM_PAGEMAP) && try_open_parent(dfd, pid, pr, pr_flags)) {
|
||||
close_image(pr->pmi);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr->pi = open_pages_image_at(dfd, flags, pr->pmi);
|
||||
if (!pr->pi) {
|
||||
close_page_read(pr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr->get_pagemap = get_pagemap;
|
||||
pr->put_pagemap = put_pagemap;
|
||||
pr->read_page = read_pagemap_page;
|
||||
pr->close = close_page_read;
|
||||
pr->id = ids++;
|
||||
|
||||
pr_debug("Opened page read %u (parent %u)\n",
|
||||
pr->id, pr->parent ? pr->parent->id : 0);
|
||||
|
||||
return 1;
|
||||
|
||||
open_old:
|
||||
pr->pmi = open_image_at(dfd, i_typ_o, flags, pid);
|
||||
if (!pr->pmi) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr->get_pagemap = get_page_vaddr;
|
||||
pr->put_pagemap = NULL;
|
||||
pr->read_page = read_page;
|
||||
pr->pi = NULL;
|
||||
pr->close = close_page_read;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int open_page_read(int pid, struct page_read *pr, int pr_flags)
|
||||
|
|
|
|||
|
|
@ -741,7 +741,7 @@ static int open_page_local_xfer(struct page_xfer *xfer, int fd_type, long id)
|
|||
}
|
||||
|
||||
ret = open_page_read_at(pfd, id, xfer->parent, PR_TASK);
|
||||
if (ret) {
|
||||
if (ret <= 0) {
|
||||
pr_perror("No parent image found, though parent directory is set");
|
||||
xfree(xfer->parent);
|
||||
xfer->parent = NULL;
|
||||
|
|
|
|||
2
shmem.c
2
shmem.c
|
|
@ -152,7 +152,7 @@ static int restore_shmem_content(void *addr, struct shmem_info *si)
|
|||
unsigned long off_real;
|
||||
|
||||
ret = open_page_read(si->shmid, &pr, PR_SHMEM);
|
||||
if (ret)
|
||||
if (ret <= 0)
|
||||
return -1;
|
||||
|
||||
fd_pg = img_raw_fd(pr.pi);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue