[CRIU] [PATCH] compel: Prepare for several ways to load blob into libcompel

Pavel Emelyanov xemul at virtuozzo.com
Thu Nov 24 04:21:36 PST 2016


Right now we load blob into libcompel by providing values
from .h file which was generated by "compel hgen" command.

In the future we'd like to provide other ways (e.g. by
pusing mmap()-ed memory with .o file, or by .o file path),
so prepare for such future.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 compel/include/uapi/infect.h | 28 ++++++++++++++++++++--------
 compel/src/lib/infect.c      | 19 +++++++++++--------
 criu/parasite-syscall.c      | 18 ++++++++++--------
 3 files changed, 41 insertions(+), 24 deletions(-)

diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index ffcc1c8..c5a85b9 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -125,15 +125,27 @@ 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
 
+/*
+ * There are several ways to describe a blob to compel
+ * library. The simplest one derived from criu is to
+ * provide it from .h files.
+ */
+#define COMPEL_BLOB_CHEADER	0x1
+
 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;
+	unsigned		parasite_type;
+	union {
+		struct {
+			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;
+		} hdr;
+	};
 };
 
 extern struct parasite_blob_desc *compel_parasite_blob_desc(struct parasite_ctl *);
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index b85f36e..df95f5e 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -845,6 +845,9 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
 	int ret;
 	unsigned long p, map_exchange_size, parasite_size = 0;
 
+	if (ctl->pblob.parasite_type != COMPEL_BLOB_CHEADER)
+		goto err;
+
 	if (ctl->ictx.log_fd < 0)
 		goto err;
 
@@ -858,7 +861,7 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
 	 * without using ptrace at all.
 	 */
 
-	parasite_size = ctl->pblob.size;
+	parasite_size = ctl->pblob.hdr.size;
 
 	ctl->args_size = round_up(args_size, PAGE_SIZE);
 	parasite_size += ctl->args_size;
@@ -874,14 +877,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);
 
-	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;
+	ctl->parasite_ip = (unsigned long)(ctl->remote_map + ctl->pblob.hdr.parasite_ip_off);
+	ctl->addr_cmd = ctl->local_map + ctl->pblob.hdr.addr_cmd_off;
+	ctl->addr_args = ctl->local_map + ctl->pblob.hdr.addr_arg_off;
 
-	memcpy(ctl->local_map, ctl->pblob.mem, ctl->pblob.size);
-	if (ctl->pblob.nr_relocs)
-		compel_relocs_apply(ctl->local_map, ctl->remote_map, ctl->pblob.bsize,
-				    ctl->pblob.relocs, ctl->pblob.nr_relocs);
+	memcpy(ctl->local_map, ctl->pblob.hdr.mem, ctl->pblob.hdr.size);
+	if (ctl->pblob.hdr.nr_relocs)
+		compel_relocs_apply(ctl->local_map, ctl->remote_map, ctl->pblob.hdr.bsize,
+				    ctl->pblob.hdr.relocs, ctl->pblob.hdr.nr_relocs);
 
 	p = parasite_size;
 
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 8984d70..ac33fbf 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -539,21 +539,21 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe *
 #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);		\
+		bdesc->hdr.relocs = parasite_##blob_type##_relocs;			\
+		bdesc->hdr.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);				\
+	bdesc->hdr.size = pie_size(parasite_##blob_type);				\
+	bdesc->hdr.mem = parasite_##blob_type##_blob;					\
+	bdesc->hdr.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);	\
+	bdesc->hdr.parasite_ip_off = pblob_offset(blob_type, __export_parasite_head_start);\
+	bdesc->hdr.addr_cmd_off    = pblob_offset(blob_type, __export_parasite_cmd);	\
+	bdesc->hdr.addr_arg_off    = pblob_offset(blob_type, __export_parasite_args);	\
 	init_blob_relocs(bdesc, blob_type);						\
 	} while (0)
 
@@ -605,6 +605,8 @@ 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);
+	pbd->parasite_type = COMPEL_BLOB_CHEADER;
+
 	if (compel_mode_native(ctl))
 		init_blob_desc(pbd, native);
 #ifdef CONFIG_COMPAT
-- 
2.5.0


More information about the CRIU mailing list