[CRIU] [PATCH] restore: Parse /proc/self/maps for self mappings

Pavel Emelyanov xemul at parallels.com
Thu Feb 6 11:20:17 PST 2014


On restore we only need to know currnet task mappings' start and end
to find where to put the restorer blob. And since the smaps file in
/proc/pid is up to 3 times slower, than the maps one, it makes
perfect sense just to parse the latter one.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-restore.c         |  2 +-
 include/proc_parse.h |  1 +
 mem.c                |  4 ++++
 proc_parse.c         | 36 ++++++++++++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/cr-restore.c b/cr-restore.c
index f07c973..1afe7bd 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -2246,7 +2246,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	 * this unwanted mapping might get overlapped by the restorer.
 	 */
 
-	ret = parse_smaps(pid, &self_vmas, false);
+	ret = parse_self_maps_lite(&self_vmas);
 	close_proc();
 	if (ret < 0)
 		goto err;
diff --git a/include/proc_parse.h b/include/proc_parse.h
index 276a0de..f6af7d3 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -142,6 +142,7 @@ extern struct mount_info *parse_mountinfo(pid_t pid);
 extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
 extern int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s);
 extern int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_files);
+extern int parse_self_maps_lite(struct vm_area_list *vms);
 extern int parse_pid_status(pid_t pid, struct proc_status_creds *);
 
 union fdinfo_entries {
diff --git a/proc_parse.c b/proc_parse.c
index 26dd9c4..bc64b73 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -212,6 +212,42 @@ static int vma_get_mapfile(struct vma_area *vma, DIR *mfd,
 	return 0;
 }
 
+int parse_self_maps_lite(struct vm_area_list *vms)
+{
+	FILE *maps;
+
+	vm_area_list_init(vms);
+
+	maps = fopen("/proc/self/maps", "r");
+	if (maps == NULL) {
+		pr_perror("Can't open self maps");
+		return -1;
+	}
+
+	while (fgets(buf, BUF_SIZE, maps) != NULL) {
+		struct vma_area *vma;
+		char *end;
+
+		vma = alloc_vma_area();
+		if (!vma) {
+			fclose(maps);
+			return -1;
+		}
+
+		pr_debug("Parse %s\n", buf);
+		vma->e->start = strtoul(buf, &end, 16);
+		pr_debug("  Parse %s\n", end + 1);
+		vma->e->end = strtoul(end + 1, NULL, 16);
+		list_add_tail(&vma->list, &vms->h);
+		vms->nr++;
+
+		pr_debug("Parsed %lx-%lx vma\n", vma->e->start, vma->e->end);
+	}
+
+	fclose(maps);
+	return 0;
+}
+
 int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list, bool use_map_files)
 {
 	struct vma_area *vma_area = NULL;
-- 
1.8.4.2


More information about the CRIU mailing list