[CRIU] Re: [PATCH 1/10] parasite: Check for unexpected signals delivery

Pavel Emelyanov xemul at parallels.com
Thu Mar 1 11:22:47 EST 2012


On 03/01/2012 08:21 PM, Cyrill Gorcunov wrote:
> On Thu, Mar 01, 2012 at 07:29:53PM +0400, Cyrill Gorcunov wrote:
>> On Thu, Mar 01, 2012 at 07:27:35PM +0400, Pavel Emelyanov wrote:
>>>>
>>>> And I think we can do this on top of this series of course. Sounds
>>>> reasonable?
>>>
>>> I don't see how parasite can set up this bit on a crtools-side structure,
>>> but if you find some elegant way of doing this -- please do.
>>>
>>
>> OK. It's not critical. I'll update on top a bit later.
>>
> 
> I thought about something like below. Tell me what do you think.

Awful :(

> Just a slab of shared memory which we can extend if needed and
> it's controlled by parasite itself.
> 
> Note, I've not tested it yet ;)
> 
> 	Cyrill
> ---
> From: Cyrill Gorcunov <gorcunov at openvz.org>
> Date: Thu, 1 Mar 2012 20:19:26 +0400
> Subject: [PATCH] parasite: Add context local variables
> 
> This allow us to have shared variables between
> parasite itself and calling code.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  include/parasite-syscall.h |    5 +++--
>  include/parasite.h         |    9 +++++++--
>  parasite-syscall.c         |    9 ++++-----
>  parasite.c                 |   25 ++++++++++++++++---------
>  4 files changed, 30 insertions(+), 18 deletions(-)
> 
> diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
> index 5ae1554..4fee1a7 100644
> --- a/include/parasite-syscall.h
> +++ b/include/parasite-syscall.h
> @@ -11,6 +11,8 @@
>  
>  #define BUILTIN_SYSCALL_SIZE	8
>  
> +struct parasite_ctx;
> +
>  /* parasite control block */
>  struct parasite_ctl {
>  	pid_t			pid;					/* process pid where we live in */
> @@ -23,10 +25,9 @@ struct parasite_ctl {
>  	unsigned long		syscall_ip;				/* entry point of infection */
>  	u8			code_orig[BUILTIN_SYSCALL_SIZE];
>  
> -	int			signals_blocked;
> -
>  	void *			addr_cmd;				/* addr for command */
>  	void *			addr_args;				/* address for arguments */
> +	struct parasite_ctx	*parasite_ctx;				/* address for parasite context vars */
>  };
>  
>  extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset);
> diff --git a/include/parasite.h b/include/parasite.h
> index 2a67647..d5287e1 100644
> --- a/include/parasite.h
> +++ b/include/parasite.h
> @@ -13,6 +13,7 @@
>  
>  #define PARASITE_STACK_SIZE	2048
>  #define PARASITE_ARG_SIZE	8196
> +#define PARASITE_CONTEXT_SIZE	16
>  
>  #define PARASITE_MAX_SIZE	(64 << 10)
>  
> @@ -104,6 +105,10 @@ struct parasite_dump_sk_queues {
>  	struct sk_queue_item	items[0];
>  };
>  
> +struct parasite_ctx {
> +	int			signals_blocked;
> +};
> +
>  /*
>   * Some useful offsets
>   */
> @@ -114,7 +119,7 @@ struct parasite_dump_sk_queues {
>  	((start) + parasite_blob_offset__parasite_cmd)
>  #define PARASITE_HEAD_ADDR(start)				\
>  	((start) + parasite_blob_offset__parasite_head_start)
> -#define PARASITE_COMPLETE_ADDR(start)				\
> -	((start) + parasite_blob_offset__parasite_service_complete)
> +#define PARASITE_CONTEXT_ADDR(start)				\
> +	((start) + parasite_blob_offset__parasite_context)
>  
>  #endif /* CR_PARASITE_H_ */
> diff --git a/parasite-syscall.c b/parasite-syscall.c
> index d1d63a8..7d5cf48 100644
> --- a/parasite-syscall.c
> +++ b/parasite-syscall.c
> @@ -124,7 +124,7 @@ retry_signal:
>  		pr_debug("** delivering signal %d si_code=%d\n",
>  			 siginfo.si_signo, siginfo.si_code);
>  
> -		if (ctl->signals_blocked) {
> +		if (ctl->parasite_ctx->signals_blocked) {
>  			pr_err("Unexpected %d task interruption, aborting\n", pid);
>  			goto err;
>  		}
> @@ -619,8 +619,6 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
>  	int ret = 0;
>  
>  	if (ctl->parasite_ip) {
> -		ctl->signals_blocked = 0;
> -
>  		if (parasite_execute(PARASITE_CMD_FINI, ctl, &args, sizeof(args))) {
>  			pr_err("Can't finalize parasite (pid: %d) task\n", ctl->pid);
>  			ret = -1;
> @@ -738,6 +736,9 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are
>  	ctl->parasite_ip	= PARASITE_HEAD_ADDR((unsigned long)ctl->remote_map);
>  	ctl->addr_cmd		= (void *)PARASITE_CMD_ADDR((unsigned long)ctl->local_map);
>  	ctl->addr_args		= (void *)PARASITE_ARGS_ADDR((unsigned long)ctl->local_map);
> +	ctl->parasite_ctx	= (void *)PARASITE_CONTEXT_ADDR((unsigned long)ctl->local_map);
> +
> +	memzero(ctl->parasite_ctx, sizeof(*ctl->parasite_ctx));
>  
>  	ret = parasite_init(ctl, pid);
>  	if (ret) {
> @@ -745,8 +746,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are
>  		goto err_restore;
>  	}
>  
> -	ctl->signals_blocked = 1;
> -
>  	ret = parasite_set_logfd(ctl, pid);
>  	if (ret) {
>  		pr_err("%d: Can't set a logging descriptor\n", pid);
> diff --git a/parasite.c b/parasite.c
> index fe5a325..8f9d119 100644
> --- a/parasite.c
> +++ b/parasite.c
> @@ -365,7 +365,6 @@ err_close:
>  }
>  
>  static k_rtsigset_t old_blocked;
> -static int reset_blocked = 0;
>  
>  static int dump_misc(struct parasite_dump_misc *args)
>  {
> @@ -515,7 +514,7 @@ err_dmp:
>  	return ret;
>  }
>  
> -static int init(struct parasite_init_args *args)
> +static int init(struct parasite_init_args *args, struct parasite_ctx *ctx)
>  {
>  	int ret;
>  	k_rtsigset_t to_block;
> @@ -536,9 +535,9 @@ static int init(struct parasite_init_args *args)
>  	ksigfillset(&to_block);
>  	ret = sys_sigprocmask(SIG_SETMASK, &to_block, &old_blocked);
>  	if (ret < 0)
> -		reset_blocked = ret;
> +		ctx->signals_blocked = ret;
>  	else
> -		reset_blocked = 1;
> +		ctx->signals_blocked = 1;
>  
>  	SET_PARASITE_STATUS(&args->status, ret, ret);
>  	return ret;
> @@ -550,29 +549,34 @@ static int parasite_set_logfd(void)
>  	return logfd;
>  }
>  
> -static int fini(void)
> +static int fini(struct parasite_ctx *ctx)
>  {
> -	if (reset_blocked == 1)
> +	if (ctx->signals_blocked == 1) {
>  		sys_sigprocmask(SIG_SETMASK, &old_blocked, NULL);
> +		ctx->signals_blocked = 0;
> +	}
> +
>  	sys_close(logfd);
>  	sys_close(tsock);
>  	brk_fini();
>  	return 0;
>  }
>  
> -static int __used parasite_service(unsigned long cmd, void *args)
> +static int __used parasite_service(unsigned long cmd, void *args,
> +				   struct parasite_ctx *ctx)
>  {
>  	BUILD_BUG_ON(sizeof(struct parasite_dump_pages_args) > PARASITE_ARG_SIZE);
>  	BUILD_BUG_ON(sizeof(struct parasite_init_args) > PARASITE_ARG_SIZE);
>  	BUILD_BUG_ON(sizeof(struct parasite_dump_misc) > PARASITE_ARG_SIZE);
> +	BUILD_BUG_ON(sizeof(struct parasite_ctx) > PARASITE_CONTEXT_SIZE);
>  
>  	switch (cmd) {
>  	case PARASITE_CMD_PINGME:
>  		return 0;
>  	case PARASITE_CMD_INIT:
> -		return init((struct parasite_init_args *) args);
> +		return init((struct parasite_init_args *)args, ctx);
>  	case PARASITE_CMD_FINI:
> -		return fini();
> +		return fini(ctx);
>  	case PARASITE_CMD_SET_LOGFD:
>  		return parasite_set_logfd();
>  	case PARASITE_CMD_DUMPPAGES_INIT:
> @@ -612,12 +616,15 @@ static void __parasite_head __used parasite_head(void)
>  		     "movq %rsp, %rbp					\n"
>  		     "movl parasite_cmd(%rip), %edi			\n"
>  		     "leaq parasite_args(%rip), %rsi			\n"
> +		     "leaq parasite_context(%rip), %rdx			\n"
>  		     "call parasite_service				\n"
>  		     "parasite_service_complete:			\n"
>  		     "int $0x03						\n"
>  		     ".align 8						\n"
>  		     "parasite_cmd:					\n"
>  		     ".long 0						\n"
> +		     "parasite_context:					\n"
> +		     ".space "__stringify(PARASITE_CONTEXT_SIZE)",0	\n"
>  		     "parasite_args:					\n"
>  		     ".long 0						\n"
>  		     ".space "__stringify(PARASITE_ARG_SIZE)",0		\n"



More information about the CRIU mailing list