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) ...@@ -68,7 +68,7 @@ static int cr_dedup_one_pagemap(int pid)
struct iovec iov; struct iovec iov;
ret = open_page_read(pid, &pr, PR_TASK | PR_MOD); ret = open_page_read(pid, &pr, PR_TASK | PR_MOD);
if (ret) { if (ret <= 0) {
ret = -1; ret = -1;
goto exit; goto exit;
} }
......
...@@ -391,7 +391,7 @@ static int restore_priv_vma_content(pid_t pid) ...@@ -391,7 +391,7 @@ static int restore_priv_vma_content(pid_t pid)
vma = list_first_entry(vmas, struct vma_area, list); vma = list_first_entry(vmas, struct vma_area, list);
ret = open_page_read(pid, &pr, PR_TASK); ret = open_page_read(pid, &pr, PR_TASK);
if (ret) if (ret <= 0)
return -1; return -1;
/* /*
......
...@@ -74,6 +74,11 @@ struct page_read { ...@@ -74,6 +74,11 @@ struct page_read {
#define PR_TYPE_MASK 0x3 #define PR_TYPE_MASK 0x3
#define PR_MOD 0x4 /* Will need to modify */ #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(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 int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags);
extern void pagemap2iovec(PagemapEntry *pe, struct iovec *iov); extern void pagemap2iovec(PagemapEntry *pe, struct iovec *iov);
......
...@@ -192,7 +192,7 @@ static void close_page_read(struct page_read *pr) ...@@ -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) 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; struct page_read *parent = NULL;
pfd = openat(dfd, CR_PARENT_LINK, O_RDONLY); 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) ...@@ -203,9 +203,11 @@ static int try_open_parent(int dfd, int pid, struct page_read *pr, int pr_flags)
if (!parent) if (!parent)
goto err_cl; goto err_cl;
if (open_page_read_at(pfd, pid, parent, pr_flags)) { ret = open_page_read_at(pfd, pid, parent, pr_flags);
if (errno != ENOENT) if (ret < 0)
goto err_free; goto err_free;
if (!ret) {
xfree(parent); xfree(parent);
parent = NULL; parent = NULL;
} }
...@@ -225,6 +227,7 @@ err_cl: ...@@ -225,6 +227,7 @@ err_cl:
int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags) int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
{ {
int flags, i_typ, i_typ_o; int flags, i_typ, i_typ_o;
static unsigned ids = 1;
if (opts.auto_dedup) if (opts.auto_dedup)
pr_flags |= PR_MOD; pr_flags |= PR_MOD;
...@@ -254,40 +257,50 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags) ...@@ -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); pr->pmi = open_image_at(dfd, i_typ, O_RSTR, (long)pid);
if (!pr->pmi) { if (!pr->pmi) {
pr->pmi = open_image_at(dfd, i_typ_o, flags, pid); if (errno == ENOENT)
if (!pr->pmi) goto open_old;
else
return -1; return -1;
}
pr->get_pagemap = get_page_vaddr; if ((i_typ != CR_FD_SHMEM_PAGEMAP) && try_open_parent(dfd, pid, pr, pr_flags)) {
pr->put_pagemap = NULL; close_image(pr->pmi);
pr->read_page = read_page; return -1;
pr->pi = NULL; }
} else {
static unsigned ids = 1;
if ((i_typ != CR_FD_SHMEM_PAGEMAP) && try_open_parent(dfd, pid, pr, pr_flags)) { pr->pi = open_pages_image_at(dfd, flags, pr->pmi);
close_image(pr->pmi); if (!pr->pi) {
return -1; close_page_read(pr);
} return -1;
}
pr->pi = open_pages_image_at(dfd, flags, pr->pmi); pr->get_pagemap = get_pagemap;
if (!pr->pi) { pr->put_pagemap = put_pagemap;
close_page_read(pr); pr->read_page = read_pagemap_page;
return -1; pr->close = close_page_read;
} pr->id = ids++;
pr->get_pagemap = get_pagemap; pr_debug("Opened page read %u (parent %u)\n",
pr->put_pagemap = put_pagemap; pr->id, pr->parent ? pr->parent->id : 0);
pr->read_page = read_pagemap_page;
pr->id = ids++;
pr_debug("Opened page read %u (parent %u)\n", return 1;
pr->id, pr->parent ? pr->parent->id : 0);
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; pr->close = close_page_read;
return 0; return 1;
} }
int open_page_read(int pid, struct page_read *pr, int pr_flags) 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) ...@@ -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); 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"); pr_perror("No parent image found, though parent directory is set");
xfree(xfer->parent); xfree(xfer->parent);
xfer->parent = NULL; xfer->parent = NULL;
......
...@@ -152,7 +152,7 @@ static int restore_shmem_content(void *addr, struct shmem_info *si) ...@@ -152,7 +152,7 @@ static int restore_shmem_content(void *addr, struct shmem_info *si)
unsigned long off_real; unsigned long off_real;
ret = open_page_read(si->shmid, &pr, PR_SHMEM); ret = open_page_read(si->shmid, &pr, PR_SHMEM);
if (ret) if (ret <= 0)
return -1; return -1;
fd_pg = img_raw_fd(pr.pi); 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