Commit 995ef5ec authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

Use openat() helper intensively when opening /proc/pid/X files

This allows us to get rid of open-coded "/proc/pid/X".

Based-on-patch-from: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent b0a95330
This diff is collapsed.
...@@ -1307,6 +1307,7 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1307,6 +1307,7 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
struct pstree_entry pstree_entry; struct pstree_entry pstree_entry;
int *fd_core_threads; int *fd_core_threads;
int fd_pstree = -1; int fd_pstree = -1;
int pid_dir;
pr_info("%d: Restore via sigreturn\n", pid); pr_info("%d: Restore via sigreturn\n", pid);
...@@ -1316,7 +1317,13 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -1316,7 +1317,13 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
restore_thread_vma_len = 0; restore_thread_vma_len = 0;
restore_shmem_vma_len = SHMEMS_SIZE; restore_shmem_vma_len = SHMEMS_SIZE;
if (parse_maps(getpid(), &self_vma_list, false)) pid_dir = open_pid_proc(pid);
if (pid_dir < 0)
goto err;
ret = parse_maps(getpid(), pid_dir, &self_vma_list, false);
close(pid_dir);
if (ret)
goto err; goto err;
/* pr_info_vma_list(&self_vma_list); */ /* pr_info_vma_list(&self_vma_list); */
......
#ifndef CR_SOCKETS_H__ #ifndef CR_SOCKETS_H__
#define CR_SOCKETS_H__ #define CR_SOCKETS_H__
#include <sys/types.h>
#include <unistd.h>
#include <stdbool.h> #include <stdbool.h>
struct cr_fdset; struct cr_fdset;
extern int try_dump_socket(char *dir_name, char *fd_name, struct cr_fdset *cr_fdset); extern int try_dump_socket(pid_t pid, char *fd_name, struct cr_fdset *cr_fdset);
extern int collect_sockets(void); extern int collect_sockets(void);
extern int prepare_sockets(int pid); extern int prepare_sockets(int pid);
......
...@@ -165,7 +165,7 @@ extern void printk_vma(struct vma_area *vma_area); ...@@ -165,7 +165,7 @@ extern void printk_vma(struct vma_area *vma_area);
#define pr_info_siginfo(siginfo) printk_siginfo(siginfo) #define pr_info_siginfo(siginfo) printk_siginfo(siginfo)
extern int move_img_fd(int *img_fd, int want_fd); extern int move_img_fd(int *img_fd, int want_fd);
extern int parse_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files); extern int parse_maps(pid_t pid, int pid_dir, struct list_head *vma_area_list, bool use_map_files);
extern int close_safe(int *fd); extern int close_safe(int *fd);
extern int reopen_fd_as_safe(int new_fd, int old_fd, bool allow_reuse_fd); extern int reopen_fd_as_safe(int new_fd, int old_fd, bool allow_reuse_fd);
...@@ -174,10 +174,10 @@ extern int reopen_fd_as_safe(int new_fd, int old_fd, bool allow_reuse_fd); ...@@ -174,10 +174,10 @@ 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);
extern DIR *opendir_proc(char *fmt, ...); int open_pid_proc(pid_t pid);
extern FILE *fopen_proc(char *fmt, char *mode, ...); int open_proc(int pid_dir_fd, char *fmt, ...);
extern FILE *fopen_fmt(char *fmt, char *mode, ...); DIR *opendir_proc(int pid_dir_fd, char *fmt, ...);
extern int open_fmt(char *fmt, int mode, ...); FILE *fopen_proc(int pid_dir_fd, char *fmt, ...);
#define __xalloc(op, size, ...) \ #define __xalloc(op, size, ...) \
({ \ ({ \
......
...@@ -175,13 +175,18 @@ err: ...@@ -175,13 +175,18 @@ err:
return -1; return -1;
} }
int try_dump_socket(char *dir, char *fd, struct cr_fdset *cr_fdset) int try_dump_socket(pid_t pid, char *fd, struct cr_fdset *cr_fdset)
{ {
struct socket_desc *sk; struct socket_desc *sk;
struct statfs fst; struct statfs fst;
struct stat st; struct stat st;
char path[64];
snprintf(buf, sizeof(buf), "%s/%s", dir, fd); /*
* Sockets are tricky, we can't open it but can
* do stats over and check for sokets magic.
*/
snprintf(buf, sizeof(buf), "/proc/%d/fd/%s", pid, fd);
if (statfs(buf, &fst)) { if (statfs(buf, &fst)) {
pr_err("Can't statfs %s\n", buf); pr_err("Can't statfs %s\n", buf);
return -1; return -1;
...@@ -206,8 +211,10 @@ int try_dump_socket(char *dir, char *fd, struct cr_fdset *cr_fdset) ...@@ -206,8 +211,10 @@ int try_dump_socket(char *dir, char *fd, struct cr_fdset *cr_fdset)
return dump_one_unix(sk, fd, cr_fdset); return dump_one_unix(sk, fd, cr_fdset);
default: default:
pr_err("BUG! Unknown socket collected\n"); pr_err("BUG! Unknown socket collected\n");
return -1; break;
} }
return -1;
} }
static int unix_collect_one(struct unix_diag_msg *m, struct rtattr **tb) static int unix_collect_one(struct unix_diag_msg *m, struct rtattr **tb)
......
...@@ -180,12 +180,11 @@ int move_img_fd(int *img_fd, int want_fd) ...@@ -180,12 +180,11 @@ int move_img_fd(int *img_fd, int want_fd)
return 0; return 0;
} }
int parse_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files) int parse_maps(pid_t pid, int pid_dir, 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;
char big_buffer[1024]; char big_buffer[1024];
char path[64];
unsigned long ino; unsigned long ino;
char r,w,x,s; char r,w,x,s;
int dev_maj, dev_min; int dev_maj, dev_min;
...@@ -194,18 +193,16 @@ int parse_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files) ...@@ -194,18 +193,16 @@ int parse_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files)
DIR *map_files_dir = NULL; DIR *map_files_dir = NULL;
FILE *maps = NULL; FILE *maps = NULL;
snprintf(path, sizeof(path), "/proc/%d/maps", pid); maps = fopen_proc(pid_dir, "maps");
maps = fopen(path, "r");
if (!maps) { if (!maps) {
pr_perror("Can't open: %s\n", path); pr_perror("Can't open %d's maps\n", pid);
goto err; goto err;
} }
if (use_map_files) { if (use_map_files) {
snprintf(path, sizeof(path), "/proc/%d/map_files", pid); map_files_dir = opendir_proc(pid_dir, "map_files");
map_files_dir = opendir(path);
if (!map_files_dir) { if (!map_files_dir) {
pr_err("Can't open %s, old kernel?\n", path); pr_err("Can't open %d's, old kernel?\n", pid);
goto err; goto err;
} }
} }
...@@ -227,6 +224,8 @@ int parse_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files) ...@@ -227,6 +224,8 @@ int parse_maps(pid_t pid, struct list_head *vma_area_list, bool use_map_files)
goto err; goto err;
if (map_files_dir) { if (map_files_dir) {
char path[32];
/* Figure out if it's file mapping */ /* Figure out if it's file mapping */
snprintf(path, sizeof(path), "%lx-%lx", start, end); snprintf(path, sizeof(path), "%lx-%lx", start, end);
...@@ -341,56 +340,6 @@ err_bogus_mapping: ...@@ -341,56 +340,6 @@ err_bogus_mapping:
goto err; goto err;
} }
DIR *opendir_proc(char *fmt, ...)
{
DIR *dir;
char path[128];
va_list args;
sprintf(path, "/proc/");
va_start(args, fmt);
vsnprintf(path + 6, sizeof(path) - 6, fmt, args);
va_end(args);
dir = opendir(path);
if (!dir)
pr_perror("Can't open %s\n", path);
return dir;
}
FILE *fopen_proc(char *fmt, char *mode, ...)
{
FILE *file;
char fname[128];
va_list args;
sprintf(fname, "/proc/");
va_start(args, mode);
vsnprintf(fname + 6, sizeof(fname) - 6, fmt, args);
va_end(args);
file = fopen(fname, mode);
if (!file)
pr_perror("Can't open %s\n", fname);
return file;
}
FILE *fopen_fmt(char *fmt, char *mode, ...)
{
FILE *file;
char fname[128];
va_list args;
va_start(args, mode);
vsnprintf(fname, sizeof(fname), fmt, args);
va_end(args);
file = fopen(fname, mode);
if (!file)
pr_perror("Can't open %s\n", fname);
return file;
}
int open_image_ro_nocheck(const char *fmt, int pid) int open_image_ro_nocheck(const char *fmt, int pid)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
...@@ -424,3 +373,54 @@ int open_image_ro(int type, int pid) ...@@ -424,3 +373,54 @@ int open_image_ro(int type, int pid)
return fd; return fd;
} }
int open_pid_proc(pid_t pid)
{
char path[18];
int fd;
sprintf(path, "/proc/%d", pid);
fd = open(path, O_RDONLY);
if (fd < 0)
pr_perror("Can't open %s\n", path);
return fd;
}
#define do_open_proc(pid_dir_fd, fmt) \
({ \
char fname[64]; \
va_list args; \
\
va_start(args, fmt); \
vsnprintf(fname, sizeof(fname), fmt, args); \
va_end(args); \
\
openat(pid_dir_fd, fname, O_RDONLY); \
})
int open_proc(int pid_dir_fd, char *fmt, ...)
{
return do_open_proc(pid_dir_fd, fmt);
}
DIR *opendir_proc(int pid_dir_fd, char *fmt, ...)
{
int dirfd;
dirfd = do_open_proc(pid_dir_fd, fmt);
if (dirfd >= 0)
return fdopendir(dirfd);
return NULL;
}
FILE *fopen_proc(int pid_dir_fd, char *fmt, ...)
{
int fd;
fd = do_open_proc(pid_dir_fd, fmt);
if (fd >= 0)
return fdopen(fd, "r");
return NULL;
}
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