Commit 5c171b13 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

parasite: get a file descriptor for procfs from a target pidns (v2)

It will be used for dumping zombies.

v2: Add a fast path, if /proc belongs to the target pipns. it's usually for CT.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 760994c6
...@@ -42,6 +42,7 @@ struct fd_opts; ...@@ -42,6 +42,7 @@ struct fd_opts;
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl, extern int parasite_drain_fds_seized(struct parasite_ctl *ctl,
struct parasite_drain_fd *dfds, struct parasite_drain_fd *dfds,
int *lfds, struct fd_opts *flags); int *lfds, struct fd_opts *flags);
extern int parasite_get_proc_fd_seized(struct parasite_ctl *ctl);
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, extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
......
...@@ -31,6 +31,7 @@ enum { ...@@ -31,6 +31,7 @@ enum {
PARASITE_CMD_DUMP_MISC, PARASITE_CMD_DUMP_MISC,
PARASITE_CMD_DUMP_TID_ADDR, PARASITE_CMD_DUMP_TID_ADDR,
PARASITE_CMD_DRAIN_FDS, PARASITE_CMD_DRAIN_FDS,
PARASITE_CMD_GET_PROC_FD,
PARASITE_CMD_MAX, PARASITE_CMD_MAX,
}; };
......
...@@ -40,7 +40,10 @@ __NR_wait4 61 sys_waitpid (int pid, int *status, int options, struct rusage * ...@@ -40,7 +40,10 @@ __NR_wait4 61 sys_waitpid (int pid, int *status, int options, struct rusage *
__NR_kill 62 sys_kill (long pid, int sig) __NR_kill 62 sys_kill (long pid, int sig)
__NR_fcntl 72 sys_fcntl (int fd, int type, long arg) __NR_fcntl 72 sys_fcntl (int fd, int type, long arg)
__NR_flock 73 sys_flock (int fd, unsigned long cmd) __NR_flock 73 sys_flock (int fd, unsigned long cmd)
__NR_mkdir 83 sys_mkdir (const char *name, int mode)
__NR_rmdir 84 sys_rmdir (const char *name)
__NR_unlink 87 sys_unlink (char *pathname) __NR_unlink 87 sys_unlink (char *pathname)
__NR_readlink 89 sys_readlink (const char *path, char *buf, int bufsize)
__NR_setresuid 117 sys_setresuid (int uid, int euid, int suid) __NR_setresuid 117 sys_setresuid (int uid, int euid, int suid)
__NR_setresgid 119 sys_setresgid (int gid, int egid, int sgid) __NR_setresgid 119 sys_setresgid (int gid, int egid, int sgid)
__NR_getpgid 121 sys_getpgid (void) __NR_getpgid 121 sys_getpgid (void)
...@@ -51,6 +54,8 @@ __NR_capset 126 sys_capset (struct cap_header *h, struct cap_data *d) ...@@ -51,6 +54,8 @@ __NR_capset 126 sys_capset (struct cap_header *h, struct cap_data *d)
__NR_personality 135 sys_personality (unsigned int personality) __NR_personality 135 sys_personality (unsigned int personality)
__NR_prctl 157 sys_prctl (int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) __NR_prctl 157 sys_prctl (int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
__NR_arch_prctl 158 sys_arch_prctl (int option, unsigned long addr) __NR_arch_prctl 158 sys_arch_prctl (int option, unsigned long addr)
__NR_mount 165 sys_mount (char *dev_nmae, char *dir_name, char *type, unsigned long flags, void *data)
__NR_umount2 166 sys_umount2 (char *name, int flags)
__NR_gettid 186 sys_gettid (void) __NR_gettid 186 sys_gettid (void)
__NR_futex 202 sys_futex (u32 *uaddr, int op, u32 val, struct timespec *utime, u32 *uaddr2, u32 val3) __NR_futex 202 sys_futex (u32 *uaddr, int op, u32 val, struct timespec *utime, u32 *uaddr2, u32 val3)
__NR_set_thread_area 205 sys_set_thread_area (user_desc_t *info) __NR_set_thread_area 205 sys_set_thread_area (user_desc_t *info)
......
...@@ -623,6 +623,25 @@ err: ...@@ -623,6 +623,25 @@ err:
return ret; return ret;
} }
int parasite_get_proc_fd_seized(struct parasite_ctl *ctl)
{
int ret = -1, fd;
ret = parasite_execute(PARASITE_CMD_GET_PROC_FD, ctl, NULL, 0);
if (ret) {
pr_err("Parasite failed to get proc fd\n");
return ret;
}
fd = recv_fd(ctl->tsock);
if (fd < 0) {
pr_err("Can't retrieve FD from socket\n");
return fd;
}
return fd;
}
int parasite_cure_seized(struct parasite_ctl *ctl) int parasite_cure_seized(struct parasite_ctl *ctl)
{ {
int ret = 0; int ret = 0;
......
#include <sys/mman.h> #include <sys/mman.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <linux/limits.h>
#include <sys/mount.h>
#include "syscall.h" #include "syscall.h"
#include "parasite.h" #include "parasite.h"
...@@ -375,6 +377,58 @@ static int init(struct parasite_init_args *args) ...@@ -375,6 +377,58 @@ static int init(struct parasite_init_args *args)
return ret; return ret;
} }
static char proc_mountpoint[] = "proc.crtools";
static int parasite_get_proc_fd()
{
int ret, fd;
char buf[2];
ret = sys_readlink("/proc/self", buf, sizeof(buf));
if (ret < 0 && ret != -ENOENT) {
sys_write_msg("Can't readlink /proc/self\n");
return ret;
}
/* Fast path -- if /proc belongs to this pidns */
if (ret == 1 && buf[0] == '1') {
fd = sys_open("/proc", O_RDONLY, 0);
goto out_send_fd;
}
if (sys_mkdir(proc_mountpoint, 0700)) {
sys_write_msg("Can't create a directory ");
sys_write_msg(proc_mountpoint);
sys_write_msg("\n");
return ret;
}
if (sys_mount("proc", proc_mountpoint, "proc", MS_MGC_VAL, NULL)) {
sys_write_msg("mount failed\n");
ret = -1;
goto out_rmdir;
}
fd = sys_open(proc_mountpoint, O_RDONLY, 0);
if (sys_umount2(proc_mountpoint, MNT_DETACH)) {
sys_write_msg("Can't umount procfs\n");
return -1;
}
out_rmdir:
if (sys_rmdir(proc_mountpoint)) {
sys_write_msg("Can't remove directory\n");
return -1;
}
out_send_fd:
if (fd < 0)
return fd;
ret = send_fd(tsock, NULL, 0, fd);
sys_close(fd);
return ret;
}
static int parasite_set_logfd() static int parasite_set_logfd()
{ {
int ret; int ret;
...@@ -430,6 +484,8 @@ int __used parasite_service(unsigned long cmd, void *args) ...@@ -430,6 +484,8 @@ int __used parasite_service(unsigned long cmd, void *args)
return dump_tid_info((struct parasite_dump_tid_info *)args); return dump_tid_info((struct parasite_dump_tid_info *)args);
case PARASITE_CMD_DRAIN_FDS: case PARASITE_CMD_DRAIN_FDS:
return drain_fds((struct parasite_drain_fd *)args); return drain_fds((struct parasite_drain_fd *)args);
case PARASITE_CMD_GET_PROC_FD:
return parasite_get_proc_fd();
} }
sys_write_msg("Unknown command to parasite\n"); sys_write_msg("Unknown command to parasite\n");
......
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