[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