Commit 45a0cc42 authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
parent e29c9dae
......@@ -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);
......
......@@ -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)
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,16 +257,11 @@ 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);
......@@ -279,15 +277,30 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment