[CRIU] [PATCH 75/78] infect: Introduce and use parasite_blob_desc

Cyrill Gorcunov gorcunov at openvz.org
Mon Nov 7 08:37:00 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

The _desc is to describe where libcompel should task
parasite code from. For now the parasite is taken as
piece of memory, but more ways to load the code will
come soon.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/include/infect-priv.h |  2 ++
 criu/include/infect.h      | 14 ++++++++++++++
 criu/infect.c              | 48 ++++++++++++++--------------------------------
 criu/parasite-syscall.c    | 36 ++++++++++++++++++++++++++++++++++
 4 files changed, 66 insertions(+), 34 deletions(-)

diff --git a/criu/include/infect-priv.h b/criu/include/infect-priv.h
index c994981d190a..db5259c2c315 100644
--- a/criu/include/infect-priv.h
+++ b/criu/include/infect-priv.h
@@ -32,6 +32,8 @@ struct parasite_ctl {
 	void			*addr_args;				/* address for arguments */
 	unsigned long		args_size;
 	int			tsock;					/* transport socket for transferring fds */
+
+	struct parasite_blob_desc pblob;
 };
 
 #define MEMFD_FNAME	"CRIUMFD"
diff --git a/criu/include/infect.h b/criu/include/infect.h
index 3f3913ac3165..71255b54cf1c 100644
--- a/criu/include/infect.h
+++ b/criu/include/infect.h
@@ -3,6 +3,7 @@
 
 #include "asm/infect-types.h"
 #include <compel/ksigset.h>
+#include <compel/compel.h>
 
 #define PARASITE_START_AREA_MIN	(4096)
 
@@ -120,6 +121,19 @@ extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *);
 #define INFECT_NO_BREAKPOINTS	0x4	/* no breakpoints in pie tracking */
 #define INFECT_HAS_COMPAT_SIGRETURN 0x8
 
+struct parasite_blob_desc {
+	const void		*mem;
+	size_t			bsize; /* size of the blob */
+	size_t			size;  /* size of the blob with relocs */
+	unsigned long		parasite_ip_off;
+	unsigned long		addr_cmd_off;
+	unsigned long		addr_arg_off;
+	compel_reloc_t		*relocs;
+	unsigned int		nr_relocs;
+};
+
+extern struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl *);
+
 typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
 extern int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t, void *);
 
diff --git a/criu/infect.c b/criu/infect.c
index 8f8f6020a456..27b557abbb36 100644
--- a/criu/infect.c
+++ b/criu/infect.c
@@ -10,7 +10,6 @@
 #include <linux/seccomp.h>
 
 #include "pie-relocs.h"
-#include "parasite-blob.h"
 #include "criu-log.h"
 #include "common/bug.h"
 #include "common/xmalloc.h"
@@ -743,27 +742,6 @@ int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size)
 	return ret;
 }
 
-/* the parasite prefix is added by gen_offsets.sh */
-#define __pblob_offset(ptype, symbol)					\
-	parasite_ ## ptype ## _blob_offset__ ## symbol
-#define parasite_sym(pblob, ptype, symbol)				\
-	((void *)(pblob) + __pblob_offset(ptype, symbol))
-
-#define init_parasite_ctl(ctl, blob_type)				\
-	do {								\
-	memcpy(ctl->local_map, parasite_##blob_type##_blob,		\
-		sizeof(parasite_##blob_type##_blob));			\
-	ELF_RELOCS_APPLY(parasite_##blob_type,				\
-		ctl->local_map, ctl->remote_map);			\
-	/* Setup the rest of a control block */				\
-	ctl->parasite_ip = (unsigned long)parasite_sym(ctl->remote_map,	\
-		blob_type, __export_parasite_head_start);		\
-	ctl->addr_cmd    = parasite_sym(ctl->local_map, blob_type,	\
-		__export_parasite_cmd);					\
-	ctl->addr_args   = parasite_sym(ctl->local_map, blob_type,	\
-		__export_parasite_args);				\
-	} while (0)
-
 int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size)
 {
 	int ret;
@@ -782,12 +760,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
 	 * without using ptrace at all.
 	 */
 
-	if (compel_mode_native(ctl))
-		parasite_size = pie_size(parasite_native);
-#ifdef CONFIG_COMPAT
-	else
-		parasite_size = pie_size(parasite_compat);
-#endif
+	parasite_size = ctl->pblob.size;
 
 	ctl->args_size = round_up(args_size, PAGE_SIZE);
 	parasite_size += ctl->args_size;
@@ -803,12 +776,14 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
 
 	pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map);
 
-	if (compel_mode_native(ctl))
-		init_parasite_ctl(ctl, native);
-#ifdef CONFIG_COMPAT
-	else
-		init_parasite_ctl(ctl, compat);
-#endif
+	ctl->parasite_ip = (unsigned long)(ctl->remote_map + ctl->pblob.parasite_ip_off);
+	ctl->addr_cmd = ctl->local_map + ctl->pblob.addr_cmd_off;
+	ctl->addr_args = ctl->local_map + ctl->pblob.addr_arg_off;
+
+	memcpy(ctl->local_map, ctl->pblob.mem, ctl->pblob.size);
+	if (ctl->pblob.nr_relocs)
+		elf_relocs_apply(ctl->local_map, ctl->remote_map, ctl->pblob.bsize,
+				ctl->pblob.relocs, ctl->pblob.nr_relocs);
 
 	p = parasite_size;
 
@@ -1252,3 +1227,8 @@ struct infect_ctx *compel_infect_ctx(struct parasite_ctl *ctl)
 {
 	return &ctl->ictx;
 }
+
+struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl *ctl)
+{
+	return &ctl->pblob;
+}
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index db405bca5dad..0e33428b0900 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -5,6 +5,7 @@
 #include <sys/wait.h>
 #include <sys/mman.h>
 
+#include "common/compiler.h"
 #include "types.h"
 #include "protobuf.h"
 #include "images/sa.pb-c.h"
@@ -43,6 +44,7 @@
 
 #include "infect.h"
 #include "infect-rpc.h"
+#include "parasite-blob.h"
 
 unsigned long get_exec_start(struct vm_area_list *vmas)
 {
@@ -522,11 +524,37 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe *
 	return construct_sigframe(sf, rtsf, bs, (CoreEntry *)arg);
 }
 
+/* the parasite prefix is added by gen_offsets.sh */
+#define pblob_offset(ptype, symbol)					\
+	parasite_ ## ptype ## _blob_offset__ ## symbol
+
+#ifdef CONFIG_PIEGEN
+#define init_blob_relocs(bdesc, blob_type)						\
+	do {										\
+		bdesc->relocs = parasite_##blob_type##_relocs;				\
+		bdesc->nr_relocs = ARRAY_SIZE(parasite_##blob_type##_relocs);		\
+	} while (0)
+#else
+#define init_blob_relocs(bdesc, blob_type)
+#endif
+
+#define init_blob_desc(bdesc, blob_type) do {						\
+	pbd->size = pie_size(parasite_##blob_type);					\
+	bdesc->mem = parasite_##blob_type##_blob;					\
+	bdesc->bsize = sizeof(parasite_##blob_type##_blob);				\
+	/* Setup the rest of a control block */						\
+	bdesc->parasite_ip_off = pblob_offset(blob_type, __export_parasite_head_start);	\
+	bdesc->addr_cmd_off    = pblob_offset(blob_type, __export_parasite_cmd);	\
+	bdesc->addr_arg_off    = pblob_offset(blob_type, __export_parasite_args);	\
+	init_blob_relocs(bdesc, blob_type);						\
+	} while (0)
+
 struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		struct vm_area_list *vma_area_list)
 {
 	struct parasite_ctl *ctl;
 	struct infect_ctx *ictx;
+	struct parasite_blob_desc *pbd;
 	unsigned long p;
 
 	BUG_ON(item->threads[0].real != pid);
@@ -564,6 +592,14 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 
 	ictx->log_fd = log_get_fd();
 
+	pbd = compel_parasite_blob_desc(ctl);
+	if (compel_mode_native(ctl))
+		init_blob_desc(pbd, native);
+#ifdef CONFIG_COMPAT
+	else
+		init_blob_desc(pbd, compat);
+#endif
+
 	parasite_ensure_args_size(dump_pages_args_size(vma_area_list));
 	parasite_ensure_args_size(aio_rings_args_size(vma_area_list));
 
-- 
2.7.4



More information about the CRIU mailing list