[CRIU] [PATCH 22/22] compel: Move in parasite engine
Cyrill Gorcunov
gorcunov at openvz.org
Wed Oct 19 12:21:37 PDT 2016
Here we move parasite engine into compel library
and start using it in criu.
Note that currently the compel relies on piegen mode
which creates binary blob via parasite_blob_desc_t
structure but in future we will implement complete
runtime loader of object files so the parasite will
be external object module which criu upload into
dumpee and run with compel help.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
compel/Makefile | 3 +
.../aarch64/src/lib/include/compel/asm/infect.h | 6 +
.../arch/aarch64/src/lib}/infect.c | 57 ++--
.../arch/arm/src/lib/include/compel/asm/infect.h | 6 +
.../arch/arm => compel/arch/arm/src/lib}/infect.c | 64 ++---
.../arch/ppc64/src/lib/include/compel/asm/infect.h | 6 +
compel/arch/ppc64/src/lib/infect.c | 85 ++++++
.../arch/x86/src/lib/include/compel/asm/infect.h | 6 +
.../arch/x86 => compel/arch/x86/src/lib}/infect.c | 97 ++-----
compel/include/compel/err.h | 1 +
.../include/compel}/infect-priv.h | 9 +-
compel/include/compel/infect.h | 21 ++
compel/include/compel/signal.h | 1 +
compel/include/uapi/compel/compel.h | 179 ++++++++++++
{criu => compel/src/lib}/infect-rpc.c | 17 +-
{criu => compel/src/lib}/infect.c | 128 ++++++---
criu/Makefile.crtools | 2 -
criu/aio.c | 5 +-
criu/arch/aarch64/Makefile | 1 -
criu/arch/aarch64/crtools.c | 8 -
criu/arch/aarch64/include/asm/dump.h | 2 +
criu/arch/aarch64/include/asm/parasite-syscall.h | 8 -
criu/arch/arm/Makefile | 1 -
criu/arch/arm/crtools.c | 12 -
criu/arch/arm/include/asm/dump.h | 2 +
criu/arch/arm/include/asm/parasite-syscall.h | 6 -
criu/arch/ppc64/Makefile | 1 -
criu/arch/ppc64/crtools.c | 15 -
criu/arch/ppc64/include/asm/dump.h | 2 +
criu/arch/ppc64/include/asm/parasite-syscall.h | 8 -
criu/arch/ppc64/infect.c | 308 ---------------------
criu/arch/x86/Makefile | 1 -
criu/arch/x86/crtools.c | 23 +-
criu/arch/x86/include/asm/dump.h | 2 +
criu/arch/x86/include/asm/parasite-syscall.h | 10 -
criu/arch/x86/sys-exec-tbl.c | 2 +-
criu/cr-exec.c | 3 -
criu/cr-restore.c | 2 -
criu/include/errno.h | 9 -
criu/include/infect-rpc.h | 20 --
criu/include/infect.h | 108 --------
criu/include/parasite-syscall.h | 5 -
criu/include/parasite.h | 31 +--
criu/include/proc_parse.h | 4 +-
criu/mem.c | 4 +-
criu/parasite-syscall.c | 38 ++-
criu/pie/parasite.c | 12 +-
criu/seize.c | 3 +-
criu/vdso.c | 5 +-
49 files changed, 547 insertions(+), 802 deletions(-)
create mode 100644 compel/arch/aarch64/src/lib/include/compel/asm/infect.h
rename {criu/arch/aarch64 => compel/arch/aarch64/src/lib}/infect.c (61%)
create mode 100644 compel/arch/arm/src/lib/include/compel/asm/infect.h
rename {criu/arch/arm => compel/arch/arm/src/lib}/infect.c (57%)
create mode 100644 compel/arch/ppc64/src/lib/include/compel/asm/infect.h
create mode 100644 compel/arch/ppc64/src/lib/infect.c
create mode 100644 compel/arch/x86/src/lib/include/compel/asm/infect.h
rename {criu/arch/x86 => compel/arch/x86/src/lib}/infect.c (53%)
create mode 120000 compel/include/compel/err.h
rename {criu/include => compel/include/compel}/infect-priv.h (88%)
create mode 100644 compel/include/compel/infect.h
create mode 120000 compel/include/compel/signal.h
rename {criu => compel/src/lib}/infect-rpc.c (90%)
rename {criu => compel/src/lib}/infect.c (90%)
delete mode 100644 criu/arch/aarch64/include/asm/parasite-syscall.h
delete mode 100644 criu/arch/arm/include/asm/parasite-syscall.h
delete mode 100644 criu/arch/ppc64/include/asm/parasite-syscall.h
delete mode 100644 criu/arch/ppc64/infect.c
delete mode 100644 criu/arch/x86/include/asm/parasite-syscall.h
delete mode 100644 criu/include/errno.h
delete mode 100644 criu/include/infect-rpc.h
delete mode 100644 criu/include/infect.h
diff --git a/compel/Makefile b/compel/Makefile
index adf864eb383f..b4e15892682c 100644
--- a/compel/Makefile
+++ b/compel/Makefile
@@ -28,6 +28,9 @@ lib-y += src/lib/compel.o
lib-y += arch/$(ARCH)/src/lib/cpu.o
lib-y += arch/$(ARCH)/src/lib/sigframe.o
lib-y += src/lib/ptrace.o
+lib-y += src/lib/infect-rpc.o
+lib-y += arch/$(ARCH)/src/lib/infect.o
+lib-y += src/lib/infect.o
#
# This requires arch specific header to
diff --git a/compel/arch/aarch64/src/lib/include/compel/asm/infect.h b/compel/arch/aarch64/src/lib/include/compel/asm/infect.h
new file mode 100644
index 000000000000..05faf08f4b37
--- /dev/null
+++ b/compel/arch/aarch64/src/lib/include/compel/asm/infect.h
@@ -0,0 +1,6 @@
+#ifndef COMPEL_ASM_INFECT_H__
+#define COMPEL_ASM_INFECT_H__
+
+#define BUILTIN_SYSCALL_SIZE 8
+
+#endif /* COMPEL_ASM_INFECT_H__ */
diff --git a/criu/arch/aarch64/infect.c b/compel/arch/aarch64/src/lib/infect.c
similarity index 61%
rename from criu/arch/aarch64/infect.c
rename to compel/arch/aarch64/src/lib/infect.c
index aaa91b8c162a..d0111701d76c 100644
--- a/criu/arch/aarch64/infect.c
+++ b/compel/arch/aarch64/src/lib/infect.c
@@ -1,16 +1,20 @@
-#include <sys/ptrace.h>
-#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
-#include <compel/plugins/std/syscall-codes.h>
+#include <sys/mman.h>
+#include <errno.h>
-#include "asm/parasite-syscall.h"
+#include "asm/processor-flags.h"
+#include "asm/infect.h"
#include "asm/types.h"
-#include "criu-log.h"
-#include "kerndat.h"
-#include "parasite-syscall.h"
-#include "errno.h"
+
+#include "compiler.h"
#include "infect.h"
#include "infect-priv.h"
+#include "bug.h"
+#include "err.h"
+
+#include <compel/plugins/std/syscall-codes.h>
/*
* Injected syscall instruction
@@ -29,33 +33,6 @@ static inline void __always_unused __check_code_syscall(void)
BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
}
-int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg)
-{
- struct iovec iov;
- user_fpregs_struct_t fpsimd;
- int ret;
-
- pr_info("Dumping GP/FPU registers for %d\n", pid);
-
- iov.iov_base = ®s;
- iov.iov_len = sizeof(user_regs_struct_t);
- if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov))) {
- pr_perror("Failed to obtain CPU registers for %d", pid);
- goto err;
- }
-
- iov.iov_base = &fpsimd;
- iov.iov_len = sizeof(fpsimd);
- if ((ret = ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov))) {
- pr_perror("Failed to obtain FPU registers for %d", pid);
- goto err;
- }
-
- ret = save(arg, ®s, &fpsimd);
-err:
- return ret;
-}
-
int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
unsigned long arg1,
unsigned long arg2,
@@ -83,7 +60,14 @@ int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
return err;
}
-void *mmap_re(struct parasite_ctl *ctl,
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
+{
+ regs->pc = new_ip;
+ if (stack)
+ regs->sp = (unsigned long)stack;
+}
+
+void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset)
{
@@ -97,4 +81,3 @@ void *mmap_re(struct parasite_ctl *ctl,
return (void *)map;
}
-
diff --git a/compel/arch/arm/src/lib/include/compel/asm/infect.h b/compel/arch/arm/src/lib/include/compel/asm/infect.h
new file mode 100644
index 000000000000..05faf08f4b37
--- /dev/null
+++ b/compel/arch/arm/src/lib/include/compel/asm/infect.h
@@ -0,0 +1,6 @@
+#ifndef COMPEL_ASM_INFECT_H__
+#define COMPEL_ASM_INFECT_H__
+
+#define BUILTIN_SYSCALL_SIZE 8
+
+#endif /* COMPEL_ASM_INFECT_H__ */
diff --git a/criu/arch/arm/infect.c b/compel/arch/arm/src/lib/infect.c
similarity index 57%
rename from criu/arch/arm/infect.c
rename to compel/arch/arm/src/lib/infect.c
index 6f87a33d23d8..6d65cb8815f7 100644
--- a/criu/arch/arm/infect.c
+++ b/compel/arch/arm/src/lib/infect.c
@@ -1,16 +1,20 @@
-#include <sys/ptrace.h>
-#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
-#include <compel/plugins/std/syscall-codes.h>
+#include <sys/mman.h>
+#include <errno.h>
-#include "asm/parasite-syscall.h"
+#include "asm/processor-flags.h"
+#include "asm/infect.h"
#include "asm/types.h"
-#include "criu-log.h"
-#include "kerndat.h"
-#include "parasite-syscall.h"
-#include "errno.h"
+
+#include "compiler.h"
#include "infect.h"
#include "infect-priv.h"
+#include "bug.h"
+#include "err.h"
+
+#include "uapi/compel/plugins/std/syscall-codes.h"
/*
* Injected syscall instruction
@@ -29,39 +33,14 @@ static inline __always_unused void __check_code_syscall(void)
BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
}
-#define PTRACE_GETVFPREGS 27
-int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg)
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
{
- user_fpregs_struct_t vfp;
- int ret = -1;
-
- pr_info("Dumping GP/FPU registers for %d\n", pid);
-
- if (ptrace(PTRACE_GETVFPREGS, pid, NULL, &vfp)) {
- pr_perror("Can't obtain FPU registers for %d", pid);
- goto err;
- }
-
- /* Did we come from a system call? */
- if ((int)regs.ARM_ORIG_r0 >= 0) {
- /* Restart the system call */
- switch ((long)(int)regs.ARM_r0) {
- case -ERESTARTNOHAND:
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- regs.ARM_r0 = regs.ARM_ORIG_r0;
- regs.ARM_pc -= 4;
- break;
- case -ERESTART_RESTARTBLOCK:
- regs.ARM_r0 = __NR_restart_syscall;
- regs.ARM_pc -= 4;
- break;
- }
- }
-
- ret = save(arg, ®s, &vfp);
-err:
- return ret;
+ regs->ARM_pc = new_ip;
+ if (stack)
+ regs->ARM_sp = (unsigned long)stack;
+
+ /* Make sure flags are in known state */
+ regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | MODE32_BIT;
}
int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
@@ -101,9 +80,10 @@ void *remote_mmap(struct parasite_ctl *ctl,
err = compel_syscall(ctl, __NR_mmap2, &map,
(unsigned long)addr, length, prot, flags, fd, offset >> 12);
- if (err < 0 || map > kdat.task_size)
+ // FIXME @kdat?
+// if (err < 0 || map > kdat.task_size)
+ if (err < 0)
map = 0;
return (void *)map;
}
-
diff --git a/compel/arch/ppc64/src/lib/include/compel/asm/infect.h b/compel/arch/ppc64/src/lib/include/compel/asm/infect.h
new file mode 100644
index 000000000000..05faf08f4b37
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/include/compel/asm/infect.h
@@ -0,0 +1,6 @@
+#ifndef COMPEL_ASM_INFECT_H__
+#define COMPEL_ASM_INFECT_H__
+
+#define BUILTIN_SYSCALL_SIZE 8
+
+#endif /* COMPEL_ASM_INFECT_H__ */
diff --git a/compel/arch/ppc64/src/lib/infect.c b/compel/arch/ppc64/src/lib/infect.c
new file mode 100644
index 000000000000..815cf8b61acc
--- /dev/null
+++ b/compel/arch/ppc64/src/lib/infect.c
@@ -0,0 +1,85 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include <sys/mman.h>
+#include <errno.h>
+
+#include "asm/processor-flags.h"
+#include "asm/infect.h"
+#include "asm/types.h"
+
+#include "compiler.h"
+#include "infect.h"
+#include "infect-priv.h"
+#include "bug.h"
+#include "err.h"
+
+#include "uapi/compel/plugins/std/syscall-codes.h"
+
+/*
+ * Injected syscall instruction
+ */
+const uint32_t code_syscall[] = {
+ 0x44000002, /* sc */
+ 0x0fe00000 /* twi 31,0,0 */
+};
+
+static inline void __check_code_syscall(void)
+{
+ BUILD_BUG_ON(sizeof(code_syscall) != BUILTIN_SYSCALL_SIZE);
+ BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
+}
+
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
+{
+ /*
+ * OpenPOWER ABI requires that r12 is set to the calling function addressi
+ * to compute the TOC pointer.
+ */
+ regs->gpr[12] = new_ip;
+ regs->nip = new_ip;
+ if (stack)
+ regs->gpr[1] = (unsigned long) stack;
+ regs->trap = 0;
+}
+
+int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1,
+ unsigned long arg2,
+ unsigned long arg3,
+ unsigned long arg4,
+ unsigned long arg5,
+ unsigned long arg6)
+{
+ user_regs_struct_t regs = ctl->orig.regs;
+ int err;
+
+ regs.gpr[0] = (unsigned long)nr;
+ regs.gpr[3] = arg1;
+ regs.gpr[4] = arg2;
+ regs.gpr[5] = arg3;
+ regs.gpr[6] = arg4;
+ regs.gpr[7] = arg5;
+ regs.gpr[8] = arg6;
+
+ err = compel_execute_syscall(ctl, ®s, (char*)code_syscall);
+
+ *ret = regs.gpr[3];
+ return err;
+}
+
+void *remote_mmap(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset)
+{
+ unsigned long map = 0;
+ int err;
+
+ err = compel_syscall(ctl, __NR_mmap, &map,
+ (unsigned long)addr, length, prot, flags, fd, offset);
+ if (err < 0 || (long)map < 0)
+ map = 0;
+
+ return (void *)map;
+}
diff --git a/compel/arch/x86/src/lib/include/compel/asm/infect.h b/compel/arch/x86/src/lib/include/compel/asm/infect.h
new file mode 100644
index 000000000000..05faf08f4b37
--- /dev/null
+++ b/compel/arch/x86/src/lib/include/compel/asm/infect.h
@@ -0,0 +1,6 @@
+#ifndef COMPEL_ASM_INFECT_H__
+#define COMPEL_ASM_INFECT_H__
+
+#define BUILTIN_SYSCALL_SIZE 8
+
+#endif /* COMPEL_ASM_INFECT_H__ */
diff --git a/criu/arch/x86/infect.c b/compel/arch/x86/src/lib/infect.c
similarity index 53%
rename from criu/arch/x86/infect.c
rename to compel/arch/x86/src/lib/infect.c
index 70423f6e34c3..4503a816e8ca 100644
--- a/criu/arch/x86/infect.c
+++ b/compel/arch/x86/src/lib/infect.c
@@ -1,19 +1,20 @@
-#include <sys/ptrace.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/auxv.h>
-#include <sys/mman.h>
+#include <stdlib.h>
+#include <stdio.h>
-#include <compel/plugins/std/syscall-codes.h>
-#include <compel/cpu.h>
+#include <sys/mman.h>
+#include <errno.h>
-#include "asm/parasite-syscall.h"
-#include "err.h"
+#include "asm/processor-flags.h"
+#include "asm/infect.h"
#include "asm/types.h"
-#include "errno.h"
-#include "parasite-syscall.h"
+
+#include "compiler.h"
#include "infect.h"
#include "infect-priv.h"
+#include "bug.h"
+#include "err.h"
+
+#include "uapi/compel/plugins/std/syscall-codes.h"
/*
* Injected syscall instruction
@@ -40,71 +41,21 @@ static inline __always_unused void __check_code_syscall(void)
BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
}
-#define get_signed_user_reg(pregs, name) \
- ((user_regs_native(pregs)) ? (int64_t)((pregs)->native.name) : \
- (int32_t)((pregs)->compat.name))
-
-int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg)
+/*
+ * regs must be inited when calling this function from original context
+ */
+void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
{
- user_fpregs_struct_t xsave = { }, *xs = NULL;
-
- struct iovec iov;
- int ret = -1;
-
- pr_info("Dumping general registers for %d in %s mode\n", pid,
- user_regs_native(®s) ? "native" : "compat");
-
- /* Did we come from a system call? */
- if (get_signed_user_reg(®s, orig_ax) >= 0) {
- /* Restart the system call */
- switch (get_signed_user_reg(®s, ax)) {
- case -ERESTARTNOHAND:
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- set_user_reg(®s, ax, get_user_reg(®s, orig_ax));
- set_user_reg(®s, ip, get_user_reg(®s, ip) - 2);
- break;
- case -ERESTART_RESTARTBLOCK:
- pr_warn("Will restore %d with interrupted system call\n", pid);
- set_user_reg(®s, ax, -EINTR);
- break;
- }
- }
-
-#ifndef PTRACE_GETREGSET
-# define PTRACE_GETREGSET 0x4204
-#endif
-
- if (!cpu_has_feature(X86_FEATURE_FPU))
- goto out;
-
- /*
- * FPU fetched either via fxsave or via xsave,
- * thus decode it accrodingly.
- */
+ set_user_reg(regs, ip, new_ip);
+ if (stack)
+ set_user_reg(regs, sp, (unsigned long) stack);
- pr_info("Dumping GP/FPU registers for %d\n", pid);
-
- if (cpu_has_feature(X86_FEATURE_XSAVE)) {
- iov.iov_base = &xsave;
- iov.iov_len = sizeof(xsave);
-
- if (ptrace(PTRACE_GETREGSET, pid, (unsigned int)NT_X86_XSTATE, &iov) < 0) {
- pr_perror("Can't obtain FPU registers for %d", pid);
- goto err;
- }
- } else {
- if (ptrace(PTRACE_GETFPREGS, pid, NULL, &xsave)) {
- pr_perror("Can't obtain FPU registers for %d", pid);
- goto err;
- }
- }
+ /* Avoid end of syscall processing */
+ set_user_reg(regs, orig_ax, -1);
- xs = &xsave;
-out:
- ret = save(arg, ®s, xs);
-err:
- return ret;
+ /* Make sure flags are in known state */
+ set_user_reg(regs, flags, get_user_reg(regs, flags) &
+ ~(X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_IF));
}
int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
diff --git a/compel/include/compel/err.h b/compel/include/compel/err.h
new file mode 120000
index 000000000000..62323ce5b06f
--- /dev/null
+++ b/compel/include/compel/err.h
@@ -0,0 +1 @@
+../../../criu/include/err.h
\ No newline at end of file
diff --git a/criu/include/infect-priv.h b/compel/include/compel/infect-priv.h
similarity index 88%
rename from criu/include/infect-priv.h
rename to compel/include/compel/infect-priv.h
index 3ddd1175f754..3766ef2b134a 100644
--- a/criu/include/infect-priv.h
+++ b/compel/include/compel/infect-priv.h
@@ -1,8 +1,11 @@
-#ifndef __COMPEL_INFECT_PRIV_H__
-#define __COMPEL_INFECT_PRIV_H__
+#ifndef COMPEL_INFECT_PRIV_H__
+#define COMPEL_INFECT_PRIV_H__
#include <stdbool.h>
+#include "uapi/compel/plugins/std/syscall-types.h"
+#include "uapi/compel/compel.h"
+
/* parasite control block */
struct parasite_ctl {
int rpid; /* Real pid of the victim */
@@ -49,4 +52,4 @@ extern int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
extern void *remote_mmap(struct parasite_ctl *ctl,
void *addr, size_t length, int prot,
int flags, int fd, off_t offset);
-#endif
+#endif /* COMPEL_INFECT_PRIV_H__ */
diff --git a/compel/include/compel/infect.h b/compel/include/compel/infect.h
new file mode 100644
index 000000000000..9db6a7b22e83
--- /dev/null
+++ b/compel/include/compel/infect.h
@@ -0,0 +1,21 @@
+#ifndef COMPEL_INFECT_H__
+#define COMPEL_INFECT_H__
+
+#include <stdint.h>
+#include <sys/un.h>
+
+#include "asm/infect.h"
+#include "asm/types.h"
+
+struct parasite_ctl;
+
+extern void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
+extern int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
+ unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5, unsigned long arg6);
+extern void *mmap_seized(struct parasite_ctl *ctl,
+ void *addr, size_t length, int prot,
+ int flags, int fd, off_t offset);
+
+#endif /* COMPEL_INFECT_H__ */
diff --git a/compel/include/compel/signal.h b/compel/include/compel/signal.h
new file mode 120000
index 000000000000..c8868266d8fa
--- /dev/null
+++ b/compel/include/compel/signal.h
@@ -0,0 +1 @@
+../../../criu/include/signal.h
\ No newline at end of file
diff --git a/compel/include/uapi/compel/compel.h b/compel/include/uapi/compel/compel.h
index c0828fdfbb2d..7e1e4fcc1745 100644
--- a/compel/include/uapi/compel/compel.h
+++ b/compel/include/uapi/compel/compel.h
@@ -1,8 +1,17 @@
#ifndef UAPI_COMPEL_H__
#define UAPI_COMPEL_H__
+#include <stdint.h>
+#include <signal.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#include <compel/asm/types.h>
+#include <compel/asm/sigframe.h>
+#include <compel/lock.h>
+
#define COMPEL_TYPE_INT (1u << 0)
#define COMPEL_TYPE_LONG (1u << 1)
#define COMPEL_TYPE_GOTPCREL (1u << 2)
@@ -35,4 +44,174 @@ extern unsigned int compel_log_get_loglevel(void);
extern int compel_log_get_fd(void);
extern void compel_log_set_fd(int fd);
+/*
+ * Parasite engine
+ */
+
+struct parasite_ctl;
+
+extern int compel_rpc_sync(unsigned int cmd, struct parasite_ctl *ctl);
+extern int compel_rpc_call(unsigned int cmd, struct parasite_ctl *ctl);
+extern int compel_rpc_call_sync(unsigned int cmd, struct parasite_ctl *ctl);
+extern int compel_rpc_sock(struct parasite_ctl *ctl);
+
+struct ctl_msg {
+ uint32_t cmd; /* command itself */
+ uint32_t ack; /* ack on command */
+ uint32_t err; /* error code on reply */
+};
+
+#define ctl_msg_cmd(_cmd) (struct ctl_msg){ .cmd = _cmd, }
+#define ctl_msg_ack(_cmd, _err) (struct ctl_msg){ .cmd = _cmd, .ack = _cmd, .err = _err, }
+
+struct parasite_unmap_args {
+ uint64_t parasite_start;
+ uint64_t parasite_len;
+};
+
+typedef struct {
+ void * blob;
+ size_t blob_size;
+ size_t pie_size;
+ unsigned long (*get_parasite_ip)(void *remote_map);
+ unsigned int * (*get_addr_cmd)(void *local_map);
+ void * (*get_addr_args)(void *local_map);
+ void (*postproc)(void *local_map, void *remote_map);
+} parasite_blob_desc_t;
+
+enum {
+ COMPEL_PARASITE_CMD_IDLE = 0,
+ COMPEL_PARASITE_CMD_ACK = 100,
+ COMPEL_PARASITE_CMD_INIT_DAEMON = 200,
+ COMPEL_PARASITE_CMD_UNMAP = 300,
+ COMPEL_PARASITE_CMD_FINI = 400,
+
+ /*
+ * Custom user commands should start from here.
+ */
+ COMPEL_PARASITE_CMD_USR_BASE = 500,
+};
+
+#define PARASITE_ARG_SIZE_MIN (1 << 12)
+#define PARASITE_START_AREA_MIN (4096)
+
+#define compel_parasite_args(ctl, type) \
+ ({ \
+ void *___ret; \
+ BUILD_BUG_ON(sizeof(type) > PARASITE_ARG_SIZE_MIN); \
+ ___ret = compel_parasite_args_p(ctl); \
+ ___ret; \
+ })
+
+extern void *compel_parasite_args_p(struct parasite_ctl *ctl);
+extern void *compel_parasite_args_s(struct parasite_ctl *ctl, int args_size);
+
+extern int compel_execute_syscall(struct parasite_ctl *ctl,
+ user_regs_struct_t *regs,
+ const char *code_syscall);
+
+#define COMPEL_PARASITE_STACK_SIZE (16 << 10)
+
+struct parasite_init_args {
+ int32_t h_addr_len;
+ struct sockaddr_un h_addr;
+ int32_t log_level;
+ uint64_t sigreturn_addr;
+ uint64_t sigframe; /* pointer to sigframe */
+ futex_t daemon_connected;
+};
+
+struct seize_task_status {
+ char state;
+ int ppid;
+ unsigned long long sigpnd;
+ unsigned long long shdpnd;
+ int seccomp_mode;
+};
+
+struct thread_ctx {
+ k_rtsigset_t sigmask;
+ user_regs_struct_t regs;
+};
+
+/*
+ * FIXME -- these should be mapped to CRIU's pid.h's
+ */
+
+#define TASK_ALIVE 0x1
+#define TASK_DEAD 0x2
+#define TASK_STOPPED 0x3
+#define TASK_ZOMBIE 0x6
+
+struct infect_ctx {
+ int *p_sock;
+
+ /*
+ * Regs manipulation context.
+ */
+ int (*save_regs)(void *arg, user_regs_struct_t *regs,
+ user_fpregs_struct_t *f);
+ int (*make_sigframe)(void *arg, struct rt_sigframe *sf,
+ struct rt_sigframe *rtsf,
+ k_rtsigset_t *bs);
+ void *regs_arg;
+
+ unsigned long syscall_ip; /* entry point of infection */
+ unsigned long flags; /* fine-tune (e.g. faults) */
+
+ /* Hander for SIGCHLD deaths */
+ void (*child_handler)(int signal, siginfo_t *siginfo,
+ void *data);
+};
+
+extern struct parasite_ctl *compel_prepare(pid_t pid);
+extern int compel_infect(struct parasite_ctl *ctl,
+ parasite_blob_desc_t *d,
+ unsigned long nr_threads,
+ unsigned long args_size);
+extern int compel_prepare_thread(pid_t pid, struct thread_ctx *ctx);
+extern int compel_run_in_thread(pid_t pid, unsigned int cmd,
+ struct parasite_ctl *ctl,
+ struct thread_ctx *octx);
+extern int compel_stop_daemon(struct parasite_ctl *ctl);
+extern int compel_cure_remote(struct parasite_ctl *ctl);
+extern int compel_cure_local(struct parasite_ctl *ctl);
+extern int compel_cure(struct parasite_ctl *ctl);
+
+/*
+ * The PTRACE_SYSCALL will trap task twice -- on
+ * enter into and on exit from syscall. If we trace
+ * a single task, we may skip half of all getregs
+ * calls -- on exit we don't need them.
+ */
+enum trace_flags {
+ TRACE_ALL,
+ TRACE_ENTER,
+ TRACE_EXIT,
+};
+
+extern int compel_stop_on_syscall(int tasks, int sys_nr,
+ int sys_nr_compat,
+ enum trace_flags trace);
+
+extern int compel_stop_pie(pid_t pid, void *addr,
+ enum trace_flags *tf, bool no_bp);
+extern int compel_unmap(struct parasite_ctl *ctl, unsigned long addr);
+
+extern int compel_stop_task(pid_t pid);
+extern int compel_wait_task(pid_t pid, pid_t ppid,
+ int (*get_status)(pid_t pid, struct seize_task_status *ss),
+ struct seize_task_status *ss);
+extern int compel_unseize_task(pid_t pid, int orig_state, int st);
+
+#define INFECT_NO_MEMFD 0x1 /* don't use memfd() */
+#define INFECT_FAIL_CONNECT 0x2 /* make parasite connect() fail */
+#define INFECT_NO_BREAKPOINTS 0x4 /* no breakpoints in pie tracking */
+
+extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *ctl);
+
+extern int compel_mode_native(struct parasite_ctl *ctl);
+
+extern k_rtsigset_t *compel_task_sigmask(struct parasite_ctl *ctl);
+
#endif /* UAPI_COMPEL_H__ */
diff --git a/criu/infect-rpc.c b/compel/src/lib/infect-rpc.c
similarity index 90%
rename from criu/infect-rpc.c
rename to compel/src/lib/infect-rpc.c
index 0084495acbcf..097b177a38c5 100644
--- a/criu/infect-rpc.c
+++ b/compel/src/lib/infect-rpc.c
@@ -1,9 +1,14 @@
-#include "xmalloc.h"
-#include "parasite.h"
-#include "parasite-syscall.h"
-#include "infect.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <compel/compel.h>
+
#include "infect-priv.h"
-#include "infect-rpc.h"
+#include "log.h"
static int __parasite_send_cmd(int sockfd, struct ctl_msg *m)
{
@@ -30,7 +35,7 @@ int parasite_wait_ack(int sockfd, unsigned int cmd, struct ctl_msg *m)
pr_debug("Wait for ack %d on daemon socket\n", cmd);
while (1) {
- memzero(m, sizeof(*m));
+ memset(m, 0, sizeof(*m));
ret = recv(sockfd, m, sizeof(*m), MSG_WAITALL);
if (ret == -1) {
diff --git a/criu/infect.c b/compel/src/lib/infect.c
similarity index 90%
rename from criu/infect.c
rename to compel/src/lib/infect.c
index 002500f167ac..2882148b1be5 100644
--- a/criu/infect.c
+++ b/compel/src/lib/infect.c
@@ -1,38 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdint.h>
+
#include <sys/wait.h>
#include <sys/types.h>
+#include <sys/socket.h>
#include <sys/ptrace.h>
-#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/un.h>
+
#include <errno.h>
#include <signal.h>
+
#include <linux/seccomp.h>
-#include <compel/asm/sigframe.h>
+#include <compel/plugins/std/syscall-codes.h>
+#include <compel/ptrace.h>
+#include <compel/compel.h>
+
+#include "uapi/compel/plugins/plugin-fds.h"
-#include "ptrace.h"
-#include "signal.h"
-#include "asm/parasite-syscall.h"
-#include "asm/dump.h"
-#include "restorer.h"
-#include "parasite.h"
-#include "parasite-syscall.h"
-#include "pie-relocs.h"
-#include "parasite-blob.h"
-#include "log.h"
#include "infect.h"
-#include "infect-rpc.h"
#include "infect-priv.h"
-#define PTRACE_EVENT_STOP 128
+#include "xmalloc.h"
+#include "signal.h"
+#include "log.h"
+#include "bug.h"
-#ifndef SECCOMP_MODE_DISABLED
-#define SECCOMP_MODE_DISABLED 0
+#ifdef LOG_PREFIX
+#undef LOG_PREFIX
#endif
-#ifndef PTRACE_O_SUSPEND_SECCOMP
-# define PTRACE_O_SUSPEND_SECCOMP (1 << 21)
-#endif
+#define LOG_PREFIX "compel: infect: "
+
+#define UNIX_PATH_MAX (sizeof(struct sockaddr_un) - \
+ (size_t)((struct sockaddr_un *) 0)->sun_path)
-#define SI_EVENT(_si_code) (((_si_code) & 0xFFFF) >> 8)
+#define close_safe(x) if (*(x) >= 0) { close(*(x)); *(x) = -1; }
int compel_stop_task(int pid)
{
@@ -125,7 +132,7 @@ static int do_suspend_seccomp(pid_t pid)
* up with someone else.
*/
int compel_wait_task(int pid, int ppid,
- int (*get_status)(int pid, struct seize_task_status *),
+ int (*get_status)(int pid, struct seize_task_status *ss),
struct seize_task_status *ss)
{
siginfo_t si;
@@ -477,7 +484,7 @@ int compel_execute_syscall(struct parasite_ctl *ctl,
{
pid_t pid = ctl->rpid;
int err;
- u8 code_orig[BUILTIN_SYSCALL_SIZE];
+ uint8_t code_orig[BUILTIN_SYSCALL_SIZE];
/*
* Inject syscall instruction and remember original code,
@@ -525,13 +532,14 @@ static int parasite_init_daemon(struct parasite_ctl *ctl)
pid_t pid = ctl->rpid;
user_regs_struct_t regs;
struct ctl_msg m = { };
+ int rpc_sk;
- *ctl->addr_cmd = PARASITE_CMD_INIT_DAEMON;
+ *ctl->addr_cmd = COMPEL_PARASITE_CMD_INIT_DAEMON;
args = compel_parasite_args(ctl, struct parasite_init_args);
args->sigframe = (uintptr_t)ctl->rsigframe;
- args->log_level = log_get_loglevel();
+ args->log_level = compel_log_get_loglevel();
futex_set(&args->daemon_connected, 0);
@@ -556,12 +564,15 @@ static int parasite_init_daemon(struct parasite_ctl *ctl)
if (accept_tsock(ctl) < 0)
goto err;
- if (parasite_send_fd(ctl, log_get_fd()))
+ rpc_sk = compel_rpc_sock(ctl);
+ if (send_fd(rpc_sk, NULL, 0, compel_log_get_fd()) < 0) {
+ pr_perror("Can't send file descriptor");
goto err;
+ }
pr_info("Wait for parasite being daemonized...\n");
- if (parasite_wait_ack(ctl->tsock, PARASITE_CMD_INIT_DAEMON, &m)) {
+ if (parasite_wait_ack(ctl->tsock, COMPEL_PARASITE_CMD_INIT_DAEMON, &m)) {
pr_err("Can't switch parasite %d to daemon mode %d\n",
pid, m.err);
goto err;
@@ -602,6 +613,7 @@ static int parasite_start_daemon(struct parasite_ctl *ctl)
static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
{
+ char path[64];
int fd;
ctl->remote_map = remote_mmap(ctl, NULL, size,
@@ -614,10 +626,13 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
ctl->map_length = round_up(size, page_size());
- fd = open_proc_rw(ctl->rpid, "map_files/%p-%p",
- ctl->remote_map, ctl->remote_map + ctl->map_length);
- if (fd < 0)
+ snprintf(path, sizeof(path), "/proc/%d/map_files/%p-%p",
+ ctl->rpid, ctl->remote_map, ctl->remote_map + ctl->map_length);
+ fd = open(path, O_RDWR);
+ if (fd < 0) {
+ pr_perror("Can't open %s\n", path);
return -1;
+ }
ctl->local_map = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FILE, fd, 0);
@@ -635,11 +650,12 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
{
void *where = (void *)ctl->ictx.syscall_ip + BUILTIN_SYSCALL_SIZE;
- u8 orig_code[MEMFD_FNAME_SZ] = MEMFD_FNAME;
+ uint8_t orig_code[MEMFD_FNAME_SZ] = MEMFD_FNAME;
pid_t pid = ctl->rpid;
unsigned long sret = -ENOSYS;
int ret, fd, lfd;
bool __maybe_unused compat_task = !compel_mode_native(ctl);
+ char path[64];
if (ctl->ictx.flags & INFECT_NO_MEMFD)
return 1;
@@ -673,9 +689,12 @@ static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
return fd;
ctl->map_length = round_up(size, page_size());
- lfd = open_proc_rw(ctl->rpid, "fd/%d", fd);
- if (lfd < 0)
+ snprintf(path, sizeof(path), "/proc/%d/fd/%d", ctl->rpid, fd);
+ lfd = open(path, O_RDWR);
+ if (lfd < 0) {
+ pr_perror("Can't open %s", path);
goto err_cure;
+ }
if (ftruncate(lfd, ctl->map_length) < 0) {
pr_perror("Fail to truncate memfd for parasite");
@@ -738,11 +757,18 @@ int compel_map_exchange(struct parasite_ctl *ctl, unsigned long size)
__export_parasite_args); \
} while (0)
-int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size)
+int compel_infect(struct parasite_ctl *ctl, parasite_blob_desc_t *d,
+ unsigned long nr_threads, unsigned long args_size)
{
int ret;
unsigned long p, map_exchange_size, parasite_size = 0;
+ pr_debug("desc: blob %p blob_size %zd pie_size %zd "
+ "get_parasite_ip %p get_addr_cmd %p "
+ "get_addr_args %p postproc %p\n",
+ d->blob, d->blob_size, d->pie_size, d->get_parasite_ip,
+ d->get_addr_cmd, d->get_addr_args, d->postproc);
+
/*
* Inject a parasite engine. Ie allocate memory inside alien
* space and copy engine code there. Then re-map the engine
@@ -750,20 +776,23 @@ 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);
+ if (compel_mode_native(ctl)) {
+ //parasite_size = pie_size(parasite_native);
+ parasite_size = d->pie_size;
#ifdef CONFIG_COMPAT
- else
- parasite_size = pie_size(parasite_compat);
+ } else {
+ //parasite_size = pie_size(parasite_compat);
+ parasite_size = d->pie_size;
#endif
+ }
ctl->args_size = round_up(args_size, PAGE_SIZE);
parasite_size += ctl->args_size;
map_exchange_size = parasite_size;
- map_exchange_size += RESTORE_STACK_SIGFRAME + PARASITE_STACK_SIZE;
+ map_exchange_size += RESTORE_STACK_SIGFRAME + COMPEL_PARASITE_STACK_SIZE;
if (nr_threads > 1)
- map_exchange_size += PARASITE_STACK_SIZE;
+ map_exchange_size += COMPEL_PARASITE_STACK_SIZE;
ret = compel_map_exchange(ctl, map_exchange_size);
if (ret)
@@ -771,12 +800,22 @@ 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 0
if (compel_mode_native(ctl))
init_parasite_ctl(ctl, native);
#ifdef CONFIG_COMPAT
else
init_parasite_ctl(ctl, compat);
#endif
+#endif
+
+ memcpy(ctl->local_map, d->blob, d->blob_size);
+ ctl->parasite_ip = d->get_parasite_ip(ctl->remote_map);
+ ctl->addr_cmd = d->get_addr_cmd(ctl->local_map);
+ ctl->addr_args = d->get_addr_args(ctl->local_map);
+
+ pr_debug("Calling postproc action\n");
+ d->postproc(ctl->local_map, ctl->remote_map);
p = parasite_size;
@@ -784,11 +823,11 @@ int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned l
ctl->sigframe = ctl->local_map + p;
p += RESTORE_STACK_SIGFRAME;
- p += PARASITE_STACK_SIZE;
+ p += COMPEL_PARASITE_STACK_SIZE;
ctl->rstack = ctl->remote_map + p;
if (nr_threads > 1) {
- p += PARASITE_STACK_SIZE;
+ p += COMPEL_PARASITE_STACK_SIZE;
ctl->r_thread_stack = ctl->remote_map + p;
}
@@ -820,7 +859,8 @@ struct parasite_ctl *compel_prepare(int pid)
{
struct parasite_ctl *ctl = NULL;
- if (!arch_can_dump_task(pid))
+ if (!ptrace_task_compatible(pid))
+// if (!arch_can_dump_task(pid))
goto err;
/*
@@ -895,7 +935,7 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
return -1;
}
- ret = compel_rpc_call(PARASITE_CMD_FINI, ctl);
+ ret = compel_rpc_call(COMPEL_PARASITE_CMD_FINI, ctl);
close_safe(&ctl->tsock);
if (ret)
return -1;
@@ -955,7 +995,7 @@ int compel_cure_remote(struct parasite_ctl *ctl)
if (ctl->addr_cmd) {
struct parasite_unmap_args *args;
- *ctl->addr_cmd = PARASITE_CMD_UNMAP;
+ *ctl->addr_cmd = COMPEL_PARASITE_CMD_UNMAP;
args = compel_parasite_args(ctl, struct parasite_unmap_args);
args->parasite_start = (uintptr_t)ctl->remote_map;
diff --git a/criu/Makefile.crtools b/criu/Makefile.crtools
index 60176cad56b2..fb5f91e8ee58 100644
--- a/criu/Makefile.crtools
+++ b/criu/Makefile.crtools
@@ -3,8 +3,6 @@ ccflags-y += -iquote criu/$(ARCH)
ccflags-y += -I compel/include/uapi
ccflags-y += -I compel/plugins/include/uapi
-obj-y += infect.o
-obj-y += infect-rpc.o
obj-y += action-scripts.o
obj-y += external.o
obj-y += aio.o
diff --git a/criu/aio.c b/criu/aio.c
index 011a1afcf135..8e33576fc150 100644
--- a/criu/aio.c
+++ b/criu/aio.c
@@ -1,6 +1,9 @@
#include <unistd.h>
#include <stdio.h>
#include <stdbool.h>
+
+#include <compel/compel.h>
+
#include "vma.h"
#include "xmalloc.h"
#include "pstree.h"
@@ -11,8 +14,6 @@
#include "parasite.h"
#include "parasite-syscall.h"
#include "images/mm.pb-c.h"
-#include "infect.h"
-#include "infect-rpc.h"
#define NR_IOEVENTS_IN_NPAGES(npages) ((PAGE_SIZE * npages - sizeof(struct aio_ring)) / sizeof(struct io_event))
diff --git a/criu/arch/aarch64/Makefile b/criu/arch/aarch64/Makefile
index 6ae255a8aad9..652d4821bdfd 100644
--- a/criu/arch/aarch64/Makefile
+++ b/criu/arch/aarch64/Makefile
@@ -5,4 +5,3 @@ ccflags-y += -iquote $(obj)/include -iquote $(SRC_DIR)/criu/include
obj-y += cpu.o
obj-y += crtools.o
-obj-y += infect.o
diff --git a/criu/arch/aarch64/crtools.c b/criu/arch/aarch64/crtools.c
index d6b1b1344722..b4f87d5e7417 100644
--- a/criu/arch/aarch64/crtools.c
+++ b/criu/arch/aarch64/crtools.c
@@ -19,14 +19,6 @@
#include "cpu.h"
#include "parasite-syscall.h"
#include "restorer.h"
-#include "infect.h"
-
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
-{
- regs->pc = new_ip;
- if (stack)
- regs->sp = (unsigned long)stack;
-}
bool arch_can_dump_task(pid_t pid)
{
diff --git a/criu/arch/aarch64/include/asm/dump.h b/criu/arch/aarch64/include/asm/dump.h
index 8a966628900b..c53f67c3d487 100644
--- a/criu/arch/aarch64/include/asm/dump.h
+++ b/criu/arch/aarch64/include/asm/dump.h
@@ -1,7 +1,9 @@
#ifndef __CR_ASM_DUMP_H__
#define __CR_ASM_DUMP_H__
+typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
+extern int get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t, void *);
extern int arch_alloc_thread_info(CoreEntry *core);
extern void arch_free_thread_info(CoreEntry *core);
diff --git a/criu/arch/aarch64/include/asm/parasite-syscall.h b/criu/arch/aarch64/include/asm/parasite-syscall.h
deleted file mode 100644
index 4a370f605f57..000000000000
--- a/criu/arch/aarch64/include/asm/parasite-syscall.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __CR_ASM_PARASITE_SYSCALL_H__
-#define __CR_ASM_PARASITE_SYSCALL_H__
-
-struct parasite_ctl;
-
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-
-#endif
diff --git a/criu/arch/arm/Makefile b/criu/arch/arm/Makefile
index 69de18e49585..5db577340a7d 100644
--- a/criu/arch/arm/Makefile
+++ b/criu/arch/arm/Makefile
@@ -4,4 +4,3 @@ ccflags-y += -iquote $(obj) -iquote $(SRC_DIR) -iquote $(obj)/include -iquote $
obj-y += cpu.o
obj-y += crtools.o
-obj-y += infect.o
diff --git a/criu/arch/arm/crtools.c b/criu/arch/arm/crtools.c
index 84e759ad0a8d..10c1de0b50c0 100644
--- a/criu/arch/arm/crtools.c
+++ b/criu/arch/arm/crtools.c
@@ -18,19 +18,7 @@
#include "elf.h"
#include "parasite-syscall.h"
#include "restorer.h"
-#include "errno.h"
#include "kerndat.h"
-#include "infect.h"
-
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
-{
- regs->ARM_pc = new_ip;
- if (stack)
- regs->ARM_sp = (unsigned long)stack;
-
- /* Make sure flags are in known state */
- regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | MODE32_BIT;
-}
bool arch_can_dump_task(pid_t pid)
{
diff --git a/criu/arch/arm/include/asm/dump.h b/criu/arch/arm/include/asm/dump.h
index f08e53843614..fa83b8267710 100644
--- a/criu/arch/arm/include/asm/dump.h
+++ b/criu/arch/arm/include/asm/dump.h
@@ -1,7 +1,9 @@
#ifndef __CR_ASM_DUMP_H__
#define __CR_ASM_DUMP_H__
+typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
+extern int get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t, void *);
extern int arch_alloc_thread_info(CoreEntry *core);
extern void arch_free_thread_info(CoreEntry *core);
diff --git a/criu/arch/arm/include/asm/parasite-syscall.h b/criu/arch/arm/include/asm/parasite-syscall.h
deleted file mode 100644
index 5c880fdaa9d5..000000000000
--- a/criu/arch/arm/include/asm/parasite-syscall.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __CR_ASM_PARASITE_SYSCALL_H__
-#define __CR_ASM_PARASITE_SYSCALL_H__
-
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-
-#endif
diff --git a/criu/arch/ppc64/Makefile b/criu/arch/ppc64/Makefile
index 69de18e49585..5db577340a7d 100644
--- a/criu/arch/ppc64/Makefile
+++ b/criu/arch/ppc64/Makefile
@@ -4,4 +4,3 @@ ccflags-y += -iquote $(obj) -iquote $(SRC_DIR) -iquote $(obj)/include -iquote $
obj-y += cpu.o
obj-y += crtools.o
-obj-y += infect.o
diff --git a/criu/arch/ppc64/crtools.c b/criu/arch/ppc64/crtools.c
index 3d19b783240a..c94b8771f46c 100644
--- a/criu/arch/ppc64/crtools.c
+++ b/criu/arch/ppc64/crtools.c
@@ -18,26 +18,11 @@
#include "log.h"
#include "util.h"
#include "cpu.h"
-#include "errno.h"
-#include "infect.h"
#include "protobuf.h"
#include "images/core.pb-c.h"
#include "images/creds.pb-c.h"
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
-{
- /*
- * OpenPOWER ABI requires that r12 is set to the calling function addressi
- * to compute the TOC pointer.
- */
- regs->gpr[12] = new_ip;
- regs->nip = new_ip;
- if (stack)
- regs->gpr[1] = (unsigned long) stack;
- regs->trap = 0;
-}
-
bool arch_can_dump_task(pid_t pid)
{
return ptrace_task_compatible(pid);
diff --git a/criu/arch/ppc64/include/asm/dump.h b/criu/arch/ppc64/include/asm/dump.h
index 6439adafd8ca..0c88b7a56235 100644
--- a/criu/arch/ppc64/include/asm/dump.h
+++ b/criu/arch/ppc64/include/asm/dump.h
@@ -1,7 +1,9 @@
#ifndef __CR_ASM_DUMP_H__
#define __CR_ASM_DUMP_H__
+typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
+extern int get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t, void *);
extern int arch_alloc_thread_info(CoreEntry *core);
extern void arch_free_thread_info(CoreEntry *core);
diff --git a/criu/arch/ppc64/include/asm/parasite-syscall.h b/criu/arch/ppc64/include/asm/parasite-syscall.h
deleted file mode 100644
index 4a370f605f57..000000000000
--- a/criu/arch/ppc64/include/asm/parasite-syscall.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __CR_ASM_PARASITE_SYSCALL_H__
-#define __CR_ASM_PARASITE_SYSCALL_H__
-
-struct parasite_ctl;
-
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-
-#endif
diff --git a/criu/arch/ppc64/infect.c b/criu/arch/ppc64/infect.c
deleted file mode 100644
index 201307be1705..000000000000
--- a/criu/arch/ppc64/infect.c
+++ /dev/null
@@ -1,308 +0,0 @@
-#include <sys/ptrace.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <errno.h>
-
-#include <compel/plugins/std/syscall-codes.h>
-
-#include "asm/types.h"
-#include "ptrace.h"
-#include "parasite-syscall.h"
-#include "errno.h"
-#include "criu-log.h"
-#include "infect.h"
-#include "infect-priv.h"
-
-#ifndef NT_PPC_TM_SPR
-#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
-#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
-#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */
-#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */
-#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
-#endif
-
-/* FIXME -- copied between crtools.c and infect.c */
-#define MSR_TMA (1UL<<34) /* bit 29 Trans Mem state: Transactional */
-#define MSR_TMS (1UL<<33) /* bit 30 Trans Mem state: Suspended */
-#define MSR_TM (1UL<<32) /* bit 31 Trans Mem Available */
-#define MSR_VEC (1UL<<25)
-#define MSR_VSX (1UL<<23)
-
-#define MSR_TM_ACTIVE(x) ((((x) & MSR_TM) && ((x)&(MSR_TMA|MSR_TMS))) != 0)
-
-/*
- * Injected syscall instruction
- */
-const u32 code_syscall[] = {
- 0x44000002, /* sc */
- 0x0fe00000 /* twi 31,0,0 */
-};
-
-static inline void __check_code_syscall(void)
-{
- BUILD_BUG_ON(sizeof(code_syscall) != BUILTIN_SYSCALL_SIZE);
- BUILD_BUG_ON(!is_log2(sizeof(code_syscall)));
-}
-
-/* This is the layout of the POWER7 VSX registers and the way they
- * overlap with the existing FPR and VMX registers.
- *
- * VSR doubleword 0 VSR doubleword 1
- * ----------------------------------------------------------------
- * VSR[0] | FPR[0] | |
- * ----------------------------------------------------------------
- * VSR[1] | FPR[1] | |
- * ----------------------------------------------------------------
- * | ... | |
- * ----------------------------------------------------------------
- * VSR[30] | FPR[30] | |
- * ----------------------------------------------------------------
- * VSR[31] | FPR[31] | |
- * ----------------------------------------------------------------
- * VSR[32] | VR[0] |
- * ----------------------------------------------------------------
- * VSR[33] | VR[1] |
- * ----------------------------------------------------------------
- * | ... |
- * ----------------------------------------------------------------
- * VSR[62] | VR[30] |
- * ----------------------------------------------------------------
- * VSR[63] | VR[31] |
- * ----------------------------------------------------------------
- *
- * PTRACE_GETFPREGS returns FPR[0..31] + FPSCR
- * PTRACE_GETVRREGS returns VR[0..31] + VSCR + VRSAVE
- * PTRACE_GETVSRREGS returns VSR[0..31]
- *
- * PTRACE_GETVSRREGS and PTRACE_GETFPREGS are required since we need
- * to save FPSCR too.
- *
- * There 32 VSX double word registers to save since the 32 first VSX double
- * word registers are saved through FPR[0..32] and the remaining registers
- * are saved when saving the Altivec registers VR[0..32].
- */
-
-static int get_fpu_regs(pid_t pid, user_fpregs_struct_t *fp)
-{
- if (ptrace(PTRACE_GETFPREGS, pid, 0, (void *)&fp->fpregs) < 0) {
- pr_perror("Couldn't get floating-point registers");
- return -1;
- }
- fp->flags |= USER_FPREGS_FL_FP;
-
- return 0;
-}
-
-static int get_altivec_regs(pid_t pid, user_fpregs_struct_t *fp)
-{
- if (ptrace(PTRACE_GETVRREGS, pid, 0, (void*)&fp->vrregs) < 0) {
- /* PTRACE_GETVRREGS returns EIO if Altivec is not supported.
- * This should not happen if msr_vec is set. */
- if (errno != EIO) {
- pr_perror("Couldn't get Altivec registers");
- return -1;
- }
- pr_debug("Altivec not supported\n");
- }
- else {
- pr_debug("Dumping Altivec registers\n");
- fp->flags |= USER_FPREGS_FL_ALTIVEC;
- }
- return 0;
-}
-
-/*
- * Since the FPR[0-31] is stored in the first double word of VSR[0-31] and
- * FPR are saved through the FP state, there is no need to save the upper part
- * of the first 32 VSX registers.
- * Furthermore, the 32 last VSX registers are also the 32 Altivec registers
- * already saved, so no need to save them.
- * As a consequence, only the doubleword 1 of the 32 first VSX registers have
- * to be saved (the ones are returned by PTRACE_GETVSRREGS).
- */
-static int get_vsx_regs(pid_t pid, user_fpregs_struct_t *fp)
-{
- if (ptrace(PTRACE_GETVSRREGS, pid, 0, (void*)fp->vsxregs) < 0) {
- /*
- * EIO is returned in the case PTRACE_GETVRREGS is not
- * supported.
- */
- if (errno != EIO) {
- pr_perror("Couldn't get VSX registers");
- return -1;
- }
- pr_debug("VSX register's dump not supported.\n");
- }
- else {
- pr_debug("Dumping VSX registers\n");
- fp->flags |= USER_FPREGS_FL_VSX;
- }
- return 0;
-}
-
-static int get_tm_regs(pid_t pid, user_fpregs_struct_t *fpregs)
-{
- struct iovec iov;
-
- pr_debug("Dumping TM registers\n");
-
-#define TM_REQUIRED 0
-#define TM_OPTIONAL 1
-#define PTRACE_GET_TM(s,n,c,u) do { \
- iov.iov_base = &s; \
- iov.iov_len = sizeof(s); \
- if (ptrace(PTRACE_GETREGSET, pid, c, &iov)) { \
- if (!u || errno != EIO) { \
- pr_perror("Couldn't get TM "n); \
- pr_err("Your kernel seems to not support the " \
- "new TM ptrace API (>= 4.8)\n"); \
- goto out_free; \
- } \
- pr_debug("TM "n" not supported.\n"); \
- iov.iov_base = NULL; \
- } \
-} while(0)
-
- /* Get special registers */
- PTRACE_GET_TM(fpregs->tm.tm_spr_regs, "SPR", NT_PPC_TM_SPR, TM_REQUIRED);
-
- /* Get checkpointed regular registers */
- PTRACE_GET_TM(fpregs->tm.regs, "GPR", NT_PPC_TM_CGPR, TM_REQUIRED);
-
- /* Get checkpointed FP registers */
- PTRACE_GET_TM(fpregs->tm.fpregs, "FPR", NT_PPC_TM_CFPR, TM_OPTIONAL);
- if (iov.iov_base)
- fpregs->tm.flags |= USER_FPREGS_FL_FP;
-
- /* Get checkpointed VMX (Altivec) registers */
- PTRACE_GET_TM(fpregs->tm.vrregs, "VMX", NT_PPC_TM_CVMX, TM_OPTIONAL);
- if (iov.iov_base)
- fpregs->tm.flags |= USER_FPREGS_FL_ALTIVEC;
-
- /* Get checkpointed VSX registers */
- PTRACE_GET_TM(fpregs->tm.vsxregs, "VSX", NT_PPC_TM_CVSX, TM_OPTIONAL);
- if (iov.iov_base)
- fpregs->tm.flags |= USER_FPREGS_FL_VSX;
-
- return 0;
-
-out_free:
- return -1; /* still failing the checkpoint */
-}
-
-static int __get_task_regs(pid_t pid, user_regs_struct_t *regs,
- user_fpregs_struct_t *fpregs)
-{
- pr_info("Dumping GP/FPU registers for %d\n", pid);
-
- /*
- * This is inspired by kernel function check_syscall_restart in
- * arch/powerpc/kernel/signal.c
- */
-#ifndef TRAP
-#define TRAP(r) ((r).trap & ~0xF)
-#endif
-
- if (TRAP(*regs) == 0x0C00 && regs->ccr & 0x10000000) {
- /* Restart the system call */
- switch (regs->gpr[3]) {
- case ERESTARTNOHAND:
- case ERESTARTSYS:
- case ERESTARTNOINTR:
- regs->gpr[3] = regs->orig_gpr3;
- regs->nip -= 4;
- break;
- case ERESTART_RESTARTBLOCK:
- regs->gpr[0] = __NR_restart_syscall;
- regs->nip -= 4;
- break;
- }
- }
-
- /* Resetting trap since we are now coming from user space. */
- regs->trap = 0;
-
- fpregs->flags = 0;
- /*
- * Check for Transactional Memory operation in progress.
- * Until we have support of TM register's state through the ptrace API,
- * we can't checkpoint process with TM operation in progress (almost
- * impossible) or suspended (easy to get).
- */
- if (MSR_TM_ACTIVE(regs->msr)) {
- pr_debug("Task %d has %s TM operation at 0x%lx\n",
- pid,
- (regs->msr & MSR_TMS) ? "a suspended" : "an active",
- regs->nip);
- if (get_tm_regs(pid, fpregs))
- return -1;
- fpregs->flags = USER_FPREGS_FL_TM;
- }
-
- if (get_fpu_regs(pid, fpregs))
- return -1;
-
- if (get_altivec_regs(pid, fpregs))
- return -1;
-
- if (fpregs->flags & USER_FPREGS_FL_ALTIVEC) {
- /*
- * Save the VSX registers if Altivec registers are supported
- */
- if (get_vsx_regs(pid, fpregs))
- return -1;
- }
- return 0;
-}
-
-int compel_get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t save, void *arg)
-{
- user_fpregs_struct_t fpregs;
- int ret;
-
- ret = __get_task_regs(pid, ®s, &fpregs);
- if (ret)
- return ret;
-
- return save(arg, ®s, &fpregs);
-}
-
-int compel_syscall(struct parasite_ctl *ctl, int nr, unsigned long *ret,
- unsigned long arg1,
- unsigned long arg2,
- unsigned long arg3,
- unsigned long arg4,
- unsigned long arg5,
- unsigned long arg6)
-{
- user_regs_struct_t regs = ctl->orig.regs;
- int err;
-
- regs.gpr[0] = (unsigned long)nr;
- regs.gpr[3] = arg1;
- regs.gpr[4] = arg2;
- regs.gpr[5] = arg3;
- regs.gpr[6] = arg4;
- regs.gpr[7] = arg5;
- regs.gpr[8] = arg6;
-
- err = compel_execute_syscall(ctl, ®s, (char*)code_syscall);
-
- *ret = regs.gpr[3];
- return err;
-}
-
-void *remote_mmap(struct parasite_ctl *ctl,
- void *addr, size_t length, int prot,
- int flags, int fd, off_t offset)
-{
- unsigned long map = 0;
- int err;
-
- err = compel_syscall(ctl, __NR_mmap, &map,
- (unsigned long)addr, length, prot, flags, fd, offset);
- if (err < 0 || (long)map < 0)
- map = 0;
-
- return (void *)map;
-}
diff --git a/criu/arch/x86/Makefile b/criu/arch/x86/Makefile
index c088b2dd47e4..fb8608211ab5 100644
--- a/criu/arch/x86/Makefile
+++ b/criu/arch/x86/Makefile
@@ -8,7 +8,6 @@ asflags-y += -iquote $(obj)/include
obj-y += cpu.o
obj-y += crtools.o
-obj-y += infect.o
ifeq ($(CONFIG_COMPAT),y)
obj-y += sigaction_compat.o
obj-y += call32.o
diff --git a/criu/arch/x86/crtools.c b/criu/arch/x86/crtools.c
index 952041d2428b..cf877cf2754e 100644
--- a/criu/arch/x86/crtools.c
+++ b/criu/arch/x86/crtools.c
@@ -8,8 +8,10 @@
#include <compel/plugins/std/syscall-codes.h>
#include <compel/asm/processor-flags.h>
+#include <compel/asm/fpu.h>
+#include <compel/cpu.h>
+#include <compel/compel.h>
-#include "asm/parasite-syscall.h"
#include "asm/restorer.h"
#include "asm/types.h"
#include "asm/dump.h"
@@ -22,31 +24,12 @@
#include "log.h"
#include "util.h"
#include "cpu.h"
-#include "errno.h"
#include "kerndat.h"
-#include "infect.h"
#include "protobuf.h"
#include "images/core.pb-c.h"
#include "images/creds.pb-c.h"
-/*
- * regs must be inited when calling this function from original context
- */
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs)
-{
- set_user_reg(regs, ip, new_ip);
- if (stack)
- set_user_reg(regs, sp, (unsigned long) stack);
-
- /* Avoid end of syscall processing */
- set_user_reg(regs, orig_ax, -1);
-
- /* Make sure flags are in known state */
- set_user_reg(regs, flags, get_user_reg(regs, flags) &
- ~(X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_IF));
-}
-
#ifdef CONFIG_X86_64
/* Remaps 64-bit vDSO on the same addr, where it already is */
int kdat_compat_sigreturn_test(void)
diff --git a/criu/arch/x86/include/asm/dump.h b/criu/arch/x86/include/asm/dump.h
index ca7cd675f21c..ac48a2fc96e7 100644
--- a/criu/arch/x86/include/asm/dump.h
+++ b/criu/arch/x86/include/asm/dump.h
@@ -1,7 +1,9 @@
#ifndef __CR_ASM_DUMP_H__
#define __CR_ASM_DUMP_H__
+typedef int (*save_regs_t)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
+extern int get_task_regs(pid_t pid, user_regs_struct_t regs, save_regs_t, void *);
extern int arch_alloc_thread_info(CoreEntry *core);
extern void arch_free_thread_info(CoreEntry *core);
diff --git a/criu/arch/x86/include/asm/parasite-syscall.h b/criu/arch/x86/include/asm/parasite-syscall.h
deleted file mode 100644
index 769367d70a78..000000000000
--- a/criu/arch/x86/include/asm/parasite-syscall.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __CR_ASM_PARASITE_SYSCALL_H__
-#define __CR_ASM_PARASITE_SYSCALL_H__
-
-#include "asm/types.h"
-
-struct parasite_ctl;
-
-void parasite_setup_regs(unsigned long new_ip, void *stack, user_regs_struct_t *regs);
-
-#endif
diff --git a/criu/arch/x86/sys-exec-tbl.c b/criu/arch/x86/sys-exec-tbl.c
index 1051af06fe46..4667989ded60 100644
--- a/criu/arch/x86/sys-exec-tbl.c
+++ b/criu/arch/x86/sys-exec-tbl.c
@@ -1,4 +1,4 @@
-#include "infect.h"
+//#include "compel/infect.h"
static struct syscall_exec_desc sc_exec_table_64[] = {
#include "sys-exec-tbl-64.c"
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index e7b3f058f1a4..b65b080a3331 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -4,14 +4,11 @@
#include "crtools.h"
#include "parasite-syscall.h"
#include "proc_parse.h"
-#include "ptrace.h"
#include "pstree.h"
#include "vma.h"
#include "log.h"
#include "util.h"
#include "kerndat.h"
-#include "infect.h"
-#include "infect-priv.h"
struct syscall_exec_desc {
char *name;
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 4a9a58f41df1..ac92270cf5b2 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -76,7 +76,6 @@
#include "file-lock.h"
#include "action-scripts.h"
#include "shmem.h"
-#include "infect.h"
#include "aio.h"
#include "lsm.h"
#include "seccomp.h"
@@ -95,7 +94,6 @@
#include "images/siginfo.pb-c.h"
#include "asm/restore.h"
-#include "asm/parasite-syscall.h"
#include "cr-errno.h"
diff --git a/criu/include/errno.h b/criu/include/errno.h
deleted file mode 100644
index 5c2322e9fae9..000000000000
--- a/criu/include/errno.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __CR_ERRNO_H__
-#define __CR_ERRNO_H__
-
-#define ERESTARTSYS 512
-#define ERESTARTNOINTR 513
-#define ERESTARTNOHAND 514
-#define ERESTART_RESTARTBLOCK 516
-
-#endif /* __CR_ERRNO_H__ */
diff --git a/criu/include/infect-rpc.h b/criu/include/infect-rpc.h
deleted file mode 100644
index fd03a096721a..000000000000
--- a/criu/include/infect-rpc.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __COMPEL_INFECT_RPC_H__
-#define __COMPEL_INFECT_RPC_H__
-extern int compel_rpc_sync(unsigned int cmd, struct parasite_ctl *ctl);
-extern int compel_rpc_call(unsigned int cmd, struct parasite_ctl *ctl);
-extern int compel_rpc_call_sync(unsigned int cmd, struct parasite_ctl *ctl);
-extern int compel_rpc_sock(struct parasite_ctl *ctl);
-
-struct ctl_msg {
- u32 cmd; /* command itself */
- u32 ack; /* ack on command */
- s32 err; /* error code on reply */
-};
-
-#define ctl_msg_cmd(_cmd) \
- (struct ctl_msg){.cmd = _cmd, }
-
-#define ctl_msg_ack(_cmd, _err) \
- (struct ctl_msg){.cmd = _cmd, .ack = _cmd, .err = _err, }
-
-#endif
diff --git a/criu/include/infect.h b/criu/include/infect.h
deleted file mode 100644
index 197540cf344b..000000000000
--- a/criu/include/infect.h
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef __COMPEL_INFECT_H__
-#define __COMPEL_INFECT_H__
-extern int compel_stop_task(int pid);
-
-struct seize_task_status {
- char state;
- int ppid;
- unsigned long long sigpnd;
- unsigned long long shdpnd;
- int seccomp_mode;
-};
-
-extern int compel_wait_task(int pid, int ppid,
- int (*get_status)(int pid, struct seize_task_status *),
- struct seize_task_status *st);
-extern int compel_unseize_task(pid_t pid, int orig_state, int state);
-
-/*
- * FIXME -- these should be mapped to pid.h's
- */
-
-#define TASK_ALIVE 0x1
-#define TASK_DEAD 0x2
-#define TASK_STOPPED 0x3
-#define TASK_ZOMBIE 0x6
-
-struct parasite_ctl;
-struct thread_ctx;
-
-extern struct parasite_ctl *compel_prepare(int pid);
-extern int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size);
-extern int compel_prepare_thread(int pid, struct thread_ctx *ctx);
-
-extern int compel_stop_daemon(struct parasite_ctl *ctl);
-extern int compel_cure_remote(struct parasite_ctl *ctl);
-extern int compel_cure_local(struct parasite_ctl *ctl);
-extern int compel_cure(struct parasite_ctl *ctl);
-
-#define PARASITE_ARG_SIZE_MIN ( 1 << 12)
-
-#define compel_parasite_args(ctl, type) \
- ({ \
- void *___ret; \
- BUILD_BUG_ON(sizeof(type) > PARASITE_ARG_SIZE_MIN); \
- ___ret = compel_parasite_args_p(ctl); \
- ___ret; \
- })
-
-extern void *compel_parasite_args_p(struct parasite_ctl *ctl);
-extern void *compel_parasite_args_s(struct parasite_ctl *ctl, int args_size);
-
-extern int compel_execute_syscall(struct parasite_ctl *ctl,
- user_regs_struct_t *regs, const char *code_syscall);
-extern int compel_run_in_thread(pid_t pid, unsigned int cmd,
- struct parasite_ctl *ctl,
- struct thread_ctx *octx);
-
-/*
- * The PTRACE_SYSCALL will trap task twice -- on
- * enter into and on exit from syscall. If we trace
- * a single task, we may skip half of all getregs
- * calls -- on exit we don't need them.
- */
-enum trace_flags {
- TRACE_ALL,
- TRACE_ENTER,
- TRACE_EXIT,
-};
-
-extern int compel_stop_on_syscall(int tasks, int sys_nr,
- int sys_nr_compat, enum trace_flags trace);
-
-extern int compel_stop_pie(pid_t pid, void *addr, enum trace_flags *tf, bool no_bp);
-
-extern int compel_unmap(struct parasite_ctl *ctl, unsigned long addr);
-
-extern int compel_mode_native(struct parasite_ctl *ctl);
-
-extern k_rtsigset_t *compel_task_sigmask(struct parasite_ctl *ctl);
-
-struct rt_sigframe;
-
-struct infect_ctx {
- int *p_sock;
-
- /*
- * Regs manipulation context.
- */
- int (*save_regs)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
- int (*make_sigframe)(void *, struct rt_sigframe *, struct rt_sigframe *, k_rtsigset_t *);
- void *regs_arg;
-
- unsigned long syscall_ip; /* entry point of infection */
- unsigned long flags; /* fine-tune (e.g. faults) */
-
- void (*child_handler)(int, siginfo_t *, void *); /* hander for SIGCHLD deaths */
-};
-
-extern struct infect_ctx *compel_infect_ctx(struct parasite_ctl *);
-
-#define INFECT_NO_MEMFD 0x1 /* don't use memfd() */
-#define INFECT_FAIL_CONNECT 0x2 /* make parasite connect() fail */
-#define INFECT_NO_BREAKPOINTS 0x4 /* no breakpoints in pie tracking */
-
-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 *);
-
-#endif
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index e172789a0f15..ac39e375df7e 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -22,11 +22,6 @@ struct pid;
struct parasite_dump_cgroup_args;
struct rt_sigframe;
-struct thread_ctx {
- k_rtsigset_t sigmask;
- user_regs_struct_t regs;
-};
-
struct parasite_ctl;
extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_imgset *cr_imgset);
diff --git a/criu/include/parasite.h b/criu/include/parasite.h
index f7daa095371f..e1f4ded8ec47 100644
--- a/criu/include/parasite.h
+++ b/criu/include/parasite.h
@@ -1,9 +1,6 @@
#ifndef __CR_PARASITE_H__
#define __CR_PARASITE_H__
-#define PARASITE_STACK_SIZE (16 << 10)
-#define PARASITE_START_AREA_MIN (4096)
-
#define PARASITE_MAX_SIZE (64 << 10)
#ifndef __ASSEMBLY__
@@ -13,6 +10,8 @@
#include <time.h>
#include <signal.h>
+#include <compel/compel.h>
+
#include "image.h"
#include "util-pie.h"
#include "lock.h"
@@ -28,17 +27,7 @@
* alternative type for compatible tasks in parasite-compat.h
*/
enum {
- PARASITE_CMD_IDLE = 0,
- PARASITE_CMD_ACK,
-
- PARASITE_CMD_INIT_DAEMON,
- PARASITE_CMD_DUMP_THREAD,
- PARASITE_CMD_UNMAP,
-
- /*
- * This must be greater than INITs.
- */
- PARASITE_CMD_FINI,
+ PARASITE_CMD_DUMP_THREAD = COMPEL_PARASITE_CMD_USR_BASE,
PARASITE_CMD_MPROTECT_VMAS,
PARASITE_CMD_DUMPPAGES,
@@ -57,20 +46,6 @@ enum {
PARASITE_CMD_MAX,
};
-struct parasite_init_args {
- s32 h_addr_len;
- struct sockaddr_un h_addr;
- s32 log_level;
- u64 sigreturn_addr;
- u64 sigframe; /* pointer to sigframe */
- futex_t daemon_connected;
-};
-
-struct parasite_unmap_args {
- u64 parasite_start;
- u64 parasite_len;
-};
-
struct parasite_vma_entry
{
u64 start;
diff --git a/criu/include/proc_parse.h b/criu/include/proc_parse.h
index cabd90b12ea0..38e79b43f6f1 100644
--- a/criu/include/proc_parse.h
+++ b/criu/include/proc_parse.h
@@ -2,8 +2,10 @@
#define __CR_PROC_PARSE_H__
#include <sys/types.h>
+
+#include <compel/compel.h>
+
#include "asm/types.h"
-#include "infect.h"
#include "images/seccomp.pb-c.h"
#define PROC_TASK_COMM_LEN 32
diff --git a/criu/mem.c b/criu/mem.c
index 248c6ef8986f..67f0d53403c2 100644
--- a/criu/mem.c
+++ b/criu/mem.c
@@ -5,6 +5,8 @@
#include <fcntl.h>
#include <sys/syscall.h>
+#include <compel/compel.h>
+
#include "cr_options.h"
#include "servicefd.h"
#include "mem.h"
@@ -26,8 +28,6 @@
#include "files-reg.h"
#include "pagemap-cache.h"
#include "fault-injection.h"
-#include "infect.h"
-#include "infect-rpc.h"
#include "protobuf.h"
#include "images/pagemap.pb-c.h"
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index c5bf365f902c..74d1e2c37c61 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -5,6 +5,7 @@
#include <sys/wait.h>
#include <sys/mman.h>
+#include <compel/compel.h>
#include <compel/plugins/std/syscall-codes.h>
#include <compel/asm/processor-flags.h>
@@ -18,6 +19,7 @@
#include "imgset.h"
#include "ptrace.h"
#include "parasite-syscall.h"
+#include "parasite-blob.h"
#include "parasite.h"
#include "crtools.h"
#include "namespaces.h"
@@ -36,14 +38,10 @@
#include <stdlib.h>
#include <elf.h>
-#include "asm/parasite-syscall.h"
#include "asm/dump.h"
#include "asm/restorer.h"
#include "pie/pie-relocs.h"
-#include "infect.h"
-#include "infect-rpc.h"
-
unsigned long get_exec_start(struct vm_area_list *vmas)
{
struct vma_area *vma_area;
@@ -534,6 +532,26 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe *
return construct_sigframe(sf, rtsf, bs, (CoreEntry *)arg);
}
+static unsigned long get_parasite_ip(void *remote_map)
+{
+ return (unsigned long)parasite_sym(remote_map, native, __export_parasite_head_start);
+}
+
+static unsigned int *get_addr_cmd(void *local_map)
+{
+ return parasite_sym(local_map, native, __export_parasite_cmd);
+}
+
+static void *get_addr_args(void *local_map)
+{
+ return parasite_sym(local_map, native, __export_parasite_args);
+}
+
+static void postproc(void *local_map, void *remote_map)
+{
+ ELF_RELOCS_APPLY(parasite_native, local_map, remote_map);
+}
+
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
struct vm_area_list *vma_area_list)
{
@@ -541,6 +559,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
struct infect_ctx *ictx;
unsigned long p;
+ parasite_blob_desc_t d;
+
BUG_ON(item->threads[0].real != pid);
p = get_exec_start(vma_area_list);
@@ -573,7 +593,15 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
parasite_ensure_args_size(dump_pages_args_size(vma_area_list));
parasite_ensure_args_size(aio_rings_args_size(vma_area_list));
- if (compel_infect(ctl, item->nr_threads, parasite_args_size) < 0) {
+ d.blob = (void *)parasite_native_blob;
+ d.blob_size = sizeof(parasite_native_blob);
+ d.pie_size = pie_size(parasite_native);
+ d.get_parasite_ip = get_parasite_ip;
+ d.get_addr_cmd = get_addr_cmd;
+ d.get_addr_args = get_addr_args;
+ d.postproc = postproc;
+
+ if (compel_infect(ctl, &d, item->nr_threads, parasite_args_size) < 0) {
compel_cure(ctl);
return NULL;
}
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index 48ce705b9d49..3722050c0a31 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -7,6 +7,7 @@
#include <stdarg.h>
#include <sys/ioctl.h>
+#include <compel/compel.h>
#include <compel/plugins/std/syscall.h>
#include "parasite.h"
@@ -18,7 +19,6 @@
#include "log.h"
#include "tty.h"
#include "aio.h"
-#include "infect-rpc.h"
#include "asm/types.h"
#include "asm/parasite.h"
@@ -643,7 +643,7 @@ static noinline __used int noinline parasite_daemon(void *args)
pr_debug("Running daemon thread leader\n");
/* Reply we're alive */
- if (__parasite_daemon_reply_ack(PARASITE_CMD_INIT_DAEMON, 0))
+ if (__parasite_daemon_reply_ack(COMPEL_PARASITE_CMD_INIT_DAEMON, 0))
goto out;
ret = 0;
@@ -652,13 +652,13 @@ static noinline __used int noinline parasite_daemon(void *args)
if (__parasite_daemon_wait_msg(&m))
break;
- if (ret && m.cmd != PARASITE_CMD_FINI) {
+ if (ret && m.cmd != COMPEL_PARASITE_CMD_FINI) {
pr_err("Command rejected\n");
continue;
}
switch (m.cmd) {
- case PARASITE_CMD_FINI:
+ case COMPEL_PARASITE_CMD_FINI:
goto out;
case PARASITE_CMD_DUMPPAGES:
ret = dump_pages(args);
@@ -785,9 +785,9 @@ int __used __parasite_entry parasite_service(unsigned int cmd, void *args)
switch (cmd) {
case PARASITE_CMD_DUMP_THREAD:
return dump_thread(args);
- case PARASITE_CMD_INIT_DAEMON:
+ case COMPEL_PARASITE_CMD_INIT_DAEMON:
return parasite_init_daemon(args);
- case PARASITE_CMD_UNMAP:
+ case COMPEL_PARASITE_CMD_UNMAP:
return unmap_itself(args);
}
diff --git a/criu/seize.c b/criu/seize.c
index 638f7a3f4f12..837750a99e78 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -9,6 +9,8 @@
#include <sys/wait.h>
#include <time.h>
+#include <compel/compel.h>
+
#include "compiler.h"
#include "cr_options.h"
#include "cr-errno.h"
@@ -19,7 +21,6 @@
#include "stats.h"
#include "xmalloc.h"
#include "util.h"
-#include "infect.h"
#define NR_ATTEMPTS 5
diff --git a/criu/vdso.c b/criu/vdso.c
index 41df3c9b0e57..9ffb73d83591 100644
--- a/criu/vdso.c
+++ b/criu/vdso.c
@@ -9,8 +9,9 @@
#include <sys/stat.h>
#include <sys/mman.h>
+#include <compel/compel.h>
+
#include "asm/types.h"
-#include "asm/parasite-syscall.h"
#include "parasite-syscall.h"
#include "parasite.h"
@@ -21,8 +22,6 @@
#include "log.h"
#include "mem.h"
#include "vma.h"
-#include "infect.h"
-#include "infect-rpc.h"
#ifdef LOG_PREFIX
# undef LOG_PREFIX
--
2.7.4
More information about the CRIU
mailing list