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
This diff is collapsed.
......@@ -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;
......
......@@ -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_ */
......@@ -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__ */
......@@ -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) \
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
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