mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 06:45:35 +00:00
parasite: Enlighten parasite cmd/adg injection
Since we now have the parasite memory shared with crtools process we can just memcpy this data between them. Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
committed by
Cyrill Gorcunov
parent
354ab03a67
commit
e6823c274e
@@ -18,8 +18,8 @@ struct parasite_ctl {
|
|||||||
void * local_map;
|
void * local_map;
|
||||||
unsigned long map_length;
|
unsigned long map_length;
|
||||||
unsigned long parasite_ip; /* service routine start ip */
|
unsigned long parasite_ip; /* service routine start ip */
|
||||||
unsigned long addr_cmd; /* addr for command */
|
void * addr_cmd; /* addr for command */
|
||||||
unsigned long addr_args; /* address for arguments */
|
void * addr_args; /* address for arguments */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int can_run_syscall(unsigned long ip, unsigned long start, unsigned long end);
|
extern int can_run_syscall(unsigned long ip, unsigned long start, unsigned long end);
|
||||||
|
@@ -199,19 +199,13 @@ int parasite_execute(unsigned long cmd, struct parasite_ctl *ctl,
|
|||||||
/*
|
/*
|
||||||
* Pass the command first, it's immutable.
|
* Pass the command first, it's immutable.
|
||||||
*/
|
*/
|
||||||
jerr(ptrace_poke_area((long)ctl->pid, (void *)&cmd, (void *)ctl->addr_cmd,
|
memcpy(ctl->addr_cmd, &cmd, sizeof(cmd));
|
||||||
sizeof(cmd)), err_restore);
|
|
||||||
|
|
||||||
again:
|
again:
|
||||||
regs = regs_orig;
|
regs = regs_orig;
|
||||||
regs.ip = ctl->parasite_ip;
|
regs.ip = ctl->parasite_ip;
|
||||||
jerr(ptrace(PTRACE_SETREGS, ctl->pid, NULL, ®s), err_restore);
|
jerr(ptrace(PTRACE_SETREGS, ctl->pid, NULL, ®s), err_restore);
|
||||||
|
|
||||||
if (ptrace_poke_area((long)ctl->pid, (void *)args,
|
memcpy(ctl->addr_args, args, args_size);
|
||||||
(void *)ctl->addr_args, args_size)) {
|
|
||||||
pr_err("Can't setup parasite arguments (pid: %d)\n", ctl->pid);
|
|
||||||
goto err_restore;
|
|
||||||
}
|
|
||||||
|
|
||||||
jerr(ptrace(PTRACE_CONT, (long)ctl->pid, NULL, NULL), err_restore);
|
jerr(ptrace(PTRACE_CONT, (long)ctl->pid, NULL, NULL), err_restore);
|
||||||
jerr(wait4((long)ctl->pid, &status, __WALL, NULL) != (long)ctl->pid, err_restore);
|
jerr(wait4((long)ctl->pid, &status, __WALL, NULL) != (long)ctl->pid, err_restore);
|
||||||
@@ -240,13 +234,8 @@ retry_signal:
|
|||||||
/*
|
/*
|
||||||
* Check if error happened during dumping.
|
* Check if error happened during dumping.
|
||||||
*/
|
*/
|
||||||
if (ptrace_peek_area((long)ctl->pid,
|
|
||||||
(void *)args,
|
memcpy(args, ctl->addr_args, args_size);
|
||||||
(void *)(ctl->addr_args),
|
|
||||||
args_size)) {
|
|
||||||
pr_err("Can't get dumper ret code (pid: %d)\n", ctl->pid);
|
|
||||||
goto err_restore;
|
|
||||||
}
|
|
||||||
if (args->ret) {
|
if (args->ret) {
|
||||||
pr_panic("Dumping sigactions failed with %li (%li) at %li\n",
|
pr_panic("Dumping sigactions failed with %li (%li) at %li\n",
|
||||||
args->ret,
|
args->ret,
|
||||||
@@ -584,8 +573,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_
|
|||||||
ctl->map_length = round_up(parasite_size, PAGE_SIZE);
|
ctl->map_length = round_up(parasite_size, PAGE_SIZE);
|
||||||
|
|
||||||
ctl->parasite_ip = PARASITE_HEAD_ADDR((unsigned long)ctl->remote_map);
|
ctl->parasite_ip = PARASITE_HEAD_ADDR((unsigned long)ctl->remote_map);
|
||||||
ctl->addr_cmd = PARASITE_CMD_ADDR((unsigned long)ctl->remote_map);
|
|
||||||
ctl->addr_args = PARASITE_ARGS_ADDR((unsigned long)ctl->remote_map);
|
|
||||||
|
|
||||||
snprintf(fname, sizeof(fname), "map_files/%p-%p",
|
snprintf(fname, sizeof(fname), "map_files/%p-%p",
|
||||||
ctl->remote_map, ctl->remote_map + ctl->map_length);
|
ctl->remote_map, ctl->remote_map + ctl->map_length);
|
||||||
@@ -609,6 +596,9 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_
|
|||||||
|
|
||||||
jerr(ptrace(PTRACE_SETREGS, pid, NULL, ®s_orig), err_munmap_restore);
|
jerr(ptrace(PTRACE_SETREGS, pid, NULL, ®s_orig), err_munmap_restore);
|
||||||
|
|
||||||
|
ctl->addr_cmd = (void *)PARASITE_CMD_ADDR((unsigned long)ctl->local_map);
|
||||||
|
ctl->addr_args = (void *)PARASITE_ARGS_ADDR((unsigned long)ctl->local_map);
|
||||||
|
|
||||||
ret = parasite_init(ctl, pid);
|
ret = parasite_init(ctl, pid);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%d: Can't create a transport socket\n", pid);
|
pr_err("%d: Can't create a transport socket\n", pid);
|
||||||
|
Reference in New Issue
Block a user