[CRIU] [PATCH 3/3] crtoools: add support of stopped tasks
Pavel Emelyanov
xemul at parallels.com
Thu Sep 26 08:10:01 EDT 2013
On 09/26/2013 02:37 PM, Andrey Vagin wrote:
> Currently we catch processes on the exit point from sigreturn.
> If a task must be restored in the stopped state, we can send SIGSTOP
> before detaching from it.
>
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> cr-dump.c | 7 +------
> cr-restore.c | 15 +++++++++++++--
> ptrace.c | 26 +++++++++++++++++++++++++-
> test/zdtm.sh | 1 +
> 4 files changed, 40 insertions(+), 9 deletions(-)
>
> diff --git a/cr-dump.c b/cr-dump.c
> index ebd2cc5..284c1e3 100644
> --- a/cr-dump.c
> +++ b/cr-dump.c
> @@ -660,7 +660,7 @@ static int dump_task_core_all(struct pstree_item *item,
>
> strncpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN);
> core->tc->flags = stat->flags;
> - core->tc->task_state = TASK_ALIVE;
> + core->tc->task_state = item->state;
> core->tc->exit_code = 0;
>
> ret = dump_thread_core(pid, core, &misc->ti);
> @@ -1364,11 +1364,6 @@ static int dump_one_task(struct pstree_item *item)
> pr_info("Dumping task (pid: %d)\n", pid);
> pr_info("========================================\n");
>
> - if (item->state == TASK_STOPPED) {
> - pr_err("Stopped tasks are not supported\n");
> - return -1;
> - }
> -
> if (item->state == TASK_DEAD)
> return 0;
>
> diff --git a/cr-restore.c b/cr-restore.c
> index 419f14e..cd1e8cb 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -861,6 +861,7 @@ static int restore_one_task(int pid, CoreEntry *core)
>
> switch ((int)core->tc->task_state) {
> case TASK_ALIVE:
> + case TASK_STOPPED:
> ret = restore_one_alive_task(pid, core);
> break;
> case TASK_DEAD:
> @@ -909,8 +910,17 @@ static inline int fork_with_pid(struct pstree_item *item)
>
> item->state = ca.core->tc->task_state;
>
> - if (item->state == TASK_DEAD)
> + switch (item->state) {
> + case TASK_ALIVE:
> + case TASK_STOPPED:
> + break;
> + case TASK_DEAD:
> item->parent->rst->nr_zombies++;
> + break;
> + default:
> + pr_err("Unknown task state %d\n", item->state);
> + return -1;
> + }
> } else
> ca.core = NULL;
>
> @@ -1389,7 +1399,8 @@ static void finalize_restore(int status)
>
> xfree(ctl);
>
> - /* TODO restore the process state */
Will it work with stopped threads?
> + if (item->state == TASK_STOPPED)
> + kill(item->pid.real, SIGSTOP);
> detach:
> #ifdef CR_DEBUG
> BUG_ON(status < 0);
> diff --git a/ptrace.c b/ptrace.c
> index 4b6b84c..71570e8 100644
> --- a/ptrace.c
> +++ b/ptrace.c
> @@ -136,8 +136,32 @@ try_again:
>
> if (si.si_signo == SIGTRAP)
> return TASK_ALIVE;
> - else if (si.si_signo == SIGSTOP)
> + else if (si.si_signo == SIGSTOP) {
> + /* Skip SIGSTOP */
More descriptive comment required.
> + ret = ptrace(PTRACE_CONT, pid, 0, 0);
> + if (ret) {
> + pr_perror("Unable to start process");
> + goto err;
> + }
> +
> + ret = wait4(pid, &status, __WALL, NULL);
> + if (ret < 0) {
> + pr_perror("SEIZE %d: can't wait task", pid);
> + goto err;
> + }
> +
> + if (ret != pid) {
> + pr_err("SEIZE %d: wrong task attached (%d)\n", pid, ret);
> + goto err;
> + }
> +
> + if (!WIFSTOPPED(status)) {
> + pr_err("SEIZE %d: task not stopped after seize\n", pid);
> + goto err;
> + }
> +
> return TASK_STOPPED;
> + }
>
> pr_err("SEIZE %d: unsupported stop signal %d\n", pid, si.si_signo);
> err:
> diff --git a/test/zdtm.sh b/test/zdtm.sh
> index e1be1a5..ebc53fc 100755
> --- a/test/zdtm.sh
> +++ b/test/zdtm.sh
> @@ -94,6 +94,7 @@ static/sk-netlink
> static/proc-self
> static/grow_map
> static/grow_map02
> +static/stopped
> "
> # Duplicate list with ns/ prefix
> TEST_LIST=$TEST_LIST$(echo $TEST_LIST | tr ' ' '\n' | sed 's#^#ns/#')
>
More information about the CRIU
mailing list