[CRIU] [PATCH 04/78] seize: Make seize_wait_task() parse task status via callback

Cyrill Gorcunov gorcunov at openvz.org
Mon Nov 7 08:35:49 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

When seizeing task we need to parse /proc/pid/status for its
state, parent, signals and seccomp status.

In criu case we also parse other stuff in one go, so make
this parsing be a callback which criu will provide.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/cr-exec.c            |  2 +-
 criu/include/proc_parse.h |  2 +-
 criu/include/ptrace.h     |  6 +++---
 criu/proc_parse.c         |  3 ++-
 criu/ptrace.c             | 20 +++++++++++---------
 criu/seize.c              |  6 +++---
 6 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index e2f2ed4ef662..b00c35cbffe3 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -141,7 +141,7 @@ int cr_exec(int pid, char **opt)
 	 * mess with creds in this use case anyway.
 	 */
 
-	prev_state = ret = seize_wait_task(pid, -1, &creds);
+	prev_state = ret = seize_wait_task(pid, -1, parse_pid_status, &creds.s);
 	if (ret < 0) {
 		pr_err("Can't seize task %d\n", pid);
 		goto out;
diff --git a/criu/include/proc_parse.h b/criu/include/proc_parse.h
index ce444e5d9817..d5fbaf7a0b0a 100644
--- a/criu/include/proc_parse.h
+++ b/criu/include/proc_parse.h
@@ -96,7 +96,7 @@ extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
 extern unsigned int parse_pid_loginuid(pid_t pid, int *err, bool ignore_noent);
 extern int parse_pid_oom_score_adj(pid_t pid, int *err);
 extern int prepare_loginuid(unsigned int value, unsigned int loglevel);
-extern int parse_pid_status(pid_t pid, struct proc_status_creds *);
+extern int parse_pid_status(pid_t pid, struct seize_task_status *);
 extern int parse_file_locks(void);
 extern int get_fd_mntid(int fd, int *mnt_id);
 
diff --git a/criu/include/ptrace.h b/criu/include/ptrace.h
index 924c16329061..020b36eedfcf 100644
--- a/criu/include/ptrace.h
+++ b/criu/include/ptrace.h
@@ -80,10 +80,10 @@ struct seize_task_status {
 	int			seccomp_mode;
 };
 
-struct proc_status_creds;
-
 extern int seize_catch_task(pid_t pid);
-extern int seize_wait_task(pid_t pid, pid_t ppid, struct proc_status_creds *creds);
+extern int seize_wait_task(pid_t pid, pid_t ppid,
+		int (*get_status)(int pid, struct seize_task_status *),
+		struct seize_task_status *st);
 extern int suspend_seccomp(pid_t pid);
 extern int unseize_task(pid_t pid, int orig_state, int state);
 extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes);
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index ceb6c3915ae6..c5ce0e24485b 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -979,8 +979,9 @@ static int cap_parse(char *str, unsigned int *res)
 	return 0;
 }
 
-int parse_pid_status(pid_t pid, struct proc_status_creds *cr)
+int parse_pid_status(pid_t pid, struct seize_task_status *ss)
 {
+	struct proc_status_creds *cr = container_of(ss, struct proc_status_creds, s);
 	struct bfd f;
 	int done = 0;
 	int ret = -1;
diff --git a/criu/ptrace.c b/criu/ptrace.c
index 4dd774c63944..0d96eea50ad5 100644
--- a/criu/ptrace.c
+++ b/criu/ptrace.c
@@ -148,7 +148,9 @@ static int skip_sigstop(int pid, int nr_signals)
  * of it so the task would not know if it was saddled
  * up with someone else.
  */
-int seize_wait_task(pid_t pid, pid_t ppid, struct proc_status_creds *creds)
+int seize_wait_task(pid_t pid, pid_t ppid,
+		int (*get_status)(int pid, struct seize_task_status *),
+		struct seize_task_status *ss)
 {
 	siginfo_t si;
 	int status, nr_sigstop;
@@ -175,17 +177,17 @@ try_again:
 		wait_errno = errno;
 	}
 
-	ret2 = parse_pid_status(pid, creds);
+	ret2 = get_status(pid, ss);
 	if (ret2)
 		goto err;
 
 	if (ret < 0 || WIFEXITED(status) || WIFSIGNALED(status)) {
-		if (creds->s.state != 'Z') {
+		if (ss->state != 'Z') {
 			if (pid == getpid())
 				pr_err("The criu itself is within dumped tree.\n");
 			else
 				pr_err("Unseizable non-zombie %d found, state %c, err %d/%d\n",
-						pid, creds->s.state, ret, wait_errno);
+						pid, ss->state, ret, wait_errno);
 			return -1;
 		}
 
@@ -195,9 +197,9 @@ try_again:
 			return TASK_DEAD;
 	}
 
-	if ((ppid != -1) && (creds->s.ppid != ppid)) {
+	if ((ppid != -1) && (ss->ppid != ppid)) {
 		pr_err("Task pid reused while suspending (%d: %d -> %d)\n",
-				pid, ppid, creds->s.ppid);
+				pid, ppid, ss->ppid);
 		goto err;
 	}
 
@@ -229,13 +231,13 @@ try_again:
 		goto try_again;
 	}
 
-	if (creds->s.seccomp_mode != SECCOMP_MODE_DISABLED && suspend_seccomp(pid) < 0)
+	if (ss->seccomp_mode != SECCOMP_MODE_DISABLED && suspend_seccomp(pid) < 0)
 		goto err;
 
 	nr_sigstop = 0;
-	if (creds->s.sigpnd & (1 << (SIGSTOP - 1)))
+	if (ss->sigpnd & (1 << (SIGSTOP - 1)))
 		nr_sigstop++;
-	if (creds->s.shdpnd & (1 << (SIGSTOP - 1)))
+	if (ss->shdpnd & (1 << (SIGSTOP - 1)))
 		nr_sigstop++;
 	if (si.si_signo == SIGSTOP)
 		nr_sigstop++;
diff --git a/criu/seize.c b/criu/seize.c
index 251be7921234..a2de761822ec 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -488,7 +488,7 @@ static int collect_children(struct pstree_item *item)
 			goto free;
 		}
 
-		ret = seize_wait_task(pid, item->pid.real, creds);
+		ret = seize_wait_task(pid, item->pid.real, parse_pid_status, &creds->s);
 		if (ret < 0) {
 			/*
 			 * Here is a race window between parse_children() and seize(),
@@ -713,7 +713,7 @@ static int collect_threads(struct pstree_item *item)
 		if (!opts.freeze_cgroup && seize_catch_task(pid))
 			continue;
 
-		ret = seize_wait_task(pid, item_ppid(item), &t_creds);
+		ret = seize_wait_task(pid, item_ppid(item), parse_pid_status, &t_creds.s);
 		if (ret < 0) {
 			/*
 			 * Here is a race window between parse_threads() and seize(),
@@ -851,7 +851,7 @@ int collect_pstree(void)
 	if (!creds)
 		goto err;
 
-	ret = seize_wait_task(pid, -1, creds);
+	ret = seize_wait_task(pid, -1, parse_pid_status, &creds->s);
 	if (ret < 0)
 		goto err;
 
-- 
2.7.4



More information about the CRIU mailing list