[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