Commit 447388d7 authored by Kir Kolyshkin's avatar Kir Kolyshkin Committed by Cyrill Gorcunov

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: 's avatarKir Kolyshkin <kir@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 5661d806
...@@ -65,7 +65,7 @@ void free_mappings(struct list_head *vma_area_list) ...@@ -65,7 +65,7 @@ void free_mappings(struct list_head *vma_area_list)
INIT_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; int ret = -1;
...@@ -73,7 +73,7 @@ static int collect_mappings(pid_t pid, int pid_dir, struct list_head *vma_area_l ...@@ -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("Collecting mappings (pid: %d)\n", pid);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
ret = parse_maps(pid, pid_dir, vma_area_list, true); ret = parse_maps(pid, vma_area_list, true);
if (ret) if (ret)
goto err; goto err;
...@@ -138,14 +138,14 @@ err: ...@@ -138,14 +138,14 @@ err:
return ret; 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; struct fd_parms params;
int fd, ret; int fd, ret;
/* Dump /proc/pid/cwd */ /* Dump /proc/pid/cwd */
params = (struct fd_parms){ .fd_name = FDINFO_CWD, }; params = (struct fd_parms){ .fd_name = FDINFO_CWD, };
fd = open_proc(pid, pid_dir, "cwd"); fd = open_proc(pid, "cwd");
if (fd < 0) if (fd < 0)
return -1; return -1;
ret = dump_one_reg_file(FDINFO_FD, &params, fd, cr_fdset, 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 ...@@ -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 */ /* Dump /proc/pid/exe */
params = (struct fd_parms){ .fd_name = FDINFO_EXE, }; params = (struct fd_parms){ .fd_name = FDINFO_EXE, };
fd = open_proc(pid, pid_dir, "exe"); fd = open_proc(pid, "exe");
if (fd < 0) if (fd < 0)
return -1; return -1;
ret = dump_one_reg_file(FDINFO_FD, &params, fd, cr_fdset, 1); ret = dump_one_reg_file(FDINFO_FD, &params, fd, cr_fdset, 1);
...@@ -302,12 +302,12 @@ out_close: ...@@ -302,12 +302,12 @@ out_close:
return err; 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; FILE *file;
int ret; int ret;
file = fopen_proc(pid, pid_dir, "fdinfo/%s", fd); file = fopen_proc(pid, "fdinfo/%s", fd);
if (!file) if (!file)
return -1; return -1;
...@@ -326,7 +326,7 @@ static int read_fd_params(pid_t pid, int pid_dir, char *fd, struct fd_parms *p) ...@@ -326,7 +326,7 @@ static int read_fd_params(pid_t pid, int pid_dir, char *fd, struct fd_parms *p)
return 0; 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; struct dirent *de;
unsigned long pos; unsigned long pos;
...@@ -342,12 +342,12 @@ static int dump_task_files(pid_t pid, int pid_dir, struct cr_fdset *cr_fdset) ...@@ -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 * to re-read them in restorer, so better to make it
* fast. * 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"); pr_err("Can't dump special files\n");
return -1; return -1;
} }
fd_dir = opendir_proc(pid, pid_dir, "fd"); fd_dir = opendir_proc(pid, "fd");
if (!fd_dir) if (!fd_dir)
return -1; return -1;
...@@ -358,7 +358,7 @@ static int dump_task_files(pid_t pid, int pid_dir, struct cr_fdset *cr_fdset) ...@@ -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] == '.') if (de->d_name[0] == '.')
continue; continue;
if (read_fd_params(pid, pid_dir, de->d_name, &p)) if (read_fd_params(pid, de->d_name, &p))
return -1; return -1;
lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY); lfd = openat(dirfd(fd_dir), de->d_name, O_RDONLY);
...@@ -436,7 +436,7 @@ err: ...@@ -436,7 +436,7 @@ err:
return ret; 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) struct parasite_dump_misc *misc, struct cr_fdset *fds)
{ {
int ret, i; int ret, i;
...@@ -447,7 +447,7 @@ static int dump_task_creds(pid_t pid, int pid_dir, ...@@ -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("Dumping creds for %d)\n", pid);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
ret = parse_pid_status(pid, pid_dir, &cr); ret = parse_pid_status(pid, &cr);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -481,7 +481,7 @@ static int dump_task_creds(pid_t pid, int pid_dir, ...@@ -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_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)) #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; FILE *file;
int ret = -1; int ret = -1;
...@@ -489,7 +489,7 @@ static int get_task_sigmask(pid_t pid, int pid_dir, u64 *task_sigset) ...@@ -489,7 +489,7 @@ static int get_task_sigmask(pid_t pid, int pid_dir, u64 *task_sigset)
/* /*
* Now signals. * Now signals.
*/ */
file = fopen_proc(pid, pid_dir, "status"); file = fopen_proc(pid, "status");
if (!file) if (!file)
goto err; goto err;
...@@ -507,9 +507,9 @@ err: ...@@ -507,9 +507,9 @@ err:
return ret; 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; int ret, i;
if (fd < 0) if (fd < 0)
...@@ -535,12 +535,12 @@ err: ...@@ -535,12 +535,12 @@ err:
return ret; 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; FILE *file = NULL;
int ret = -1; int ret = -1;
file = fopen_proc(pid, pid_dir, "personality"); file = fopen_proc(pid, "personality");
if (!file) if (!file)
goto err; goto err;
...@@ -657,7 +657,7 @@ static int dump_task_core(struct core_entry *core, struct cr_fdset *fdset) ...@@ -657,7 +657,7 @@ static int dump_task_core(struct core_entry *core, struct cr_fdset *fdset)
return ret; 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 parasite_dump_misc *misc, struct cr_fdset *cr_fdset)
{ {
struct core_entry *core = xzalloc(sizeof(*core)); 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 ...@@ -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("OK\n");
pr_info("Obtainting personality ... "); pr_info("Obtainting personality ... ");
ret = get_task_personality(pid, pid_dir, &core->tc.personality); ret = get_task_personality(pid, &core->tc.personality);
if (ret) if (ret)
goto err_free; goto err_free;
pr_info("OK\n"); 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 ...@@ -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; core->tc.mm_brk = misc->brk;
pr_info("Obtainting sigmask ... "); 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) if (ret)
goto err_free; goto err_free;
pr_info("OK\n"); pr_info("OK\n");
pr_info("Obtainting task auvx ... "); pr_info("Obtainting task auvx ... ");
ret = get_task_auxv(pid, pid_dir, core); ret = get_task_auxv(pid, core);
if (ret) if (ret)
goto err_free; goto err_free;
pr_info("OK\n"); pr_info("OK\n");
...@@ -724,14 +724,14 @@ err: ...@@ -724,14 +724,14 @@ err:
return ret; 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; struct dirent *de;
DIR *dir; DIR *dir;
u32 *t = NULL; u32 *t = NULL;
int nr = 1; int nr = 1;
dir = opendir_proc(pid, pid_dir, "task"); dir = opendir_proc(pid, "task");
if (!dir) if (!dir)
return -1; return -1;
...@@ -760,7 +760,7 @@ static int parse_threads(struct pstree_item *item, pid_t pid, int pid_dir) ...@@ -760,7 +760,7 @@ static int parse_threads(struct pstree_item *item, pid_t pid, int pid_dir)
return 0; 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; FILE *file;
char *tok; char *tok;
...@@ -769,7 +769,7 @@ static int parse_children(struct pstree_item *item, pid_t pid, int pid_dir) ...@@ -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++) { 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) if (!file)
goto err; goto err;
...@@ -864,7 +864,7 @@ err: ...@@ -864,7 +864,7 @@ err:
static struct pstree_item *collect_task(pid_t pid, struct list_head *list) static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
{ {
int ret, pid_dir; int ret;
struct pstree_item *item; struct pstree_item *item;
item = xzalloc(sizeof(*item)); item = xzalloc(sizeof(*item));
...@@ -879,14 +879,10 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list) ...@@ -879,14 +879,10 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
item->pid = pid; item->pid = pid;
item->state = ret; item->state = ret;
pid_dir = open_pid_proc(pid);
if (pid_dir < 0)
goto err_free;
if (item->state == TASK_SHOULD_BE_DEAD) { if (item->state == TASK_SHOULD_BE_DEAD) {
struct proc_pid_stat_small ps; 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) if (ret < 0)
goto err_close; goto err_close;
...@@ -899,7 +895,7 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list) ...@@ -899,7 +895,7 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
item->state = TASK_DEAD; item->state = TASK_DEAD;
} }
ret = parse_threads(item, pid, pid_dir); ret = parse_threads(item, pid);
if (ret < 0) if (ret < 0)
goto err_close; goto err_close;
...@@ -907,7 +903,7 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list) ...@@ -907,7 +903,7 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
if (ret < 0) if (ret < 0)
goto err_close; goto err_close;
ret = parse_children(item, pid, pid_dir); ret = parse_children(item, pid);
if (ret < 0) if (ret < 0)
goto err_close; goto err_close;
...@@ -916,13 +912,13 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list) ...@@ -916,13 +912,13 @@ static struct pstree_item *collect_task(pid_t pid, struct list_head *list)
goto err_close; goto err_close;
} }
close(pid_dir); close_pid_proc();
list_add_tail(&item->list, list); list_add_tail(&item->list, list);
pr_info("Collected %d in %d state\n", item->pid, item->state); pr_info("Collected %d in %d state\n", item->pid, item->state);
return item; return item;
err_close: err_close:
close(pid_dir); close_pid_proc();
err_free: err_free:
xfree(item->children); xfree(item->children);
xfree(item->threads); xfree(item->threads);
...@@ -1149,7 +1145,6 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset) ...@@ -1149,7 +1145,6 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
LIST_HEAD(vma_area_list); LIST_HEAD(vma_area_list);
struct parasite_ctl *parasite_ctl; struct parasite_ctl *parasite_ctl;
int ret = -1; int ret = -1;
int pid_dir;
struct parasite_dump_misc misc; struct parasite_dump_misc misc;
pr_info("========================================\n"); pr_info("========================================\n");
...@@ -1161,14 +1156,8 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset) ...@@ -1161,14 +1156,8 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
goto err_free; 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 ... "); pr_info("Obtainting task stat ... ");
ret = parse_pid_stat(pid, pid_dir, &pps_buf); ret = parse_pid_stat(pid, &pps_buf);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -1179,13 +1168,13 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset) ...@@ -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)) if (!cr_dump_fdset_open(item->pid, CR_FD_DESC_TASK, cr_fdset))
goto err; goto err;
ret = collect_mappings(pid, pid_dir, &vma_area_list); ret = collect_mappings(pid, &vma_area_list);
if (ret) { if (ret) {
pr_err("Collect mappings (pid: %d) failed with %d\n", pid, ret); pr_err("Collect mappings (pid: %d) failed with %d\n", pid, ret);
goto err; 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) { if (!parasite_ctl) {
pr_err("Can't infect (pid: %d) with parasite\n", pid); pr_err("Can't infect (pid: %d) with parasite\n", pid);
goto err; goto err;
...@@ -1221,7 +1210,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset) ...@@ -1221,7 +1210,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
goto err; goto err;
} }
ret = dump_task_files(pid, pid_dir, cr_fdset); ret = dump_task_files(pid, cr_fdset);
if (ret) { if (ret) {
pr_err("Dump files (pid: %d) failed with %d\n", pid, ret); pr_err("Dump files (pid: %d) failed with %d\n", pid, ret);
goto err; goto err;
...@@ -1233,13 +1222,13 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset) ...@@ -1233,13 +1222,13 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
goto err; goto err;
} }
ret = dump_task_creds(pid, pid_dir, &misc, cr_fdset); ret = dump_task_creds(pid, &misc, cr_fdset);
if (ret) { if (ret) {
pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret); pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
goto err; 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) { if (ret) {
pr_err("Dump core (pid: %d) failed with %d\n", pid, ret); pr_err("Dump core (pid: %d) failed with %d\n", pid, ret);
goto err; goto err;
...@@ -1256,7 +1245,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset) ...@@ -1256,7 +1245,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
ret = dump_task_threads(item); ret = dump_task_threads(item);
err: err:
close(pid_dir); close_pid_proc();
err_free: err_free:
free_mappings(&vma_area_list); free_mappings(&vma_area_list);
return ret; return ret;
......
...@@ -1639,7 +1639,6 @@ static void sigreturn_restore(pid_t pid) ...@@ -1639,7 +1639,6 @@ static void sigreturn_restore(pid_t pid)
int num, i; int num, i;
int *fd_core_threads; int *fd_core_threads;
int pid_dir;
pr_info("%d: Restore via sigreturn\n", pid); pr_info("%d: Restore via sigreturn\n", pid);
...@@ -1647,12 +1646,8 @@ static void sigreturn_restore(pid_t pid) ...@@ -1647,12 +1646,8 @@ static void sigreturn_restore(pid_t pid)
restore_task_vma_len = 0; restore_task_vma_len = 0;
restore_thread_vma_len = 0; restore_thread_vma_len = 0;
pid_dir = open_pid_proc(pid); ret = parse_maps(pid, &self_vma_list, false);
if (pid_dir < 0) close_pid_proc();
goto err;
ret = parse_maps(pid, pid_dir, &self_vma_list, false);
close(pid_dir);
if (ret) if (ret)
goto err; goto err;
......
...@@ -37,7 +37,7 @@ extern int parasite_dump_pages_seized(struct parasite_ctl *ctl, ...@@ -37,7 +37,7 @@ extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
struct list_head *vma_area_list, struct list_head *vma_area_list,
struct cr_fdset *cr_fdset); struct cr_fdset *cr_fdset);
extern int parasite_cure_seized(struct parasite_ctl *ctl); 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); struct list_head *vma_area_list);
#endif /* PARASITE_SYSCALL_H_ */ #endif /* PARASITE_SYSCALL_H_ */
...@@ -77,9 +77,9 @@ struct proc_status_creds { ...@@ -77,9 +77,9 @@ struct proc_status_creds {
unsigned int cap_bnd[PROC_CAP_SIZE]; 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(pid_t pid, 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_pid_stat_small(pid_t pid, 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_maps(pid_t pid, 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_status(pid_t pid, struct proc_status_creds *);
#endif /* PROC_PARSE_H__ */ #endif /* PROC_PARSE_H__ */
...@@ -205,11 +205,13 @@ extern int reopen_fd_as_safe(int new_fd, int old_fd, bool allow_reuse_fd); ...@@ -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); extern void hex_dump(void *addr, unsigned long len);
int open_pid_proc(pid_t pid); 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__); \ fmt, ##__VA_ARGS__); \
if (__fd < 0) \ if (__fd < 0) \
pr_perror("Can't open /proc/%d/" fmt, \ pr_perror("Can't open /proc/%d/" fmt, \
...@@ -218,18 +220,18 @@ int do_open_proc(int pid_dir, int flags, const char *fmt, ...); ...@@ -218,18 +220,18 @@ int do_open_proc(int pid_dir, int flags, const char *fmt, ...);
__fd; \ __fd; \
}) })
/* int open_proc(pid_t pid, int pid_dir, const char *fmt, ...); */ /* int open_proc(pid_t pid, const char *fmt, ...); */
#define open_proc(pid, pid_dir, fmt, ...) \ #define open_proc(pid, fmt, ...) \
__open_proc(pid, pid_dir, O_RDONLY, fmt, ##__VA_ARGS__) __open_proc(pid, O_RDONLY, fmt, ##__VA_ARGS__)
/* int open_proc_rw(pid_t pid, int pid_dir, const char *fmt, ...); */ /* int open_proc_rw(pid_t pid, const char *fmt, ...); */
#define open_proc_rw(pid, pid_dir, fmt, ...) \ #define open_proc_rw(pid, fmt, ...) \
__open_proc(pid, pid_dir, O_RDWR, fmt, ##__VA_ARGS__) __open_proc(pid, O_RDWR, fmt, ##__VA_ARGS__)
/* DIR *opendir_proc(pid_t pid, int pid_dir, const char *fmt, ...); */ /* DIR *opendir_proc(pid_t pid, const char *fmt, ...); */
#define opendir_proc(pid, pid_dir, 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; \ DIR *__d = NULL; \
\ \
if (__fd >= 0) \ if (__fd >= 0) \
...@@ -242,10 +244,10 @@ int do_open_proc(int pid_dir, int flags, const char *fmt, ...); ...@@ -242,10 +244,10 @@ int do_open_proc(int pid_dir, int flags, const char *fmt, ...);
__d; \ __d; \
}) })
/* FILE *fopen_proc(pid_t pid, int pid_dir, const char *fmt, ...); */ /* FILE *fopen_proc(pid_t pid, const char *fmt, ...); */
#define fopen_proc(pid, pid_dir, 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; \ FILE *__f = NULL; \
\ \
if (__fd >= 0) \ if (__fd >= 0) \
......
...@@ -560,7 +560,7 @@ int parasite_cure_seized(struct parasite_ctl *ctl) ...@@ -560,7 +560,7 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
return ret; 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 parasite_ctl *ctl = NULL;
struct vma_area *vma_area; struct vma_area *vma_area;
...@@ -620,12 +620,10 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_ ...@@ -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); 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); ctl->remote_map, ctl->remote_map + ctl->map_length);
if (fd < 0) { if (fd < 0)
pr_perror("Can't open remote parasite map");
goto err_restore; goto err_restore;
}
ctl->local_map = mmap(NULL, parasite_size, PROT_READ | PROT_WRITE, ctl->local_map = mmap(NULL, parasite_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FILE, fd, 0); MAP_SHARED | MAP_FILE, fd, 0);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include "proc_parse.h" #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; struct vma_area *vma_area = NULL;
u64 start, end, pgoff; 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 ...@@ -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; DIR *map_files_dir = NULL;
FILE *maps = NULL; FILE *maps = NULL;
maps = fopen_proc(pid, pid_dir, "maps"); maps = fopen_proc(pid, "maps");
if (!maps) if (!maps)
goto err; goto err;
if (use_map_files) { 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? */ if (!map_files_dir) /* old kernel? */
goto err; goto err;
} }
...@@ -179,13 +179,13 @@ err_bogus_mapping: ...@@ -179,13 +179,13 @@ err_bogus_mapping:
goto err; 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; FILE *f;
char *tok; char *tok;
int n; int n;
f = fopen_proc(pid, pid_dir, "stat"); f = fopen_proc(pid, "stat");
if (f == NULL) if (f == NULL)
return -1; return -1;
...@@ -207,13 +207,13 @@ int parse_pid_stat_small(pid_t pid, int pid_dir, struct proc_pid_stat_small *s) ...@@ -207,13 +207,13 @@ int parse_pid_stat_small(pid_t pid, int pid_dir, struct proc_pid_stat_small *s)
return 0; 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; FILE *f;
char *tok; char *tok;
int n; int n;
f = fopen_proc(pid, pid_dir, "stat"); f = fopen_proc(pid, "stat");
if (f == NULL) if (f == NULL)
return -1; return -1;
...@@ -318,13 +318,13 @@ static int cap_parse(char *str, unsigned int *res) ...@@ -318,13 +318,13 @@ static int cap_parse(char *str, unsigned int *res)
return 0; 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; int done = 0;
FILE *f; FILE *f;
char str[64]; char str[64];
f = fopen_proc(pid, pid_dir, "status"); f = fopen_proc(pid, "status");
if (f == NULL) { if (f == NULL) {
pr_perror("Can't open proc status"); pr_perror("Can't open proc status");
return -1; return -1;
......
...@@ -205,22 +205,51 @@ int open_image_ro(int type, int pid) ...@@ -205,22 +205,51 @@ int open_image_ro(int type, int pid)
return fd; 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]; char path[18];
int fd; int fd;
if (pid == open_proc_pid)
return open_proc_fd;
close_pid_proc();
sprintf(path, "/proc/%d", pid); sprintf(path, "/proc/%d", pid);
fd = open(path, O_RDONLY); fd = open(path, O_RDONLY);
if (fd < 0) if (fd < 0)
pr_perror("Can't open %s", path); pr_perror("Can't open %s", path);
else {
open_proc_fd = fd;
open_proc_pid = pid;
}
return fd; 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]; char path[128];
va_list args; va_list args;
int dirfd = open_pid_proc(pid);
if (dirfd < 0)
return -1;
va_start(args, fmt); va_start(args, fmt);
vsnprintf(path, sizeof(path), fmt, args); vsnprintf(path, sizeof(path), fmt, args);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment