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 {
void * addr_cmd; /* addr for command */
void * addr_args; /* address for arguments */
int tsock; /* transport socket for transfering fds */
};
struct cr_fdset;
......
......@@ -19,6 +19,7 @@
enum {
PARASITE_CMD_INIT,
PARASITE_CMD_TCONNECT,
PARASITE_CMD_SET_LOGFD,
PARASITE_CMD_FINI,
......
......@@ -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_getpid 39 sys_getpid (void)
__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_recvmsg 47 sys_recvmsg (int sockfd, struct msghdr *msg, int flags)
__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)
static int parasite_send_fd(struct parasite_ctl *ctl, int fd)
{
struct sockaddr_un saddr;
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) {
if (send_fd(ctl->tsock, NULL, 0, fd) < 0) {
pr_perror("Can't send file descriptor");
goto out;
return -1;
}
ret = 0;
out:
close(sock);
return ret;
return 0;
}
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)
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,
unsigned int **tid_addr, u32 *tid)
{
......@@ -536,28 +559,12 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl, int *fds, int *lfds, int
{
struct parasite_drain_fd *args;
int ret = -1;
int sock;
args = xmalloc(sizeof(*args));
if (!args)
return -ENOMEM;
args->sun_len = gen_parasite_saddr(&args->saddr, (int)-2u);
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);
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
goto err;
}
ret = recv_fds(sock, lfds, nr_fds, flags);
ret = recv_fds(ctl->tsock, lfds, nr_fds, flags);
if (ret) {
pr_err("Can't retrieve FDs from socket\n");
goto err;
}
err:
close(sock);
out:
xfree(args);
return ret;
}
......@@ -583,6 +588,9 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
{
int ret = 0;
if (ctl->tsock >= 0)
close(ctl->tsock);
if (ctl->parasite_ip) {
ctl->signals_blocked = 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
goto err;
}
ctl->tsock = -1;
if (ptrace(PTRACE_GETREGS, pid, NULL, &ctl->regs_orig)) {
pr_err("Can't obtain registers (pid: %d)\n", pid);
goto err;
......@@ -708,6 +718,12 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are
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);
if (ret) {
pr_err("%d: Can't set a logging descriptor\n", pid);
......
......@@ -382,7 +382,7 @@ static int drain_fds(struct parasite_drain_fd *args)
{
int ret;
ret = send_fds(tsock, &args->saddr, args->sun_len,
ret = send_fds(tsock, NULL, 0,
args->fds, args->nr_fds, true);
if (ret)
sys_write_msg("send_fds failed\n");
......@@ -417,6 +417,11 @@ static int init(struct parasite_init_args *args)
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()
{
int ret;
......@@ -452,6 +457,8 @@ int __used parasite_service(unsigned long cmd, void *args)
switch (cmd) {
case PARASITE_CMD_INIT:
return init((struct parasite_init_args *) args);
case PARASITE_CMD_TCONNECT:
return tconnect((struct parasite_init_args *) args);
case PARASITE_CMD_FINI:
return fini();
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