[v4,05/41] cr-restore: Open transport socket earlier

Submitted by Kirill Tkhai on May 4, 2017, 11:47 p.m.

Details

Message ID DB6PR0802MB227760B7B063FBCF5C5CB64ACDEA0@DB6PR0802MB2277.eurprd08.prod.outlook.com
State New
Headers show

Patch hide | download patch | download mbox

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index f3f5f673..e29f6682 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-reg.c b/criu/files-reg.c
index cd30bd0d..07a12da6 100644
--- a/criu/files-reg.c
+++ b/criu/files-reg.c
@@ -388,13 +388,12 @@  static int open_remap_dead_process(struct reg_file_info *rfi,
 		return 0;
 	}
 
-	init_pstree_helper(helper);
-
 	vsid(helper) = vsid(root_item);
 	vpgid(helper) = vpgid(root_item);
 	vpid(helper) = rfe->remap_id;
 	helper->parent = root_item;
 	helper->ids = root_item->ids;
+	init_pstree_helper(helper);
 	list_add_tail(&helper->sibling, &root_item->children);
 
 	pr_info("Added a helper for restoring /proc/%d\n", vpid(helper));
diff --git a/criu/files.c b/criu/files.c
index 01cd4c0e..3821fefd 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -1195,6 +1195,8 @@  int prepare_fds(struct pstree_item *me)
 		}
 	}
 
+	BUG_ON(current->pid->state == TASK_HELPER);
+
 	ret = open_fdinfos(me);
 
 	if (rsti(me)->fdt)
@@ -1325,6 +1327,7 @@  int shared_fdt_prepare(struct pstree_item *item)
 
 		rsti(parent)->fdt = fdt;
 
+		mutex_init(&fdt->fdt_mutex);
 		futex_init(&fdt->fdt_lock);
 		fdt->nr = 1;
 		fdt->pid = vpid(parent);
@@ -1635,29 +1638,32 @@  int open_transport_socket(void)
 	struct fdt *fdt = rsti(current)->fdt;
 	pid_t pid = vpid(current);
 	struct sockaddr_un saddr;
-	int sock, slen;
+	int sock, slen, ret = -1;
 
-	if (!task_alive(current) || (fdt && fdt->pid != pid))
-		return 0;
+	if (fdt)
+		mutex_lock(&fdt->fdt_mutex);
 
 	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:
+	if (fdt)
+		mutex_unlock(&fdt->fdt_mutex);
+	return ret;
 }
diff --git a/criu/include/rst_info.h b/criu/include/rst_info.h
index 92dfc9d9..1860c21f 100644
--- a/criu/include/rst_info.h
+++ b/criu/include/rst_info.h
@@ -21,6 +21,7 @@  struct fdt {
 	 * The fdt table was restrored, if fdt_lock is equal to nr + 1
 	 */
 	futex_t			fdt_lock;
+	mutex_t			fdt_mutex;
 };
 
 struct _MmEntry;
diff --git a/criu/pstree.c b/criu/pstree.c
index b512e43b..09623462 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -255,6 +255,8 @@  void init_pstree_helper(struct pstree_item *ret)
 {
 	ret->pid->state = TASK_HELPER;
 	rsti(ret)->clone_flags = CLONE_FILES | CLONE_FS;
+	if (shared_fdt_prepare(ret) < 0)
+		return;
 	task_entries->nr_helpers++;
 }
 
@@ -889,7 +891,6 @@  static int prepare_pstree_ids(void)
 			continue;
 
 		helper = pid->item;
-		init_pstree_helper(helper);
 
 		vsid(helper) = vsid(item);
 		vpgid(helper) = vpgid(item);
@@ -898,6 +899,7 @@  static int prepare_pstree_ids(void)
 		helper->ids = item->ids;
 		list_add(&helper->sibling, &item->children);
 		rsti(item)->pgrp_leader = helper;
+		init_pstree_helper(helper);
 
 		pr_info("Add a helper %d for restoring PGID %d\n",
 				vpid(helper), vpgid(helper));