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;
extern int parasite_drain_fds_seized(struct parasite_ctl *ctl,
struct parasite_drain_fd *dfds,
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 struct parasite_ctl *parasite_infect_seized(pid_t pid,
......
......@@ -31,6 +31,7 @@ enum {
PARASITE_CMD_DUMP_MISC,
PARASITE_CMD_DUMP_TID_ADDR,
PARASITE_CMD_DRAIN_FDS,
PARASITE_CMD_GET_PROC_FD,
PARASITE_CMD_MAX,
};
......
......@@ -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_fcntl 72 sys_fcntl (int fd, int type, long arg)
__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_readlink 89 sys_readlink (const char *path, char *buf, int bufsize)
__NR_setresuid 117 sys_setresuid (int uid, int euid, int suid)
__NR_setresgid 119 sys_setresgid (int gid, int egid, int sgid)
__NR_getpgid 121 sys_getpgid (void)
......@@ -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_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_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_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)
......
......@@ -623,6 +623,25 @@ err:
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 ret = 0;
......
#include <sys/mman.h>
#include <errno.h>
#include <signal.h>
#include <linux/limits.h>
#include <sys/mount.h>
#include "syscall.h"
#include "parasite.h"
......@@ -375,6 +377,58 @@ static int init(struct parasite_init_args *args)
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()
{
int ret;
......@@ -430,6 +484,8 @@ int __used parasite_service(unsigned long cmd, void *args)
return dump_tid_info((struct parasite_dump_tid_info *)args);
case PARASITE_CMD_DRAIN_FDS:
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");
......
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