[CRIU] [PATCH 06/11] dump: Dont read prohibited kernel files

Pavel Emelyanov xemul at parallels.com
Tue Dec 15 11:25:09 PST 2015


In particular, we won't be able to do memory tracking and
zero page detection.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 kerndat.c | 14 ++++++++++++--
 mem.c     | 12 +++++++-----
 util.c    |  4 ++--
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/kerndat.c b/kerndat.c
index 0f5b859..95fb2e6 100644
--- a/kerndat.c
+++ b/kerndat.c
@@ -222,7 +222,13 @@ int kerndat_get_dirty_track(void)
 	 * was at least once re-set. (this is to be removed in
 	 * a couple of kernel releases)
 	 */
-	do_task_reset_dirty_track(getpid());
+	ret = do_task_reset_dirty_track(getpid());
+	if (ret < 0)
+		return ret;
+	if (ret == 1)
+		goto no_dt;
+
+	ret = -1;
 	pm2 = open("/proc/self/pagemap", O_RDONLY);
 	if (pm2 < 0) {
 		pr_perror("Can't open pagemap file");
@@ -244,6 +250,7 @@ int kerndat_get_dirty_track(void)
 		pr_info("Dirty track supported on kernel\n");
 		kdat.has_dirty_track = true;
 	} else {
+no_dt:
 		pr_info("Dirty tracking support is OFF\n");
 		if (opts.track_mem) {
 			pr_err("Tracking memory is not available\n");
@@ -312,7 +319,10 @@ static int init_zero_page_pfn()
 	ret = vaddr_to_pfn((unsigned long)addr, &kdat.zero_page_pfn);
 	munmap(addr, PAGE_SIZE);
 
-	if (kdat.zero_page_pfn == 0)
+	if (ret == 1) {
+		pr_info("Zero page detection failed, optimization turns off.\n");
+		ret = 0;
+	} else if (kdat.zero_page_pfn == 0)
 		ret = -1;
 
 	return ret;
diff --git a/mem.c b/mem.c
index 989efc3..92e37f3 100644
--- a/mem.c
+++ b/mem.c
@@ -26,12 +26,16 @@
 
 static int task_reset_dirty_track(int pid)
 {
+	int ret;
+
 	if (!opts.track_mem)
 		return 0;
 
 	BUG_ON(!kdat.has_dirty_track);
 
-	return do_task_reset_dirty_track(pid);
+	ret = do_task_reset_dirty_track(pid);
+	BUG_ON(ret == 1);
+	return ret;
 }
 
 int do_task_reset_dirty_track(int pid)
@@ -41,9 +45,9 @@ int do_task_reset_dirty_track(int pid)
 
 	pr_info("Reset %d's dirty tracking\n", pid);
 
-	fd = open_proc_rw(pid, "clear_refs");
+	fd = __open_proc(pid, EACCES, O_RDWR, "clear_refs");
 	if (fd < 0)
-		return -1;
+		return errno == EACCES ? 1 : -1;
 
 	ret = write(fd, cmd, sizeof(cmd));
 	close(fd);
@@ -251,8 +255,6 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
 	pr_info("Dumping pages (type: %d pid: %d)\n", CR_FD_PAGES, ctl->pid.real);
 	pr_info("----------------------------------------\n");
 
-	BUG_ON(kdat.zero_page_pfn == 0);
-
 	timing_start(TIME_MEMDUMP);
 
 	pr_debug("   Private vmas %lu/%lu pages\n",
diff --git a/util.c b/util.c
index d56f973..7f4b726 100644
--- a/util.c
+++ b/util.c
@@ -693,9 +693,9 @@ int vaddr_to_pfn(unsigned long vaddr, u64 *pfn)
 	int fd, ret = -1;
 	off_t off;
 
-	fd = open_proc(getpid(), "pagemap");
+	fd = __open_proc(getpid(), EPERM, O_RDONLY, "pagemap");
 	if (fd < 0)
-		return -1;
+		return errno == EPERM ? 1 : -1;
 
 	off = (vaddr / page_size()) * sizeof(u64);
 	if (lseek(fd, off, SEEK_SET) != off) {
-- 
1.9.3




More information about the CRIU mailing list