diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 12f13aea8..dd9fb89a3 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -267,10 +267,6 @@ static int root_prepare_shared(void) if (ret) goto err; - ret = open_transport_socket(); - if (ret) - goto err; - show_saved_files(); err: return ret; @@ -607,8 +603,6 @@ static int restore_one_alive_task(int pid, CoreEntry *core) if (prepare_vmas(current, ta)) return -1; - close_service_fd(TRANSPORT_FD_OFF); - return sigreturn_restore(pid, ta, args_len, core); } @@ -1349,6 +1343,9 @@ static int restore_task_with_children(void *_arg) fini_restore_mntns(); } + if (open_transport_socket()) + return -1; + if (restore_finish_stage(task_entries, CR_STATE_FORKING) < 0) goto err; diff --git a/criu/files.c b/criu/files.c index 21af891e9..12cc88df8 100644 --- a/criu/files.c +++ b/criu/files.c @@ -1229,6 +1229,7 @@ int prepare_fds(struct pstree_item *me) break; } out_w: + close_service_fd(TRANSPORT_FD_OFF); if (rsti(me)->fdt) futex_inc_and_wake(&rsti(me)->fdt->fdt_lock); out: @@ -1663,15 +1664,28 @@ int inherit_fd_fini() return 0; } -int open_transport_socket() +int open_transport_socket(void) { - int sock; + struct fdt *fdt = rsti(current)->fdt; + pid_t pid = current->pid.virt; + struct sockaddr_un saddr; + int sock, slen; + + if (!task_alive(current) || (fdt && fdt->pid != pid)) + return 0; sock = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sock < 0) { pr_perror("Can't create socket"); return -1; } + + transport_name_gen(&saddr, &slen, pid, -1); + if (bind(sock, (struct sockaddr *)&saddr, slen) < 0) { + pr_perror("Can't bind transport socket %s", saddr.sun_path + 1); + return -1; + } + if (install_service_fd(TRANSPORT_FD_OFF, sock) < 0) { close(sock); return -1; diff --git a/criu/util.c b/criu/util.c index 6ba787edd..2108d6045 100644 --- a/criu/util.c +++ b/criu/util.c @@ -484,6 +484,9 @@ int clone_service_fd(int id) int old = __get_service_fd(i, service_fd_id); int new = __get_service_fd(i, id); + /* Do not dup parent's transport fd */ + if (i == TRANSPORT_FD_OFF) + continue; ret = dup2(old, new); if (ret == -1) { if (errno == EBADF)