[CRIU] [PATCH 6/8] restore: catch task on the exit from sigreturn (v2)
Andrey Vagin
avagin at openvz.org
Fri Sep 13 05:53:43 EDT 2013
A task is stopped here for unmaping restorer blob and restoring a state.
The method is the same as for parasite. CRIU attaches to processes via
ptrace and start to trace all syscalls.
v2: don't use a software breakpoint
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/cr-restore.c b/cr-restore.c
index 8517672..ddfb9f9 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -64,6 +64,8 @@
#include "stats.h"
#include "tun.h"
+#include "parasite-syscall.h"
+
#include "protobuf.h"
#include "protobuf/sa.pb-c.h"
#include "protobuf/timer.pb-c.h"
@@ -1321,6 +1323,65 @@ static int restore_switch_stage(int next_stage)
return restore_wait_inprogress_tasks();
}
+static int attach_to_tasks()
+{
+ struct pstree_item *item;
+ int nr = 0;
+
+ for_each_pstree_item(item) {
+ pid_t pid = item->pid.real;
+ int status;
+
+ if (item->state == TASK_DEAD)
+ continue;
+
+ if (item->state == TASK_HELPER)
+ continue;
+
+ if (ptrace(PTRACE_ATTACH, pid, NULL, PTRACE_O_TRACEFORK)) {
+ pr_perror("Can't attach to %d", pid);
+ return -1;
+ }
+
+ if (waitpid(pid, &status, 0) < 0) {
+ pr_perror("waitpid() failed");
+ return -1;
+ }
+
+ if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL)) {
+ pr_perror("ptrace");
+ return -1;
+ }
+
+ nr++;
+ }
+
+ return nr;
+}
+
+static void finalize_restore(int status)
+{
+ struct pstree_item *item;
+
+ for_each_pstree_item(item) {
+ pid_t pid = item->pid.real;
+
+ if (item->state == TASK_DEAD)
+ continue;
+
+ if (item->state == TASK_HELPER)
+ continue;
+
+ if (status < 0)
+ goto detach;
+
+ /* TODO Unmap the restorer blob and restore the process state */
+detach:
+ if (ptrace(PTRACE_DETACH, pid, NULL, 0))
+ pr_perror("Unable to execute %d", pid);
+ }
+}
+
static int restore_root_task(struct pstree_item *init)
{
int ret, fd;
@@ -1433,9 +1494,16 @@ static int restore_root_task(struct pstree_item *init)
timing_stop(TIME_RESTORE);
+ ret = attach_to_tasks();
+
pr_info("Restore finished successfully. Resuming tasks.\n");
futex_set_and_wake(&task_entries->start, CR_STATE_COMPLETE);
+ if (ret > 0)
+ ret = parasite_stop_on_syscall(ret, __NR_rt_sigreturn);
+
+ finalize_restore(ret);
+
write_stats(RESTORE_STATS);
if (!opts.restore_detach)
--
1.8.3.1
More information about the CRIU
mailing list