[CRIU] [PATCH v5 06/42] cr-restore: Open transport socket earlier

Kirill Tkhai ktkhai at virtuozzo.com
Fri May 5 09:13:23 PDT 2017


I need named socket to communicate with pid_ns helpers
(see next patches) and receive answer from them
(it's impossible to send answer to unnamed socket).
As we already have transport socket, we'll reuse it
for the above goal too.

This patch makes transport sockets be created before
creation of children tasks. Also, now they are created
not only for alive tasks (so we need additional
manipulations for TASK_HELPERS, e.g., to call prepare_fdt()).

v5: Return CLONE_FILES clone() argument during task helpers
creation. Also get rid of fdt_mutex as CLONE_FILES processes
does not close old files after clone, and we don't have
intertersections between them. Also, socket() system call
can't return a fd in service fds range, which was the main
reason to have this mutex.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/cr-restore.c |   25 ++++++++++++++++---------
 criu/files.c      |   17 +++++++----------
 criu/pstree.c     |    2 ++
 3 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index f3f5f6731..e29f66824 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1036,7 +1036,7 @@ static int check_core(CoreEntry *core, struct pstree_item *me)
 
 static int restore_one_task(int pid, CoreEntry *core)
 {
-	int ret;
+	int i, ret;
 
 	/* No more fork()-s => no more per-pid logs */
 
@@ -1047,6 +1047,9 @@ static int restore_one_task(int pid, CoreEntry *core)
 	else if (current->pid->state == TASK_HELPER) {
 		sigset_t blockmask, oldmask;
 
+		if (prepare_fds(current))
+			return -1;
+
 		sigemptyset(&blockmask);
 		sigaddset(&blockmask, SIGCHLD);
 
@@ -1056,6 +1059,12 @@ static int restore_one_task(int pid, CoreEntry *core)
 		}
 
 		restore_finish_stage(task_entries, CR_STATE_RESTORE);
+
+		close_image_dir();
+		close_proc();
+		for (i = SERVICE_FD_MIN + 1; i < SERVICE_FD_MAX; i++)
+			close_service_fd(i);
+
 		if (wait_on_helpers_zombies()) {
 			pr_err("failed to wait on helpers and zombies\n");
 			ret = -1;
@@ -1492,11 +1501,9 @@ static int restore_task_with_children(void *_arg)
 	if ( !(ca->clone_flags & CLONE_FILES))
 		close_safe(&ca->fd);
 
-	if (current->pid->state != TASK_HELPER) {
-		ret = clone_service_fd(rsti(current)->service_fd_id);
-		if (ret)
-			goto err;
-	}
+	ret = clone_service_fd(rsti(current)->service_fd_id);
+	if (ret)
+		goto err;
 
 	pid = getpid();
 	if (vpid(current) != pid) {
@@ -1585,6 +1592,9 @@ static int restore_task_with_children(void *_arg)
 		BUG();
 	}
 
+	if (open_transport_socket())
+		goto err;
+
 	timing_start(TIME_FORK);
 
 	if (create_children_and_session())
@@ -1597,9 +1607,6 @@ static int restore_task_with_children(void *_arg)
 
 	restore_pgid();
 
-	if (open_transport_socket())
-		return -1;
-
 	if (current->parent == NULL) {
 		/*
 		 * Wait when all tasks passed the CR_STATE_FORKING stage.
diff --git a/criu/files.c b/criu/files.c
index 5c2001469..6a3e26a66 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -1631,32 +1631,29 @@ int inherit_fd_fini()
 
 int open_transport_socket(void)
 {
-	struct fdt *fdt = rsti(current)->fdt;
 	pid_t pid = vpid(current);
 	struct sockaddr_un saddr;
-	int sock, slen;
-
-	if (!task_alive(current) || (fdt && fdt->pid != pid))
-		return 0;
+	int sock, slen, ret = -1;
 
 	sock = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
 	if (sock < 0) {
 		pr_perror("Can't create socket");
-		return -1;
+		goto out;
 	}
 
 	transport_name_gen(&saddr, &slen, pid);
 	if (bind(sock, (struct sockaddr *)&saddr, slen) < 0) {
 		pr_perror("Can't bind transport socket %s", saddr.sun_path + 1);
 		close(sock);
-		return -1;
+		goto out;
 	}
 
 	if (install_service_fd(TRANSPORT_FD_OFF, sock) < 0) {
 		close(sock);
-		return -1;
+		goto out;
 	}
 	close(sock);
-
-	return 0;
+	ret = 0;
+out:
+	return ret;
 }
diff --git a/criu/pstree.c b/criu/pstree.c
index b18c04dbf..7b7189aa2 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -260,6 +260,8 @@ int init_pstree_helper(struct pstree_item *ret)
 	BUG_ON(!ret->parent);
 	ret->pid->state = TASK_HELPER;
 	rsti(ret)->clone_flags = CLONE_FILES | CLONE_FS;
+	if (shared_fdt_prepare(ret) < 0)
+		return -1;
 	task_entries->nr_helpers++;
 	return 0;
 }



More information about the CRIU mailing list