Commit c900bf74 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

parasite: unmap itself (v2)

This patch adds a new parasite command, which unmaps the parasite blob.
This command never returns and the criu process traps the target process
on the exit from the munmap syscall.

v2: rename the function for unmaping a parasite blob to not intersects
with criu's functions.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 89d8b201
...@@ -25,6 +25,7 @@ enum { ...@@ -25,6 +25,7 @@ enum {
PARASITE_CMD_INIT_DAEMON, PARASITE_CMD_INIT_DAEMON,
PARASITE_CMD_DUMP_THREAD, PARASITE_CMD_DUMP_THREAD,
PARASITE_CMD_UNMAP,
/* /*
* These two must be greater than INITs. * These two must be greater than INITs.
...@@ -70,6 +71,11 @@ struct parasite_init_args { ...@@ -70,6 +71,11 @@ struct parasite_init_args {
struct rt_sigframe *sigframe; struct rt_sigframe *sigframe;
}; };
struct parasite_unmap_args {
void *parasite_start;
unsigned long parasite_len;
};
struct parasite_vma_entry struct parasite_vma_entry
{ {
unsigned long start; unsigned long start;
......
...@@ -307,14 +307,6 @@ int parasite_execute_daemon(unsigned int cmd, struct parasite_ctl *ctl) ...@@ -307,14 +307,6 @@ int parasite_execute_daemon(unsigned int cmd, struct parasite_ctl *ctl)
return ret; return ret;
} }
static int munmap_seized(struct parasite_ctl *ctl, void *addr, size_t length)
{
unsigned long x;
return syscall_seized(ctl, __NR_munmap, &x,
(unsigned long)addr, length, 0, 0, 0, 0);
}
static int gen_parasite_saddr(struct sockaddr_un *saddr, int key) static int gen_parasite_saddr(struct sockaddr_un *saddr, int key)
{ {
int sun_len; int sun_len;
...@@ -850,10 +842,15 @@ int parasite_cure_remote(struct parasite_ctl *ctl) ...@@ -850,10 +842,15 @@ int parasite_cure_remote(struct parasite_ctl *ctl)
close_safe(&ctl->tsock); close_safe(&ctl->tsock);
if (ctl->remote_map) { if (ctl->remote_map) {
if (munmap_seized(ctl, (void *)ctl->remote_map, ctl->map_length)) { struct parasite_unmap_args *args;
pr_err("munmap_seized failed (pid: %d)\n", ctl->pid.real);
*ctl->addr_cmd = PARASITE_CMD_UNMAP;
args = parasite_args(ctl, struct parasite_unmap_args);
args->parasite_start = ctl->remote_map;
args->parasite_len = ctl->map_length;
if (parasite_unmap(ctl, ctl->parasite_ip))
ret = -1; ret = -1;
}
} }
return ret; return ret;
......
...@@ -478,6 +478,20 @@ out: ...@@ -478,6 +478,20 @@ out:
return 0; return 0;
} }
static noinline int unmap_itself(void *data)
{
struct parasite_unmap_args *args = data;
sys_munmap(args->parasite_start, args->parasite_len);
/*
* sys_munmap never return back. The controll process must
* trap us on the exit from munmap
*/
BUG();
return -1;
}
static noinline __used int parasite_init_daemon(void *data) static noinline __used int parasite_init_daemon(void *data)
{ {
struct parasite_init_args *args = data; struct parasite_init_args *args = data;
...@@ -523,6 +537,8 @@ int __used parasite_service(unsigned int cmd, void *args) ...@@ -523,6 +537,8 @@ int __used parasite_service(unsigned int cmd, void *args)
return dump_thread(args); return dump_thread(args);
case PARASITE_CMD_INIT_DAEMON: case PARASITE_CMD_INIT_DAEMON:
return parasite_init_daemon(args); return parasite_init_daemon(args);
case PARASITE_CMD_UNMAP:
return unmap_itself(args);
} }
pr_err("Unknown command to parasite: %d\n", cmd); pr_err("Unknown command to parasite: %d\n", cmd);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment