Commit 64e74fab authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

parasite: handle errors while a transport socket is being created

Currently if socket() or connect() syscall-s failed, parasite cures itself,
but criu has not got any signals and waits on accept().

This patch adds a futex to synchronize parasite and criu. The server socket
is created with SOCK_NONBLOCK and waits on the futex when a parasite
connects to it, only then criu calls accept() and it returns immediately.
Reported-by: 's avatarYohei Kamitsukasa <uhoidx@gmail.com>
Cc: Yohei Kamitsukasa <uhoidx@gmail.com>
Signed-off-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Reviewed-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 7d95face
......@@ -15,6 +15,7 @@
#include "image.h"
#include "util-pie.h"
#include "lock.h"
#include "images/vma.pb-c.h"
#include "images/tty.pb-c.h"
......@@ -72,6 +73,7 @@ struct parasite_init_args {
struct rt_sigframe *sigframe;
void *sigreturn_addr;
futex_t daemon_connected;
};
struct parasite_unmap_args {
......
......@@ -1678,7 +1678,7 @@ static int prep_ns_sockets(struct ns_id *ns, bool for_dump)
} else
ns->net.nlsk = -1;
ret = ns->net.seqsk = socket(PF_UNIX, SOCK_SEQPACKET, 0);
ret = ns->net.seqsk = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
if (ret < 0) {
pr_perror("Can't create seqsk for parasite");
goto err_sq;
......
......@@ -509,6 +509,8 @@ static int parasite_init_daemon(struct parasite_ctl *ctl, struct ns_id *net)
args->sigframe = ctl->rsigframe;
args->log_level = log_get_loglevel();
futex_set(&args->daemon_connected, 0);
if (prepare_tsock(ctl, pid, args, net))
goto err;
......@@ -520,6 +522,13 @@ static int parasite_init_daemon(struct parasite_ctl *ctl, struct ns_id *net)
if (parasite_run(pid, PTRACE_CONT, ctl->parasite_ip, ctl->rstack, &regs, &ctl->orig))
goto err;
futex_wait_while_eq(&args->daemon_connected, 0);
if (futex_get(&args->daemon_connected) != 1) {
errno = -(int)futex_get(&args->daemon_connected);
pr_perror("Unable to connect a transport socket");
goto err;
}
if (accept_tsock(ctl) < 0)
goto err;
......
......@@ -735,7 +735,7 @@ static noinline __used int parasite_init_daemon(void *data)
args->sigreturn_addr = fini_sigreturn;
sigframe = args->sigframe;
tsock = sys_socket(PF_UNIX, SOCK_SEQPACKET, 0);
ret = tsock = sys_socket(PF_UNIX, SOCK_SEQPACKET, 0);
if (tsock < 0) {
pr_err("Can't create socket: %d\n", tsock);
goto err;
......@@ -747,6 +747,8 @@ static noinline __used int parasite_init_daemon(void *data)
goto err;
}
futex_set_and_wake(&args->daemon_connected, 1);
ret = recv_fd(tsock);
if (ret >= 0) {
log_set_fd(ret);
......@@ -758,6 +760,7 @@ static noinline __used int parasite_init_daemon(void *data)
parasite_daemon(data);
err:
futex_set_and_wake(&args->daemon_connected, ret);
fini();
BUG();
......
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