[CRIU] [PATCH 21/78] infect: Move parasite_stop_daemon and parasite_cure_* into infect.c

Cyrill Gorcunov gorcunov at openvz.org
Mon Nov 7 08:36:06 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/cr-dump.c                  |  16 ++--
 criu/cr-exec.c                  |   2 +-
 criu/include/infect.h           |   4 +
 criu/include/parasite-syscall.h |   4 -
 criu/infect.c                   | 172 +++++++++++++++++++++++++++++++++++++++
 criu/parasite-syscall.c         | 174 +---------------------------------------
 6 files changed, 186 insertions(+), 186 deletions(-)

diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index af3d8917369d..2e5564ad2a9f 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -1182,7 +1182,7 @@ static int pre_dump_one_task(struct pstree_item *item)
 	if (ret)
 		goto err_cure;
 
-	if (parasite_cure_remote(parasite_ctl))
+	if (compel_cure_remote(parasite_ctl))
 		pr_err("Can't cure (pid: %d) from parasite\n", pid);
 err_free:
 	free_mappings(&vmas);
@@ -1190,7 +1190,7 @@ err:
 	return ret;
 
 err_cure:
-	if (parasite_cure_seized(parasite_ctl))
+	if (compel_cure(parasite_ctl))
 		pr_err("Can't cure (pid: %d) from parasite\n", pid);
 	goto err_free;
 }
@@ -1366,7 +1366,7 @@ static int dump_one_task(struct pstree_item *item)
 		goto err_cure;
 	}
 
-	ret = parasite_stop_daemon(parasite_ctl);
+	ret = compel_stop_daemon(parasite_ctl);
 	if (ret) {
 		pr_err("Can't cure (pid: %d) from parasite\n", pid);
 		goto err;
@@ -1379,9 +1379,9 @@ static int dump_one_task(struct pstree_item *item)
 	}
 
 	if (opts.lazy_pages)
-		ret = parasite_cure_remote(parasite_ctl);
+		ret = compel_cure_remote(parasite_ctl);
 	else
-		ret = parasite_cure_seized(parasite_ctl);
+		ret = compel_cure(parasite_ctl);
 	if (ret) {
 		pr_err("Can't cure (pid: %d) from parasite\n", pid);
 		goto err;
@@ -1410,7 +1410,7 @@ err:
 err_cure:
 	close_cr_imgset(&cr_imgset);
 err_cure_imgset:
-	parasite_cure_seized(parasite_ctl);
+	compel_cure(parasite_ctl);
 	goto err;
 }
 
@@ -1487,7 +1487,7 @@ static int cr_pre_dump_finish(int ret)
 		timing_stop(TIME_MEMWRITE);
 
 		destroy_page_pipe(mem_pp);
-		parasite_cure_local(ctl);
+		compel_cure_local(ctl);
 	}
 
 	free_pstree(root_item);
@@ -1592,7 +1592,7 @@ static int cr_lazy_mem_dump(void)
 
 	for_each_pstree_item(item) {
 		destroy_page_pipe(dmpi(item)->mem_pp);
-		parasite_cure_local(dmpi(item)->parasite_ctl);
+		compel_cure_local(dmpi(item)->parasite_ctl);
 	}
 
 	if (ret)
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index 53f17e75bae2..bec423d53a5c 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -189,7 +189,7 @@ int cr_exec(int pid, char **opt)
 
 	exit_code = 0;
 out_cure:
-	parasite_cure_seized(ctl);
+	compel_cure(ctl);
 out_unseize:
 	unseize_task(pid, prev_state, prev_state);
 out:
diff --git a/criu/include/infect.h b/criu/include/infect.h
index fa6dac88cb1a..1d1a2131bd87 100644
--- a/criu/include/infect.h
+++ b/criu/include/infect.h
@@ -30,4 +30,8 @@ extern struct parasite_ctl *compel_prepare(int pid);
 extern int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size);
 extern int compel_prepare_thread(int pid, struct thread_ctx *ctx);
 
+extern int compel_stop_daemon(struct parasite_ctl *ctl);
+extern int compel_cure_remote(struct parasite_ctl *ctl);
+extern int compel_cure_local(struct parasite_ctl *ctl);
+extern int compel_cure(struct parasite_ctl *ctl);
 #endif
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index 9e151df87cae..271c05f27800 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -90,9 +90,6 @@ extern int parasite_drain_fds_seized(struct parasite_ctl *ctl,
 					int *lfds, struct fd_opts *flags);
 extern int parasite_get_proc_fd_seized(struct parasite_ctl *ctl);
 
-extern int parasite_cure_remote(struct parasite_ctl *ctl);
-extern int parasite_cure_local(struct parasite_ctl *ctl);
-extern int parasite_cure_seized(struct parasite_ctl *ctl);
 extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
 						   struct pstree_item *item,
 						   struct vm_area_list *vma_area_list);
@@ -129,7 +126,6 @@ enum trace_flags {
 	TRACE_EXIT,
 };
 
-extern int parasite_stop_daemon(struct parasite_ctl *ctl);
 extern int parasite_stop_on_syscall(int tasks, int sys_nr,
 		int sys_nr_compat, enum trace_flags trace);
 extern int parasite_unmap(struct parasite_ctl *ctl, unsigned long addr);
diff --git a/criu/infect.c b/criu/infect.c
index c1cb31daf4e4..809edf8f87ed 100644
--- a/criu/infect.c
+++ b/criu/infect.c
@@ -318,6 +318,23 @@ static int setup_child_handler(struct parasite_ctl *ctl)
 	return 0;
 }
 
+static int restore_child_handler()
+{
+	struct sigaction sa = {
+		.sa_handler	= SIG_DFL, /* XXX -- should be original? */
+		.sa_flags	= SA_SIGINFO | SA_RESTART,
+	};
+
+	sigemptyset(&sa.sa_mask);
+	sigaddset(&sa.sa_mask, SIGCHLD);
+	if (sigaction(SIGCHLD, &sa, NULL)) {
+		pr_perror("Unable to setup SIGCHLD handler");
+		return -1;
+	}
+
+	return 0;
+}
+
 int parasite_run(pid_t pid, int cmd, unsigned long ip, void *stack,
 		user_regs_struct_t *regs, struct thread_ctx *octx)
 {
@@ -574,3 +591,158 @@ err:
 	return NULL;
 }
 
+static bool task_in_parasite(struct parasite_ctl *ctl, user_regs_struct_t *regs)
+{
+	void *addr = (void *) REG_IP(*regs);
+	return addr >= ctl->remote_map &&
+		addr < ctl->remote_map + ctl->map_length;
+}
+
+static int parasite_fini_seized(struct parasite_ctl *ctl)
+{
+	pid_t pid = ctl->rpid;
+	user_regs_struct_t regs;
+	int status, ret = 0;
+	enum trace_flags flag;
+
+	/* stop getting chld from parasite -- we're about to step-by-step it */
+	if (restore_child_handler())
+		return -1;
+
+	/* Start to trace syscalls for each thread */
+	if (ptrace(PTRACE_INTERRUPT, pid, NULL, NULL)) {
+		pr_perror("Unable to interrupt the process");
+		return -1;
+	}
+
+	pr_debug("Waiting for %d to trap\n", pid);
+	if (wait4(pid, &status, __WALL, NULL) != pid) {
+		pr_perror("Waited pid mismatch (pid: %d)", pid);
+		return -1;
+	}
+
+	pr_debug("Daemon %d exited trapping\n", pid);
+	if (!WIFSTOPPED(status)) {
+		pr_err("Task is still running (pid: %d)\n", pid);
+		return -1;
+	}
+
+	ret = ptrace_get_regs(pid, &regs);
+	if (ret) {
+		pr_perror("Unable to get registers");
+		return -1;
+	}
+
+	if (!task_in_parasite(ctl, &regs)) {
+		pr_err("The task is not in parasite code\n");
+		return -1;
+	}
+
+	ret = __parasite_execute_daemon(PARASITE_CMD_FINI, ctl);
+	close_safe(&ctl->tsock);
+	if (ret)
+		return -1;
+
+	/* Go to sigreturn as closer as we can */
+	ret = ptrace_stop_pie(pid, ctl->sigreturn_addr, &flag);
+	if (ret < 0)
+		return ret;
+
+	if (parasite_stop_on_syscall(1, __NR(rt_sigreturn, 0),
+				__NR(rt_sigreturn, 1), flag))
+		return -1;
+
+	if (ptrace_flush_breakpoints(pid))
+		return -1;
+
+	/*
+	 * All signals are unblocked now. The kernel notifies about leaving
+	 * syscall before starting to deliver signals. All parasite code are
+	 * executed with blocked signals, so we can sefly unmap a parasite blob.
+	 */
+
+	return 0;
+}
+
+int compel_stop_daemon(struct parasite_ctl *ctl)
+{
+	if (ctl->daemonized) {
+		/*
+		 * Looks like a previous attempt failed, we should do
+		 * nothing in this case. parasite will try to cure itself.
+		 */
+		if (ctl->tsock < 0)
+			return -1;
+
+		if (parasite_fini_seized(ctl)) {
+			close_safe(&ctl->tsock);
+			return -1;
+		}
+	}
+
+	ctl->daemonized = false;
+
+	return 0;
+}
+
+int compel_cure_remote(struct parasite_ctl *ctl)
+{
+	if (compel_stop_daemon(ctl))
+		return -1;
+
+	if (!ctl->remote_map)
+		return 0;
+
+	/* Unseizing task with parasite -- it does it himself */
+	if (ctl->addr_cmd) {
+		struct parasite_unmap_args *args;
+
+		*ctl->addr_cmd = PARASITE_CMD_UNMAP;
+
+		args = parasite_args(ctl, struct parasite_unmap_args);
+		args->parasite_start = (uintptr_t)ctl->remote_map;
+		args->parasite_len = ctl->map_length;
+		if (parasite_unmap(ctl, ctl->parasite_ip))
+			return -1;
+	} else {
+		unsigned long ret;
+
+		syscall_seized(ctl, __NR(munmap, !seized_native(ctl)), &ret,
+				(unsigned long)ctl->remote_map, ctl->map_length,
+				0, 0, 0, 0);
+		if (ret) {
+			pr_err("munmap for remote map %p, %lu returned %lu\n",
+					ctl->remote_map, ctl->map_length, ret);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+int compel_cure_local(struct parasite_ctl *ctl)
+{
+	int ret = 0;
+
+	if (ctl->local_map) {
+		if (munmap(ctl->local_map, ctl->map_length)) {
+			pr_err("munmap failed (pid: %d)\n", ctl->rpid);
+			ret = -1;
+		}
+	}
+
+	free(ctl);
+	return ret;
+}
+
+int compel_cure(struct parasite_ctl *ctl)
+{
+	int ret;
+
+	ret = compel_cure_remote(ctl);
+	if (!ret)
+		ret = compel_cure_local(ctl);
+
+	return ret;
+}
+
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 62c1d543d6fe..1774b2838849 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -356,23 +356,6 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
 	exit(1);
 }
 
-static int restore_child_handler()
-{
-	struct sigaction sa = {
-		.sa_handler	= SIG_DFL,
-		.sa_flags	= SA_SIGINFO | SA_RESTART,
-	};
-
-	sigemptyset(&sa.sa_mask);
-	sigaddset(&sa.sa_mask, SIGCHLD);
-	if (sigaction(SIGCHLD, &sa, NULL)) {
-		pr_perror("Unable to setup SIGCHLD handler");
-		return -1;
-	}
-
-	return 0;
-}
-
 static int alloc_groups_copy_creds(CredsEntry *ce, struct parasite_dump_creds *c)
 {
 	BUILD_BUG_ON(sizeof(ce->groups[0]) != sizeof(c->groups[0]));
@@ -766,79 +749,6 @@ int parasite_get_proc_fd_seized(struct parasite_ctl *ctl)
 
 /* This is officially the 50000'th line in the CRIU source code */
 
-static bool task_in_parasite(struct parasite_ctl *ctl, user_regs_struct_t *regs)
-{
-	void *addr = (void *) REG_IP(*regs);
-	return addr >= ctl->remote_map &&
-		addr < ctl->remote_map + ctl->map_length;
-}
-
-static int parasite_fini_seized(struct parasite_ctl *ctl)
-{
-	pid_t pid = ctl->rpid;
-	user_regs_struct_t regs;
-	int status, ret = 0;
-	enum trace_flags flag;
-
-	/* stop getting chld from parasite -- we're about to step-by-step it */
-	if (restore_child_handler())
-		return -1;
-
-	/* Start to trace syscalls for each thread */
-	if (ptrace(PTRACE_INTERRUPT, pid, NULL, NULL)) {
-		pr_perror("Unable to interrupt the process");
-		return -1;
-	}
-
-	pr_debug("Waiting for %d to trap\n", pid);
-	if (wait4(pid, &status, __WALL, NULL) != pid) {
-		pr_perror("Waited pid mismatch (pid: %d)", pid);
-		return -1;
-	}
-
-	pr_debug("Daemon %d exited trapping\n", pid);
-	if (!WIFSTOPPED(status)) {
-		pr_err("Task is still running (pid: %d)\n", pid);
-		return -1;
-	}
-
-	ret = ptrace_get_regs(pid, &regs);
-	if (ret) {
-		pr_perror("Unable to get registers");
-		return -1;
-	}
-
-	if (!task_in_parasite(ctl, &regs)) {
-		pr_err("The task is not in parasite code\n");
-		return -1;
-	}
-
-	ret = __parasite_execute_daemon(PARASITE_CMD_FINI, ctl);
-	close_safe(&ctl->tsock);
-	if (ret)
-		return -1;
-
-	/* Go to sigreturn as closer as we can */
-	ret = ptrace_stop_pie(pid, ctl->sigreturn_addr, &flag);
-	if (ret < 0)
-		return ret;
-
-	if (parasite_stop_on_syscall(1, __NR(rt_sigreturn, 0),
-				__NR(rt_sigreturn, 1), flag))
-		return -1;
-
-	if (ptrace_flush_breakpoints(pid))
-		return -1;
-
-	/*
-	 * All signals are unblocked now. The kernel notifies about leaving
-	 * syscall before starting to deliver signals. All parasite code are
-	 * executed with blocked signals, so we can sefly unmap a parasite blob.
-	 */
-
-	return 0;
-}
-
 static bool task_is_trapped(int status, pid_t pid)
 {
 	if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP)
@@ -950,88 +860,6 @@ goon:
 	return 0;
 }
 
-int parasite_stop_daemon(struct parasite_ctl *ctl)
-{
-	if (ctl->daemonized) {
-		/*
-		 * Looks like a previous attempt failed, we should do
-		 * nothing in this case. parasite will try to cure itself.
-		 */
-		if (ctl->tsock < 0)
-			return -1;
-
-		if (parasite_fini_seized(ctl)) {
-			close_safe(&ctl->tsock);
-			return -1;
-		}
-	}
-
-	ctl->daemonized = false;
-
-	return 0;
-}
-
-int parasite_cure_remote(struct parasite_ctl *ctl)
-{
-	if (parasite_stop_daemon(ctl))
-		return -1;
-
-	if (!ctl->remote_map)
-		return 0;
-
-	/* Unseizing task with parasite -- it does it himself */
-	if (ctl->addr_cmd) {
-		struct parasite_unmap_args *args;
-
-		*ctl->addr_cmd = PARASITE_CMD_UNMAP;
-
-		args = parasite_args(ctl, struct parasite_unmap_args);
-		args->parasite_start = (uintptr_t)ctl->remote_map;
-		args->parasite_len = ctl->map_length;
-		if (parasite_unmap(ctl, ctl->parasite_ip))
-			return -1;
-	} else {
-		unsigned long ret;
-
-		syscall_seized(ctl, __NR(munmap, !seized_native(ctl)), &ret,
-				(unsigned long)ctl->remote_map, ctl->map_length,
-				0, 0, 0, 0);
-		if (ret) {
-			pr_err("munmap for remote map %p, %lu returned %lu\n",
-					ctl->remote_map, ctl->map_length, ret);
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-int parasite_cure_local(struct parasite_ctl *ctl)
-{
-	int ret = 0;
-
-	if (ctl->local_map) {
-		if (munmap(ctl->local_map, ctl->map_length)) {
-			pr_err("munmap failed (pid: %d)\n", ctl->rpid);
-			ret = -1;
-		}
-	}
-
-	free(ctl);
-	return ret;
-}
-
-int parasite_cure_seized(struct parasite_ctl *ctl)
-{
-	int ret;
-
-	ret = parasite_cure_remote(ctl);
-	if (!ret)
-		ret = parasite_cure_local(ctl);
-
-	return ret;
-}
-
 /*
  * parasite_unmap() is used for unmapping parasite and restorer blobs.
  * A blob can contain code for unmapping itself, so the porcess is
@@ -1242,7 +1070,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	parasite_ensure_args_size(aio_rings_args_size(vma_area_list));
 
 	if (compel_infect(ctl, item->nr_threads, parasite_args_size) < 0) {
-		parasite_cure_seized(ctl);
+		compel_cure(ctl);
 		return NULL;
 	}
 
-- 
2.7.4



More information about the CRIU mailing list