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

Cyrill Gorcunov gorcunov at openvz.org
Thu Mar 1 11:21:54 EST 2012


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.
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"
-- 
1.7.7.6



More information about the CRIU mailing list