[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