[CRIU] [PATCH 5/6] dump: try to interrupt a task as soon as possible
Pavel Emelyanov
xemul at parallels.com
Thu Dec 19 10:50:56 PST 2013
On 12/19/2013 04:59 PM, Andrey Vagin wrote:
> A task can die while we are reading /proc/pid/stat.
Task may as well die while we're checking for PTRACE_SEIZE ret code
being 0 or not. Where is the catch?
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> ptrace.c | 30 ++++++++++++++++++------------
> 1 file changed, 18 insertions(+), 12 deletions(-)
>
> diff --git a/ptrace.c b/ptrace.c
> index b3b8241..3df6ea0 100644
> --- a/ptrace.c
> +++ b/ptrace.c
> @@ -52,6 +52,14 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
>
> ret = ptrace(PTRACE_SEIZE, pid, NULL, 0);
> ptrace_errno = errno;
> + if (ret == 0) {
> + ret = ptrace(PTRACE_INTERRUPT, pid, NULL, NULL);
> + if (ret < 0) {
> + pr_perror("SEIZE %d: can't interrupt task", pid);
> + ptrace(PTRACE_DETACH, pid, NULL, NULL);
> + goto err;
> + }
> + }
>
> /*
> * It's ugly, but the ptrace API doesn't allow to distinguish
> @@ -88,12 +96,6 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
> goto err;
> }
>
> - ret = ptrace(PTRACE_INTERRUPT, pid, NULL, NULL);
> - if (ret < 0) {
> - pr_perror("SEIZE %d: can't interrupt task", pid);
> - goto err;
> - }
> -
> try_again:
> ret = wait4(pid, &status, __WALL, NULL);
> if (ret < 0) {
> @@ -145,31 +147,35 @@ try_again:
> ret = ptrace(PTRACE_CONT, pid, 0, 0);
> if (ret) {
> pr_perror("Unable to start process");
> - goto err;
> + goto err_stop;
> }
>
> ret = wait4(pid, &status, __WALL, NULL);
> if (ret < 0) {
> pr_perror("SEIZE %d: can't wait task", pid);
> - goto err;
> + goto err_stop;
> }
>
> if (ret != pid) {
> pr_err("SEIZE %d: wrong task attached (%d)\n", pid, ret);
> - goto err;
> + goto err_stop;
> }
>
> if (!WIFSTOPPED(status)) {
> pr_err("SEIZE %d: task not stopped after seize\n", pid);
> - goto err;
> + goto err_stop;
> }
>
> return TASK_STOPPED;
> + } else {
> + pr_err("SEIZE %d: unsupported stop signal %d\n", pid, si.si_signo);
> + goto err;
> }
>
> - pr_err("SEIZE %d: unsupported stop signal %d\n", pid, si.si_signo);
> +err_stop:
> + kill(pid, SIGSTOP);
> err:
> - unseize_task(pid, TASK_STOPPED);
> + ptrace(PTRACE_DETACH, pid, NULL, NULL);
> return -1;
> }
>
>
More information about the CRIU
mailing list