[CRIU] [PATCH 7/8] compel: Handier API for stopping tasks for infection

Cyrill Gorcunov gorcunov at openvz.org
Mon Nov 21 10:26:19 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

Now we have two routines one of which needs a callback for
proc parsing. This is complex, but needed by CRIU. For others
let's have a single "stop" call that would to everything.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 compel/include/uapi/infect.h |  2 +-
 compel/src/lib/infect.c      | 59 ++++++++++++++++++++++++++++++++++++++++++++
 criu/cr-exec.c               |  2 +-
 criu/seize.c                 |  8 +++---
 4 files changed, 65 insertions(+), 6 deletions(-)

diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index 8f49ae12b3ac..a6b550a7cdea 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -12,7 +12,7 @@
 
 #define PARASITE_START_AREA_MIN	(4096)
 
-extern int compel_stop_task(int pid);
+extern int compel_interrupt_task(int pid);
 
 struct seize_task_status {
 	char			state;
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index a66265c249e1..0c653f6cfc35 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -64,9 +64,68 @@ static inline void close_safe(int *pfd)
 	}
 }
 
+static int parse_pid_status(int pid, struct seize_task_status *ss)
+{
+	char aux[128];
+	FILE *f;
+
+	sprintf(aux, "/proc/%d/status", pid);
+	f = fopen(aux, "r");
+	if (!f)
+		return -1;
+
+	ss->ppid = -1; /* Not needed at this point */
+	ss->seccomp_mode = SECCOMP_MODE_DISABLED;
+
+	while (fgets(aux, sizeof(aux), f)) {
+		if (!strncmp(aux, "State:", 6)) {
+			ss->state = aux[7];
+			continue;
+		}
+
+		if (!strncmp(aux, "Seccomp:", 8)) {
+			if (sscanf(aux + 9, "%d", &ss->seccomp_mode) != 1)
+				goto err_parse;
+
+			continue;
+		}
+
+		if (!strncmp(aux, "ShdPnd:", 7)) {
+			if (sscanf(aux + 7, "%llx", &ss->shdpnd) != 1)
+				goto err_parse;
+
+			continue;
+		}
+		if (!strncmp(aux, "SigPnd:", 7)) {
+			if (sscanf(aux + 7, "%llx", &ss->sigpnd) != 1)
+				goto err_parse;
+
+			continue;
+		}
+	}
+
+	fclose(f);
+	return 0;
+
+err_parse:
+	fclose(f);
+	return -1;
+}
+
 int compel_stop_task(int pid)
 {
 	int ret;
+	struct seize_task_status ss;
+
+	ret = compel_interrupt_task(pid);
+	if (ret == 0)
+		ret = compel_wait_task(pid, -1, parse_pid_status, &ss);
+	return ret;
+}
+
+int compel_interrupt_task(int pid)
+{
+	int ret;
 
 	ret = ptrace(PTRACE_SEIZE, pid, NULL, 0);
 	if (ret) {
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index b39c77238468..538ebec86383 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -137,7 +137,7 @@ int cr_exec(int pid, char **opt)
 		goto out;
 	}
 
-	if (compel_stop_task(pid))
+	if (compel_interrupt_task(pid))
 		goto out;
 
 	/*
diff --git a/criu/seize.c b/criu/seize.c
index c28289f1f183..69aaf0a09230 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -130,7 +130,7 @@ static int seize_cgroup_tree(char *root_path, const char *state)
 			return -1;
 		}
 
-		if (!compel_stop_task(pid)) {
+		if (!compel_interrupt_task(pid)) {
 			pr_debug("SEIZE %d: success\n", pid);
 			processes_to_wait++;
 		} else if (state == frozen) {
@@ -482,7 +482,7 @@ static int collect_children(struct pstree_item *item)
 
 		if (!opts.freeze_cgroup)
 			/* fails when meets a zombie */
-			compel_stop_task(pid);
+			compel_interrupt_task(pid);
 
 		creds = xzalloc(sizeof(*creds));
 		if (!creds) {
@@ -712,7 +712,7 @@ static int collect_threads(struct pstree_item *item)
 		pr_info("\tSeizing %d's %d thread\n",
 				item->pid.real, pid);
 
-		if (!opts.freeze_cgroup && compel_stop_task(pid))
+		if (!opts.freeze_cgroup && compel_interrupt_task(pid))
 			continue;
 
 		ret = compel_wait_task(pid, item_ppid(item), parse_pid_status, &t_creds.s);
@@ -844,7 +844,7 @@ int collect_pstree(void)
 	if (opts.freeze_cgroup && freeze_processes())
 		goto err;
 
-	if (!opts.freeze_cgroup && compel_stop_task(pid)) {
+	if (!opts.freeze_cgroup && compel_interrupt_task(pid)) {
 		set_cr_errno(ESRCH);
 		goto err;
 	}
-- 
2.7.4



More information about the CRIU mailing list