Commit 903be413 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

seize: Make seize_wait_task() parse task status via callback

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: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 6e49bce7
......@@ -143,7 +143,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;
......
......@@ -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);
......
......@@ -70,10 +70,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);
......
......@@ -981,8 +981,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;
......
......@@ -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++;
......
......@@ -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(),
......@@ -714,7 +714,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(),
......@@ -853,7 +853,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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment