Commit a8607b12 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

cr-dump: create a transport socket only once

Before this patch a transport socket was created on-demand for each operation
requiring it. It will be problematic, when we start supporting net namespaces.
That said -- create a transport sockets and interconnect them early.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent f703f319
...@@ -19,6 +19,7 @@ struct parasite_ctl { ...@@ -19,6 +19,7 @@ struct parasite_ctl {
void * addr_cmd; /* addr for command */ void * addr_cmd; /* addr for command */
void * addr_args; /* address for arguments */ void * addr_args; /* address for arguments */
int tsock; /* transport socket for transfering fds */
}; };
struct cr_fdset; struct cr_fdset;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
enum { enum {
PARASITE_CMD_INIT, PARASITE_CMD_INIT,
PARASITE_CMD_TCONNECT,
PARASITE_CMD_SET_LOGFD, PARASITE_CMD_SET_LOGFD,
PARASITE_CMD_FINI, PARASITE_CMD_FINI,
......
...@@ -28,6 +28,7 @@ __NR_getitimer 36 sys_getitimer (int which, const struct itimerval *val) ...@@ -28,6 +28,7 @@ __NR_getitimer 36 sys_getitimer (int which, const struct itimerval *val)
__NR_setitimer 38 sys_setitimer (int which, const struct itimerval *val, struct itimerval *old) __NR_setitimer 38 sys_setitimer (int which, const struct itimerval *val, struct itimerval *old)
__NR_getpid 39 sys_getpid (void) __NR_getpid 39 sys_getpid (void)
__NR_socket 41 sys_socket (int domain, int type, int protocol) __NR_socket 41 sys_socket (int domain, int type, int protocol)
__NR_connect 42 sys_connect (int sockfd, struct sockaddr *addr, int addrlen)
__NR_sendmsg 46 sys_sendmsg (int sockfd, const struct msghdr *msg, int flags) __NR_sendmsg 46 sys_sendmsg (int sockfd, const struct msghdr *msg, int flags)
__NR_recvmsg 47 sys_recvmsg (int sockfd, struct msghdr *msg, int flags) __NR_recvmsg 47 sys_recvmsg (int sockfd, struct msghdr *msg, int flags)
__NR_bind 49 sys_bind (int sockfd, const struct sockaddr *addr, int addrlen) __NR_bind 49 sys_bind (int sockfd, const struct sockaddr *addr, int addrlen)
......
...@@ -326,26 +326,11 @@ static int gen_parasite_saddr(struct sockaddr_un *saddr, int key) ...@@ -326,26 +326,11 @@ static int gen_parasite_saddr(struct sockaddr_un *saddr, int key)
static int parasite_send_fd(struct parasite_ctl *ctl, int fd) static int parasite_send_fd(struct parasite_ctl *ctl, int fd)
{ {
struct sockaddr_un saddr; if (send_fd(ctl->tsock, NULL, 0, fd) < 0) {
int sun_len, ret = -1;
int sock;
sun_len = gen_parasite_saddr(&saddr, ctl->pid);
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if (sock < 0) {
pr_perror("Can't create socket");
return -1;
}
if (send_fd(sock, &saddr, sun_len, fd) < 0) {
pr_perror("Can't send file descriptor"); pr_perror("Can't send file descriptor");
goto out; return -1;
} }
ret = 0; return 0;
out:
close(sock);
return ret;
} }
static int parasite_prep_file(int fd, struct parasite_ctl *ctl) static int parasite_prep_file(int fd, struct parasite_ctl *ctl)
...@@ -413,6 +398,44 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid) ...@@ -413,6 +398,44 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid)
return 0; return 0;
} }
static int parasite_connect_tsocket(struct parasite_ctl *ctl)
{
struct parasite_init_args args = { };
struct sockaddr_un saddr;
int sun_len;
int sock;
sun_len = gen_parasite_saddr(&saddr, ctl->pid);
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if (sock < 0) {
pr_perror("Can't create socket");
return -1;
}
if (connect(sock, &saddr, sun_len) < 0) {
pr_perror("Can't connect a transport socket");
goto err;
}
args.sun_len = gen_parasite_saddr(&args.saddr, -getpid());
if (bind(sock, (struct sockaddr *)&args.saddr, args.sun_len) < 0) {
pr_perror("Can't bind socket");
goto err;
}
if (parasite_execute(PARASITE_CMD_TCONNECT, ctl,
&args, sizeof(args)) < 0)
goto err;
ctl->tsock = sock;
return 0;
err:
close(sock);
return -1;
}
int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid, int parasite_dump_thread_seized(struct parasite_ctl *ctl, pid_t pid,
unsigned int **tid_addr, u32 *tid) unsigned int **tid_addr, u32 *tid)
{ {
...@@ -536,28 +559,12 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int ...@@ -536,28 +559,12 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int
{ {
struct parasite_drain_fd *args; struct parasite_drain_fd *args;
int ret = -1; int ret = -1;
int sock;
args = xmalloc(sizeof(*args)); args = xmalloc(sizeof(*args));
if (!args) if (!args)
return -ENOMEM; return -ENOMEM;
args->sun_len = gen_parasite_saddr(&args->saddr, (int)-2u);
args->nr_fds = nr_fds; args->nr_fds = nr_fds;
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if (sock < 0) {
pr_perror("Can't create socket");
ret = sock;
goto out;
}
ret = bind(sock, (struct sockaddr *)&args->saddr, args->sun_len);
if (ret < 0) {
pr_perror("Can't bind socket");
goto err;
}
memcpy(&args->fds, fds, sizeof(int) * nr_fds); memcpy(&args->fds, fds, sizeof(int) * nr_fds);
ret = parasite_execute(PARASITE_CMD_DRAIN_FDS, ctl, args, sizeof(*args)); ret = parasite_execute(PARASITE_CMD_DRAIN_FDS, ctl, args, sizeof(*args));
...@@ -566,15 +573,13 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int ...@@ -566,15 +573,13 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int
goto err; goto err;
} }
ret = recv_fds(sock, lfds, nr_fds, flags); ret = recv_fds(ctl->tsock, lfds, nr_fds, flags);
if (ret) { if (ret) {
pr_err("Can't retrieve FDs from socket\n"); pr_err("Can't retrieve FDs from socket\n");
goto err; goto err;
} }
err: err:
close(sock);
out:
xfree(args); xfree(args);
return ret; return ret;
} }
...@@ -583,6 +588,9 @@ int parasite_cure_seized(struct parasite_ctl *ctl) ...@@ -583,6 +588,9 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
{ {
int ret = 0; int ret = 0;
if (ctl->tsock >= 0)
close(ctl->tsock);
if (ctl->parasite_ip) { if (ctl->parasite_ip) {
ctl->signals_blocked = 0; ctl->signals_blocked = 0;
parasite_execute(PARASITE_CMD_FINI, ctl, NULL, 0); parasite_execute(PARASITE_CMD_FINI, ctl, NULL, 0);
...@@ -632,6 +640,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are ...@@ -632,6 +640,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are
goto err; goto err;
} }
ctl->tsock = -1;
if (ptrace(PTRACE_GETREGS, pid, NULL, &ctl->regs_orig)) { if (ptrace(PTRACE_GETREGS, pid, NULL, &ctl->regs_orig)) {
pr_err("Can't obtain registers (pid: %d)\n", pid); pr_err("Can't obtain registers (pid: %d)\n", pid);
goto err; goto err;
...@@ -708,6 +718,12 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are ...@@ -708,6 +718,12 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are
ctl->signals_blocked = 1; ctl->signals_blocked = 1;
ret = parasite_connect_tsocket(ctl);
if (ret) {
pr_err("%d: Can't set connect\n", pid);
goto err_restore;
}
ret = parasite_set_logfd(ctl, pid); ret = parasite_set_logfd(ctl, pid);
if (ret) { if (ret) {
pr_err("%d: Can't set a logging descriptor\n", pid); pr_err("%d: Can't set a logging descriptor\n", pid);
......
...@@ -382,7 +382,7 @@ static int drain_fds(struct parasite_drain_fd *args) ...@@ -382,7 +382,7 @@ static int drain_fds(struct parasite_drain_fd *args)
{ {
int ret; int ret;
ret = send_fds(tsock, &args->saddr, args->sun_len, ret = send_fds(tsock, NULL, 0,
args->fds, args->nr_fds, true); args->fds, args->nr_fds, true);
if (ret) if (ret)
sys_write_msg("send_fds failed\n"); sys_write_msg("send_fds failed\n");
...@@ -417,6 +417,11 @@ static int init(struct parasite_init_args *args) ...@@ -417,6 +417,11 @@ static int init(struct parasite_init_args *args)
return ret; return ret;
} }
static int tconnect(struct parasite_init_args *args)
{
return sys_connect(tsock, (struct sockaddr *) &args->saddr, args->sun_len);
}
static int parasite_set_logfd() static int parasite_set_logfd()
{ {
int ret; int ret;
...@@ -452,6 +457,8 @@ int __used parasite_service(unsigned long cmd, void *args) ...@@ -452,6 +457,8 @@ int __used parasite_service(unsigned long cmd, void *args)
switch (cmd) { switch (cmd) {
case PARASITE_CMD_INIT: case PARASITE_CMD_INIT:
return init((struct parasite_init_args *) args); return init((struct parasite_init_args *) args);
case PARASITE_CMD_TCONNECT:
return tconnect((struct parasite_init_args *) args);
case PARASITE_CMD_FINI: case PARASITE_CMD_FINI:
return fini(); return fini();
case PARASITE_CMD_SET_LOGFD: case PARASITE_CMD_SET_LOGFD:
......
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