[CRIU] [crtools-bot for Kir Kolyshkin ] open_proc() and friends: hide pid_dir

Cyrill Gorcunov gorcunov at openvz.org
Fri Feb 17 07:46:25 EST 2012


The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit 447388d79b8919fab155fd7cbb5d3148385bcd34
Author: Kir Kolyshkin <kir at openvz.org>
Date:   Fri Feb 17 01:39:36 2012 +0400

    open_proc() and friends: hide pid_dir
    
    This patch tries to introduce lazy and hidden pid_dir support,
    meaning one don't have to worry about pid_dir but the optimization
    is still there.
    
    The patch relies on the fact that we work with many /proc/pid files for
    one pid, then for another pid and so on, i.e. not in a random manner.
    
    The idea is when we call open_proc() with a new pid for the first time,
    the appropriate /proc/PID directory is opened and its fd is stored.
    Next call to open_proc() with the same PID only need to check that
    the PID is not changed. In case PID is changed, we close the old one
    and open/store a new one.
    
    Now the code using open_proc() and friends:
    - does not need to carry proc_pid around, pid is enough
    - does not need to call open_pid_proc()
    
    The only thing that can't be done in that "lazy" mode is closing the last
    PID fd, thus close_pid_proc().
    
    Signed-off-by: Kir Kolyshkin <kir at openvz.org>
    Acked-by: Pavel Emelyanov <xemul at parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c                  |   91 +++++++++++++++++++------------------------
 cr-restore.c               |    9 +---
 include/parasite-syscall.h |    2 +-
 include/proc_parse.h       |    8 ++--
 include/util.h             |   32 ++++++++-------
 parasite-syscall.c         |    8 +--
 proc_parse.c               |   18 ++++----
 util.c                     |   33 +++++++++++++++-
 8 files changed, 107 insertions(+), 94 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 9aaaf13..66f44ba 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -65,7 +65,7 @@ void free_mappings(struct list_head *vma_area_list)
 	INIT_LIST_HEAD(vma_area_list);
 }
 
-static int collect_mappings(pid_t pid, int pid_dir, struct list_head *vma_area_list)
+static int collect_mappings(pid_t pid, struct list_head *vma_area_list)
 {
 	int ret = -1;
 
@@ -73,7 +73,7 @@ static int collect_mappings(pid_t pid, int pid_dir, struct list_head *vma_area_l
 	pr_info("Collecting mappings (pid: %d)\n", pid);
 	pr_info("----------------------------------------\n");
 
-	ret = parse_maps(pid, pid_dir, vma_area_list, true);
+	ret = parse_maps(pid, vma_area_list, true);
 	if (ret)
 		goto err;
 
@@ -138,14 +138,14 @@ err:
 	return ret;
 }
 
-static int dump_task_special_files(pid_t pid, int pid_dir, struct cr_fdset *cr_fdset)
+static int dump_task_special_files(pid_t pid, struct cr_fdset *cr_fdset)
 {
 	struct fd_parms params;
 	int fd, ret;
 
 	/* Dump /proc/pid/cwd */
 	params = (struct fd_parms){ .fd_name = FDINFO_CWD, };
-	fd = open_proc(pid, pid_dir, "cwd");
+	fd = open_proc(pid, "cwd");
 	if (fd < 0)
 		return -1;
 	ret = dump_one_reg_file(FDINFO_FD, &params, fd, cr_fdset, 1);
@@ -154,7 +154,7 @@ static int dump_task_special_files(pid_t pid, int pid_dir, struct cr_fdset *cr_f
 
 	/* Dump /proc/pid/exe */
 	params = (struct fd_parms){ .fd_name = FDINFO_EXE, };
-	fd = open_proc(pid, pid_dir, "exe");
+	fd = open_proc(pid, "exe");
 	if (fd < 0)
 		return -1;
 	ret = dump_one_reg_file(FDINFO_FD, &params, fd, cr_fdset, 1);
@@ -302,12 +302,12 @@ out_close:
 	return err;
 }
 
-static int read_fd_params(pid_t pid, int pid_dir, char *fd, struct fd_parms *p)
+static int read_fd_params(pid_t pid, char *fd, struct fd_parms *p)
 {
 	FILE *file;
 	int ret;
 
-	file = fopen_proc(pid, pid_dir, "fdinfo/%s", fd);
+	file = fopen_proc(pid, "fdinfo/%s", fd);
 	if (!file)
 		return -1;
 
@@ -326,7 +326,7 @@ static int read_fd_params(pid_t pid, int pid_dir, char *fd, struct fd_parms *p)
 	return 0;
 }
 
-static int dump_task_files(pid_t pid, int pid_dir, struct cr_fdset *cr_fdset)
+static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset)
 {
 	struct dirent *de;
 	unsigned long pos;
@@ -342,12 +342,12 @@ static int dump_task_files(pid_t pid, int pid_dir, struct cr_fdset *cr_fdset)
 	 * to re-read them in restorer, so better to make it
 	 * fast.
 	 */
-	if (dump_task_special_files(pid, pid_dir, cr_fdset)) {
+	if (dump_task_special_files(pid, cr_fdset)) {
 		pr_err("Can't dump special files\n");
 		return -1;
 	}
 
-	fd_dir = opendir_proc(pid, pid_dir, "fd");
+	fd_dir = opendir_proc(pid, "fd");
 	if (!fd_dir)
 		return -1;
 
@@ -358,7 +358,7 @@ static int dump_task_files(pid_t pid, int pid_dir, struct cr_fdset *cr_fdset)
 
 		if (de->d_name[0] == '.')
 			continue;
-		if (read_fd_params(pid, pid_dir, de->d_name, &p))
+		if (read_fd_params(pid, de->d_name, &p))
 			return -1;
 
 		lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY);
@@ -436,7 +436,7 @@ err:
 	return ret;
 }
 
-static int dump_task_creds(pid_t pid, int pid_dir,
+static int dump_task_creds(pid_t pid,
 		struct parasite_dump_misc *misc, struct cr_fdset *fds)
 {
 	int ret, i;
@@ -447,7 +447,7 @@ static int dump_task_creds(pid_t pid, int pid_dir,
 	pr_info("Dumping creds for %d)\n", pid);
 	pr_info("----------------------------------------\n");
 
-	ret = parse_pid_status(pid, pid_dir, &cr);
+	ret = parse_pid_status(pid, &cr);
 	if (ret < 0)
 		return ret;
 
@@ -481,7 +481,7 @@ static int dump_task_creds(pid_t pid, int pid_dir,
 #define assign_reg(dst, src, e)		dst.e = (__typeof__(dst.e))src.e
 #define assign_array(dst, src, e)	memcpy(&dst.e, &src.e, sizeof(dst.e))
 
-static int get_task_sigmask(pid_t pid, int pid_dir, u64 *task_sigset)
+static int get_task_sigmask(pid_t pid, u64 *task_sigset)
 {
 	FILE *file;
 	int ret = -1;
@@ -489,7 +489,7 @@ static int get_task_sigmask(pid_t pid, int pid_dir, u64 *task_sigset)
 	/*
 	 * Now signals.
 	 */
-	file = fopen_proc(pid, pid_dir, "status");
+	file = fopen_proc(pid, "status");
 	if (!file)
 		goto err;
 
@@ -507,9 +507,9 @@ err:
 	return ret;
 }
 
-static int get_task_auxv(pid_t pid, int pid_dir, struct core_entry *core)
+static int get_task_auxv(pid_t pid, struct core_entry *core)
 {
-	int fd = open_proc(pid, pid_dir, "auxv");
+	int fd = open_proc(pid, "auxv");
 	int ret, i;
 
 	if (fd < 0)
@@ -535,12 +535,12 @@ err:
 	return ret;
 }
 
-static int get_task_personality(pid_t pid, int pid_dir, u32 *personality)
+static int get_task_personality(pid_t pid, u32 *personality)
 {
 	FILE *file = NULL;
 	int ret = -1;
 
-	file = fopen_proc(pid, pid_dir, "personality");
+	file = fopen_proc(pid, "personality");
 	if (!file)
 		goto err;
 
@@ -657,7 +657,7 @@ static int dump_task_core(struct core_entry *core, struct cr_fdset *fdset)
 	return ret;
 }
 
-static int dump_task_core_all(pid_t pid, int pid_dir, struct proc_pid_stat *stat,
+static int dump_task_core_all(pid_t pid, struct proc_pid_stat *stat,
 		struct parasite_dump_misc *misc, struct cr_fdset *cr_fdset)
 {
 	struct core_entry *core		= xzalloc(sizeof(*core));
@@ -678,7 +678,7 @@ static int dump_task_core_all(pid_t pid, int pid_dir, struct proc_pid_stat *stat
 	pr_info("OK\n");
 
 	pr_info("Obtainting personality ... ");
-	ret = get_task_personality(pid, pid_dir, &core->tc.personality);
+	ret = get_task_personality(pid, &core->tc.personality);
 	if (ret)
 		goto err_free;
 	pr_info("OK\n");
@@ -700,13 +700,13 @@ static int dump_task_core_all(pid_t pid, int pid_dir, struct proc_pid_stat *stat
 	core->tc.mm_brk = misc->brk;
 
 	pr_info("Obtainting sigmask ... ");
-	ret = get_task_sigmask(pid, pid_dir, &core->tc.blk_sigset);
+	ret = get_task_sigmask(pid, &core->tc.blk_sigset);
 	if (ret)
 		goto err_free;
 	pr_info("OK\n");
 
 	pr_info("Obtainting task auvx ... ");
-	ret = get_task_auxv(pid, pid_dir, core);
+	ret = get_task_auxv(pid, core);
 	if (ret)
 		goto err_free;
 	pr_info("OK\n");
@@ -724,14 +724,14 @@ err:
 	return ret;
 }
 
-static int parse_threads(struct pstree_item *item, pid_t pid, int pid_dir)
+static int parse_threads(struct pstree_item *item, pid_t pid)
 {
 	struct dirent *de;
 	DIR *dir;
 	u32 *t = NULL;
 	int nr = 1;
 
-	dir = opendir_proc(pid, pid_dir, "task");
+	dir = opendir_proc(pid, "task");
 	if (!dir)
 		return -1;
 
@@ -760,7 +760,7 @@ static int parse_threads(struct pstree_item *item, pid_t pid, int pid_dir)
 	return 0;
 }
 
-static int parse_children(struct pstree_item *item, pid_t pid, int pid_dir)
+static int parse_children(struct pstree_item *item, pid_t pid)
 {
 	FILE *file;
 	char *tok;
@@ -769,7 +769,7 @@ static int parse_children(struct pstree_item *item, pid_t pid, int pid_dir)
 
 	for (i = 0; i < item->nr_threads; i++) {
 
-		file = fopen_proc(pid, pid_dir, "task/%d/children", item->threads[i]);
+		file = fopen_proc(pid, "task/%d/children", item->threads[i]);
 		if (!file)
 			goto err;
 
@@ -864,7 +864,7 @@ err:
 
 static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
 {
-	int ret, pid_dir;
+	int ret;
 	struct pstree_item *item;
 
 	item = xzalloc(sizeof(*item));
@@ -879,14 +879,10 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
 	item->pid = pid;
 	item->state = ret;
 
-	pid_dir = open_pid_proc(pid);
-	if (pid_dir < 0)
-		goto err_free;
-
 	if (item->state == TASK_SHOULD_BE_DEAD) {
 		struct proc_pid_stat_small ps;
 
-		ret = parse_pid_stat_small(pid, pid_dir, &ps);
+		ret = parse_pid_stat_small(pid, &ps);
 		if (ret < 0)
 			goto err_close;
 
@@ -899,7 +895,7 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
 		item->state = TASK_DEAD;
 	}
 
-	ret = parse_threads(item, pid, pid_dir);
+	ret = parse_threads(item, pid);
 	if (ret < 0)
 		goto err_close;
 
@@ -907,7 +903,7 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
 	if (ret < 0)
 		goto err_close;
 
-	ret = parse_children(item, pid, pid_dir);
+	ret = parse_children(item, pid);
 	if (ret < 0)
 		goto err_close;
 
@@ -916,13 +912,13 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
 		goto err_close;
 	}
 
-	close(pid_dir);
+	close_pid_proc();
 	list_add_tail(&item->list, list);
 	pr_info("Collected %d in %d state\n", item->pid, item->state);
 	return item;
 
 err_close:
-	close(pid_dir);
+	close_pid_proc();
 err_free:
 	xfree(item->children);
 	xfree(item->threads);
@@ -1149,7 +1145,6 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
 	LIST_HEAD(vma_area_list);
 	struct parasite_ctl *parasite_ctl;
 	int ret = -1;
-	int pid_dir;
 	struct parasite_dump_misc misc;
 
 	pr_info("========================================\n");
@@ -1161,14 +1156,8 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
 		goto err_free;
 	}
 
-	pid_dir = open_pid_proc(pid);
-	if (pid_dir < 0) {
-		pr_perror("Can't open %d proc dir", pid);
-		goto err_free;
-	}
-
 	pr_info("Obtainting task stat ... ");
-	ret = parse_pid_stat(pid, pid_dir, &pps_buf);
+	ret = parse_pid_stat(pid, &pps_buf);
 	if (ret < 0)
 		goto err;
 
@@ -1179,13 +1168,13 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
 	if (!cr_dump_fdset_open(item->pid, CR_FD_DESC_TASK, cr_fdset))
 		goto err;
 
-	ret = collect_mappings(pid, pid_dir, &vma_area_list);
+	ret = collect_mappings(pid, &vma_area_list);
 	if (ret) {
 		pr_err("Collect mappings (pid: %d) failed with %d\n", pid, ret);
 		goto err;
 	}
 
-	parasite_ctl = parasite_infect_seized(pid, pid_dir, &vma_area_list);
+	parasite_ctl = parasite_infect_seized(pid, &vma_area_list);
 	if (!parasite_ctl) {
 		pr_err("Can't infect (pid: %d) with parasite\n", pid);
 		goto err;
@@ -1221,7 +1210,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
 		goto err;
 	}
 
-	ret = dump_task_files(pid, pid_dir, cr_fdset);
+	ret = dump_task_files(pid, cr_fdset);
 	if (ret) {
 		pr_err("Dump files (pid: %d) failed with %d\n", pid, ret);
 		goto err;
@@ -1233,13 +1222,13 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
 		goto err;
 	}
 
-	ret = dump_task_creds(pid, pid_dir, &misc, cr_fdset);
+	ret = dump_task_creds(pid, &misc, cr_fdset);
 	if (ret) {
 		pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
 		goto err;
 	}
 
-	ret = dump_task_core_all(pid, pid_dir, &pps_buf, &misc, cr_fdset);
+	ret = dump_task_core_all(pid, &pps_buf, &misc, cr_fdset);
 	if (ret) {
 		pr_err("Dump core (pid: %d) failed with %d\n", pid, ret);
 		goto err;
@@ -1256,7 +1245,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
 	ret = dump_task_threads(item);
 
 err:
-	close(pid_dir);
+	close_pid_proc();
 err_free:
 	free_mappings(&vma_area_list);
 	return ret;
diff --git a/cr-restore.c b/cr-restore.c
index de1be9a..fb71300 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1639,7 +1639,6 @@ static void sigreturn_restore(pid_t pid)
 	int num, i;
 
 	int *fd_core_threads;
-	int pid_dir;
 
 	pr_info("%d: Restore via sigreturn\n", pid);
 
@@ -1647,12 +1646,8 @@ static void sigreturn_restore(pid_t pid)
 	restore_task_vma_len	= 0;
 	restore_thread_vma_len	= 0;
 
-	pid_dir = open_pid_proc(pid);
-	if (pid_dir < 0)
-		goto err;
-
-	ret = parse_maps(pid, pid_dir, &self_vma_list, false);
-	close(pid_dir);
+	ret = parse_maps(pid, &self_vma_list, false);
+	close_pid_proc();
 	if (ret)
 		goto err;
 
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 167822c..83ec588 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -37,7 +37,7 @@ extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
 				      struct list_head *vma_area_list,
 				      struct cr_fdset *cr_fdset);
 extern int parasite_cure_seized(struct parasite_ctl *ctl);
-extern struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir,
+extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
 						   struct list_head *vma_area_list);
 
 #endif /* PARASITE_SYSCALL_H_ */
diff --git a/include/proc_parse.h b/include/proc_parse.h
index 788200e..91714e5 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -77,9 +77,9 @@ struct proc_status_creds {
 	unsigned int cap_bnd[PROC_CAP_SIZE];
 };
 
-extern int parse_pid_stat(pid_t pid, int pid_dir, struct proc_pid_stat *s);
-extern int parse_pid_stat_small(pid_t pid, int pid_dir, struct proc_pid_stat_small *s);
-extern int parse_maps(pid_t pid, int pid_dir, struct list_head *vma_area_list, bool use_map_files);
-extern int parse_pid_status(pid_t pid, int pid_dir, struct proc_status_creds *);
+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_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files);
+extern int parse_pid_status(pid_t pid, struct proc_status_creds *);
 
 #endif /* PROC_PARSE_H__ */
diff --git a/include/util.h b/include/util.h
index 212d380..6afb85d 100644
--- a/include/util.h
+++ b/include/util.h
@@ -205,11 +205,13 @@ extern int reopen_fd_as_safe(int new_fd, int old_fd, bool allow_reuse_fd);
 extern void hex_dump(void *addr, unsigned long len);
 
 int open_pid_proc(pid_t pid);
-int do_open_proc(int pid_dir, int flags, const char *fmt, ...);
+int close_pid_proc(void);
 
-#define __open_proc(pid, pid_dir, flags, fmt, ...)		\
+int do_open_proc(pid_t pid, int flags, const char *fmt, ...);
+
+#define __open_proc(pid, flags, fmt, ...)			\
 	({							\
-		int __fd = do_open_proc(pid_dir, flags,		\
+		int __fd = do_open_proc(pid, flags,		\
 					fmt, ##__VA_ARGS__);	\
 		if (__fd < 0)					\
 			pr_perror("Can't open /proc/%d/" fmt,	\
@@ -218,18 +220,18 @@ int do_open_proc(int pid_dir, int flags, const char *fmt, ...);
 		__fd;						\
 	})
 
-/* int open_proc(pid_t pid, int pid_dir, const char *fmt, ...); */
-#define open_proc(pid, pid_dir, fmt, ...)			\
-	__open_proc(pid, pid_dir, O_RDONLY, fmt, ##__VA_ARGS__)
+/* int open_proc(pid_t pid, const char *fmt, ...); */
+#define open_proc(pid, fmt, ...)				\
+	__open_proc(pid, O_RDONLY, fmt, ##__VA_ARGS__)
 
-/* int open_proc_rw(pid_t pid, int pid_dir, const char *fmt, ...); */
-#define open_proc_rw(pid, pid_dir, fmt, ...)			\
-	__open_proc(pid, pid_dir, O_RDWR, fmt, ##__VA_ARGS__)
+/* int open_proc_rw(pid_t pid, const char *fmt, ...); */
+#define open_proc_rw(pid, fmt, ...)				\
+	__open_proc(pid, O_RDWR, fmt, ##__VA_ARGS__)
 
-/* DIR *opendir_proc(pid_t pid, int pid_dir,  const char *fmt, ...); */
-#define opendir_proc(pid, pid_dir, fmt, ...)				\
+/* DIR *opendir_proc(pid_t pid, const char *fmt, ...); */
+#define opendir_proc(pid, fmt, ...)					\
 	({								\
-		int __fd = open_proc(pid, pid_dir, fmt, ##__VA_ARGS__);	\
+		int __fd = open_proc(pid, fmt, ##__VA_ARGS__);		\
 		DIR *__d = NULL;					\
 									\
 		if (__fd >= 0)						\
@@ -242,10 +244,10 @@ int do_open_proc(int pid_dir, int flags, const char *fmt, ...);
 		__d;							\
 	 })
 
-/* FILE *fopen_proc(pid_t pid, int pid_dir, const char *fmt, ...); */
-#define fopen_proc(pid, pid_dir, fmt, ...)				\
+/* FILE *fopen_proc(pid_t pid, const char *fmt, ...); */
+#define fopen_proc(pid, fmt, ...)					\
 	({								\
-		int __fd = open_proc(pid, pid_dir, fmt, ##__VA_ARGS__);	\
+		int __fd = open_proc(pid,  fmt, ##__VA_ARGS__);		\
 		FILE *__f = NULL;					\
 									\
 		if (__fd >= 0)						\
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 83646a8..02a50fa 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -560,7 +560,7 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
 	return ret;
 }
 
-struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_head *vma_area_list)
+struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_area_list)
 {
 	struct parasite_ctl *ctl = NULL;
 	struct vma_area *vma_area;
@@ -620,12 +620,10 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_
 
 	ctl->map_length = round_up(parasite_size, PAGE_SIZE);
 
-	fd = open_proc_rw(pid, pid_dir, "map_files/%p-%p",
+	fd = open_proc_rw(pid, "map_files/%p-%p",
 		 ctl->remote_map, ctl->remote_map + ctl->map_length);
-	if (fd < 0) {
-		pr_perror("Can't open remote parasite map");
+	if (fd < 0)
 		goto err_restore;
-	}
 
 	ctl->local_map = mmap(NULL, parasite_size, PROT_READ | PROT_WRITE,
 			      MAP_SHARED | MAP_FILE, fd, 0);
diff --git a/proc_parse.c b/proc_parse.c
index 6c5620f..a443d6e 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -15,7 +15,7 @@
 
 #include "proc_parse.h"
 
-int parse_maps(pid_t pid, int pid_dir, struct list_head *vma_area_list, bool use_map_files)
+int parse_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files)
 {
 	struct vma_area *vma_area = NULL;
 	u64 start, end, pgoff;
@@ -28,12 +28,12 @@ int parse_maps(pid_t pid, int pid_dir, struct list_head *vma_area_list, bool use
 	DIR *map_files_dir = NULL;
 	FILE *maps = NULL;
 
-	maps = fopen_proc(pid, pid_dir, "maps");
+	maps = fopen_proc(pid, "maps");
 	if (!maps)
 		goto err;
 
 	if (use_map_files) {
-		map_files_dir = opendir_proc(pid, pid_dir, "map_files");
+		map_files_dir = opendir_proc(pid, "map_files");
 		if (!map_files_dir) /* old kernel? */
 			goto err;
 	}
@@ -179,13 +179,13 @@ err_bogus_mapping:
 	goto err;
 }
 
-int parse_pid_stat_small(pid_t pid, int pid_dir, struct proc_pid_stat_small *s)
+int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s)
 {
 	FILE *f;
 	char *tok;
 	int n;
 
-	f = fopen_proc(pid, pid_dir, "stat");
+	f = fopen_proc(pid, "stat");
 	if (f == NULL)
 		return -1;
 
@@ -207,13 +207,13 @@ int parse_pid_stat_small(pid_t pid, int pid_dir, struct proc_pid_stat_small *s)
 	return 0;
 }
 
-int parse_pid_stat(pid_t pid, int pid_dir, struct proc_pid_stat *s)
+int parse_pid_stat(pid_t pid, struct proc_pid_stat *s)
 {
 	FILE *f;
 	char *tok;
 	int n;
 
-	f = fopen_proc(pid, pid_dir, "stat");
+	f = fopen_proc(pid, "stat");
 	if (f == NULL)
 		return -1;
 
@@ -318,13 +318,13 @@ static int cap_parse(char *str, unsigned int *res)
 	return 0;
 }
 
-int parse_pid_status(pid_t pid, int pid_dir, struct proc_status_creds *cr)
+int parse_pid_status(pid_t pid, struct proc_status_creds *cr)
 {
 	int done = 0;
 	FILE *f;
 	char str[64];
 
-	f = fopen_proc(pid, pid_dir, "status");
+	f = fopen_proc(pid, "status");
 	if (f == NULL) {
 		pr_perror("Can't open proc status");
 		return -1;
diff --git a/util.c b/util.c
index bad52e4..d6ca8a4 100644
--- a/util.c
+++ b/util.c
@@ -205,22 +205,51 @@ int open_image_ro(int type, int pid)
 	return fd;
 }
 
-int open_pid_proc(pid_t pid)
+static pid_t open_proc_pid = 0;
+static int open_proc_fd = -1;
+
+int close_pid_proc(void)
+{
+	int ret = 0;
+
+	if (open_proc_fd >= 0)
+		ret = close(open_proc_fd);
+
+	open_proc_fd = -1;
+	open_proc_pid = 0;
+
+	return ret;
+}
+
+inline int open_pid_proc(pid_t pid)
 {
 	char path[18];
 	int fd;
 
+	if (pid == open_proc_pid)
+		return open_proc_fd;
+
+	close_pid_proc();
 	sprintf(path, "/proc/%d", pid);
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
 		pr_perror("Can't open %s", path);
+	else {
+		open_proc_fd = fd;
+		open_proc_pid = pid;
+	}
+
 	return fd;
 }
 
-int do_open_proc(int dirfd, int flags, const char *fmt, ...)
+int do_open_proc(pid_t pid, int flags, const char *fmt, ...)
 {
 	char path[128];
 	va_list args;
+	int dirfd = open_pid_proc(pid);
+
+	if (dirfd < 0)
+		return -1;
 
 	va_start(args, fmt);
 	vsnprintf(path, sizeof(path), fmt, args);


More information about the CRIU mailing list