[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