[CRIU] [PATCH 5/6] dump: try to interrupt a task as soon as possible
Andrey Vagin
avagin at openvz.org
Thu Dec 19 04:59:45 PST 2013
A task can die while we are reading /proc/pid/stat.
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;
}
--
1.8.3.1
More information about the CRIU
mailing list