[CRIU] [PATCHv2 2/9] util: Add fd parameter to vaddr_to_pfn()

Dmitry Safonov dsafonov at virtuozzo.com
Mon Jul 10 21:24:17 MSK 2017


Expand vaddr_to_pfn() so it can read and translate to PFN
from already opened fd. This can be used as optimization
if one need to translate a couple of addresses and
also to read other task's PFN.

I'll use it in the next patch for reading other tasks's
vdso's PFN.

Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
 criu/include/util.h |  2 +-
 criu/kerndat.c      |  2 +-
 criu/util.c         | 23 +++++++++++++++++------
 criu/vdso.c         |  2 +-
 4 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/criu/include/util.h b/criu/include/util.h
index ec93fd5c6bb0..ea915501c502 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -194,7 +194,7 @@ extern pid_t get_self_real_pid(void);
 #define USEC_PER_SEC	1000000L
 #define NSEC_PER_SEC    1000000000L
 
-int vaddr_to_pfn(unsigned long vaddr, u64 *pfn);
+int vaddr_to_pfn(int fd, unsigned long vaddr, u64 *pfn);
 
 /*
  * Check whether @str starts with @sub and report the
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 94711fcbf04d..85f4256547a5 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -424,7 +424,7 @@ static int init_zero_page_pfn()
 		return -1;
 	}
 
-	ret = vaddr_to_pfn((unsigned long)addr, &kdat.zero_page_pfn);
+	ret = vaddr_to_pfn(-1, (unsigned long)addr, &kdat.zero_page_pfn);
 	munmap(addr, PAGE_SIZE);
 
 	if (kdat.zero_page_pfn == 0)
diff --git a/criu/util.c b/criu/util.c
index 5ebf18f37915..563dbd50b2c4 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -834,14 +834,23 @@ out:
 	return ret;
 }
 
-int vaddr_to_pfn(unsigned long vaddr, u64 *pfn)
+/*
+ * Get PFN from pagemap file for virtual address vaddr.
+ * Optionally if fd >= 0, it's used as pagemap file descriptor
+ * (may be other task's pagemap)
+ */
+int vaddr_to_pfn(int fd, unsigned long vaddr, u64 *pfn)
 {
-	int fd, ret = -1;
+	int ret = -1;
 	off_t off;
+	bool close_fd = false;
 
-	fd = open_proc(PROC_SELF, "pagemap");
-	if (fd < 0)
-		return -1;
+	if (fd < 0) {
+		fd = open_proc(PROC_SELF, "pagemap");
+		if (fd < 0)
+			return -1;
+		close_fd = true;
+	}
 
 	off = (vaddr / page_size()) * sizeof(u64);
 	ret = pread(fd, pfn, sizeof(*pfn), off);
@@ -853,7 +862,9 @@ int vaddr_to_pfn(unsigned long vaddr, u64 *pfn)
 		ret = 0;
 	}
 
-	close(fd);
+	if (close_fd)
+		close(fd);
+
 	return ret;
 }
 
diff --git a/criu/vdso.c b/criu/vdso.c
index a0b8a4e0b39a..b4e6b1860e07 100644
--- a/criu/vdso.c
+++ b/criu/vdso.c
@@ -493,7 +493,7 @@ int vdso_init_dump(void)
 
 	if (kdat.pmap != PM_FULL)
 		pr_info("VDSO detection turned off\n");
-	else if (vaddr_to_pfn(vdso_maps.vdso_start, &vdso_pfn))
+	else if (vaddr_to_pfn(-1, vdso_maps.vdso_start, &vdso_pfn))
 		return -1;
 
 	return 0;
-- 
2.13.1



More information about the CRIU mailing list