[CRIU] [PATCH] parasite/mem: unprotect VMAs if page dumping failed

Pavel Emelyanov xemul at virtuozzo.com
Tue Mar 29 04:13:21 PDT 2016


On 03/28/2016 10:38 PM, Dmitry Safonov wrote:
> Before patch parasite_dump_pages_seized tried to unprotect pages
> by parasite command. But it had two issues:
> 1. parasite doesn't wait any command, except PARASITE_CMD_FINI after
>    it failed;

But that's OK. The fini() call first unprotects vmas back, doesn't it?

> 2. return code for parasite_dump_pages_seized was not set according
>    to __parasite_dump_pages_seized failure.
 
        ret = __parasite_dump_pages_seized(ctl, pargs, vma_area_list, pp);
        if (ret)
                pr_err("Can't dump page with parasite\n");

isn't this error setting? Why not?

> During fixing compatible patches set troubles, I saw the following picture,
> which the patch fixes:
> 
> (00.010992) Sent msg to daemon 8 0 0
> pie: __fetched msg: 8 0 0
> (00.010995) Wait for ack 8 on daemon socket
> pie: Error (pie/parasite.c:82): Can't splice pages to pipe (0/16)
> pie: __sent ack msg: 8 8 -1
> pie: Error (pie/parasite.c:721): Close the control socket for writing
>>
> pie: Daemon waits for command
> (00.011023) Fetched ack: 8 8 -1
> (00.011025) Error (parasite-syscall.c:345): Command 8 for daemon failed with -1
> (00.011131) page-pipe: Killing page pipe
> (00.011150) ----------------------------------------
> (00.011151) Error (mem.c:375): Can't dump page with parasite
> (00.011155) Sent msg to daemon 7 0 0
> (00.011156) Wait for ack 7 on daemon socket
> pie: __fetched msg: 7 0 0
> (00.011157) Error (parasite-syscall.c:318): Message reply from daemon is trimmed (12/0)
> pie: Error (pie/parasite.c:665): Command rejected
> (00.011159) Error (mem.c:379): Can't rollback unprotected vmas with parasite
> pie: Daemon waits for command
> 
> Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
> ---
>  criu/mem.c          |  4 +++-
>  criu/pie/parasite.c | 21 ++++++++++++++++++++-
>  2 files changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/criu/mem.c b/criu/mem.c
> index 5a7b5bb96ba9..a8e3953769d0 100644
> --- a/criu/mem.c
> +++ b/criu/mem.c
> @@ -371,8 +371,10 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl,
>  	}
>  
>  	ret = __parasite_dump_pages_seized(ctl, pargs, vma_area_list, pp);
> -	if (ret)
> +	if (ret) {
>  		pr_err("Can't dump page with parasite\n");
> +		ret = -1;
> +	}
>  
>  	pargs->add_prot = 0;
>  	if (parasite_execute_daemon(PARASITE_CMD_MPROTECT_VMAS, ctl)) {
> diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
> index 9d822bb2a93a..b1808bc7ed5c 100644
> --- a/criu/pie/parasite.c
> +++ b/criu/pie/parasite.c
> @@ -644,6 +644,25 @@ static int fini()
>  	return -1;
>  }
>  
> +static inline bool after_fail_cmd_allowed(struct ctl_msg *m, void *args)
> +{
> +	if (m->cmd == PARASITE_CMD_FINI)
> +		return true;
> +
> +	if (m->cmd == PARASITE_CMD_MPROTECT_VMAS) {
> +		struct parasite_dump_pages_args *dp_args = args;
> +
> +		/*
> +		 * We should allow parasite to unprotect VMAs back
> +		 * from PROT_READ after failed pages dumping.
> +		 */
> +		if (!dp_args->add_prot)
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
>  static noinline __used int noinline parasite_daemon(void *args)
>  {
>  	struct ctl_msg m = { };
> @@ -661,7 +680,7 @@ static noinline __used int noinline parasite_daemon(void *args)
>  		if (__parasite_daemon_wait_msg(&m))
>  			break;
>  
> -		if (ret && m.cmd != PARASITE_CMD_FINI) {
> +		if (ret && !after_fail_cmd_allowed(&m, args)) {
>  			pr_err("Command rejected\n");
>  			continue;
>  		}
> 



More information about the CRIU mailing list