[CRIU] [PATCH 2/3] page-read: Explicitly mark ENOENT with return code
Pavel Emelyanov
xemul at parallels.com
Fri Mar 6 07:02:22 PST 2015
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 at parallels.com>
---
cr-dedup.c | 2 +-
cr-restore.c | 2 +-
include/page-read.h | 5 ++++
page-read.c | 69 +++++++++++++++++++++++++++++++----------------------
page-xfer.c | 2 +-
shmem.c | 2 +-
6 files changed, 50 insertions(+), 32 deletions(-)
diff --git a/cr-dedup.c b/cr-dedup.c
index d0c1fc4..b453c3e 100644
--- a/cr-dedup.c
+++ b/cr-dedup.c
@@ -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;
}
diff --git a/cr-restore.c b/cr-restore.c
index c5d3a7f..15b9b7f 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -353,7 +353,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;
/*
diff --git a/include/page-read.h b/include/page-read.h
index 0ac316e..9e3013a 100644
--- a/include/page-read.h
+++ b/include/page-read.h
@@ -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);
diff --git a/page-read.c b/page-read.c
index 1126ad8..c3d8a8f 100644
--- a/page-read.c
+++ b/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;
+ }
- 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->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->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);
- 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)
diff --git a/page-xfer.c b/page-xfer.c
index 43345d5..c594aba 100644
--- a/page-xfer.c
+++ b/page-xfer.c
@@ -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;
diff --git a/shmem.c b/shmem.c
index c66b2b4..b2900f4 100644
--- a/shmem.c
+++ b/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);
--
1.8.4.2
More information about the CRIU
mailing list