mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-20 01:54:28 +00:00
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: Yohei Kamitsukasa <uhoidx@gmail.com> Cc: Yohei Kamitsukasa <uhoidx@gmail.com> Signed-off-by: Andrew Vagin <avagin@virtuozzo.com> Reviewed-by: Dmitry Safonov <dsafonov@virtuozzo.com> Acked-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
7d95face06
commit
64e74fab05
4 changed files with 16 additions and 2 deletions
|
|
@ -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, ®s, &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();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue