[CRIU] [PATCH 2/3] compel: Improve infect
Pavel Emelyanov
xemul at virtuozzo.com
Thu Nov 24 03:49:52 PST 2016
On 11/23/2016 06:33 PM, Cyrill Gorcunov wrote:
> - extend handle_sigchld
> - fix garbage return in compel_prepare
> - handle errors in make_sock_for
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> compel/src/lib/infect.c | 62 ++++++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 49 insertions(+), 13 deletions(-)
>
> diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
> index b88449efd876..de6ffbab7203 100644
> --- a/compel/src/lib/infect.c
> +++ b/compel/src/lib/infect.c
> @@ -1019,31 +1019,46 @@ out:
> */
> static int make_sock_for(int pid)
> {
> - int ret = -1;
> - int mfd, fd;
> + int ret, mfd, fd, sk = -1;
> char p[32];
>
> + pr_debug("Preparing seqsk for %d\n", pid);
> +
> sprintf(p, "/proc/%d/ns/net", pid);
> fd = open(p, O_RDONLY);
> - if (fd < 0)
> + if (fd < 0) {
> + pr_perror("Can't open %p", p);
> goto out;
> + }
>
> mfd = open("/proc/self/ns/net", O_RDONLY);
> - if (mfd < 0)
> + if (mfd < 0) {
> + pr_perror("Can't open self netns");
> goto out_c;
> + }
>
> - if (setns(fd, CLONE_NEWNET))
> + if (setns(fd, CLONE_NEWNET)) {
> + pr_perror("Can't setup target netns");
> goto out_cm;
> + }
>
> - ret = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
> + sk = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
> + if (sk < 0)
> + pr_perror("Can't create seqsk");
>
> - setns(mfd, CLONE_NEWNET);
> + ret = setns(mfd, CLONE_NEWNET);
> + if (ret) {
> + pr_perror("Can't restore former netns");
> + if (sk >= 0)
> + close(sk);
> + sk = -1;
> + }
> out_cm:
> close(mfd);
> out_c:
> close(fd);
> out:
> - return ret;
> + return sk;
> }
>
> static int simple_open_proc(int pid, int mode, const char *fmt, ...)
> @@ -1063,10 +1078,25 @@ static int simple_open_proc(int pid, int mode, const char *fmt, ...)
>
> static void handle_sigchld(int signal, siginfo_t *siginfo, void *data)
> {
> - int status;
> + int pid, status;
> +
> + pid = waitpid(-1, &status, WNOHANG);
> + if (pid <= 0)
> + return;
> +
> + pr_err("si_code=%d si_pid=%d si_status=%d\n",
> + siginfo->si_code, siginfo->si_pid, siginfo->si_status);
>
> - waitpid(-1, &status, WNOHANG);
> - /* FIXME -- what to do here? */
> + if (WIFEXITED(status))
> + pr_err("%d exited with %d unexpectedly\n", pid, WEXITSTATUS(status));
> + else if (WIFSIGNALED(status))
> + pr_err("%d was killed by %d unexpectedly: %s\n",
> + pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
> + else if (WIFSTOPPED(status))
> + pr_err("%d was stopped by %d unexpectedly\n", pid, WSTOPSIG(status));
> +
> + /* FIXME Should we exit? */
> + /* exit(1); */
> }
>
> struct plain_regs_struct {
> @@ -1135,6 +1165,10 @@ struct parasite_ctl *compel_prepare(int pid)
> ictx->open_proc = simple_open_proc;
> ictx->syscall_ip = find_executable_area(pid);
> ictx->child_handler = handle_sigchld;
> + ictx->orig_handler.sa_handler = SIG_DFL;
> + ictx->orig_handler.sa_flags = SA_SIGINFO | SA_RESTART;
> + sigemptyset(&ictx->orig_handler.sa_mask);
> + sigaddset(&ictx->orig_handler.sa_mask, SIGCHLD);
> sigaction(SIGCHLD, NULL, &ictx->orig_handler);
Isn't sigaction() not enough to fill in the orig_handler?
>
> ictx->save_regs = save_regs_plain;
> @@ -1145,6 +1179,7 @@ struct parasite_ctl *compel_prepare(int pid)
>
> if (ictx->syscall_ip == (unsigned long)MAP_FAILED)
> goto err;
> + pr_debug("Parasite syscall_ip at %#lx\n", ictx->syscall_ip);
> ictx->sock = make_sock_for(pid);
> if (ictx->sock < 0)
> goto err;
> @@ -1153,8 +1188,9 @@ out:
> return ctl;
>
> err:
> - free(ictx->regs_arg);
> - free(ctl);
> + xfree(ictx->regs_arg);
> + xfree(ctl);
> + ctl = NULL;
> goto out;
> }
>
>
More information about the CRIU
mailing list