From fd41201975d76c8fbf04c4765afdca8427e32d26 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Fri, 7 Feb 2014 13:32:21 +0400 Subject: [PATCH] restore: Parse /proc/self/maps for self mappings 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 --- cr-restore.c | 2 +- include/proc_parse.h | 1 + proc_parse.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/cr-restore.c b/cr-restore.c index afc3656a7..f8b30a932 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -2231,7 +2231,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 276a0de48..f6af7d3c8 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 26dd9c41e..de3479dc2 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -212,6 +212,40 @@ 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; + } + + vma->e->start = strtoul(buf, &end, 16); + 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;