mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-29 13:28:27 +00:00
parasite: Split infecting routine into parts
The fist part prepares ctl to controll the seized task. The 2nd one mmaps shareb buffer for data exchange. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
3b404e3776
commit
45fdee04fb
@ -52,6 +52,8 @@ extern int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *it
|
|||||||
extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
|
extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
|
||||||
struct pstree_item *item,
|
struct pstree_item *item,
|
||||||
struct list_head *vma_area_list);
|
struct list_head *vma_area_list);
|
||||||
|
extern struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_list);
|
||||||
|
extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
|
||||||
|
|
||||||
extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd);
|
extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd);
|
||||||
|
|
||||||
|
@ -776,11 +776,10 @@ int parasite_cure_seized(struct parasite_ctl *ctl, struct pstree_item *item)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list)
|
struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct list_head *vma_area_list)
|
||||||
{
|
{
|
||||||
struct parasite_ctl *ctl = NULL;
|
struct parasite_ctl *ctl = NULL;
|
||||||
struct vma_area *vma_area;
|
struct vma_area *vma_area;
|
||||||
int ret, fd;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control block early setup.
|
* Control block early setup.
|
||||||
@ -822,26 +821,31 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return ctl;
|
||||||
* Inject a parasite engine. Ie allocate memory inside alien
|
|
||||||
* space and copy engine code there. Then re-map the engine
|
err:
|
||||||
* locally, so we will get an easy way to access engine memory
|
xfree(ctl);
|
||||||
* without using ptrace at all.
|
return NULL;
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
ctl->remote_map = mmap_seized(ctl, NULL, (size_t)parasite_size,
|
ctl->remote_map = mmap_seized(ctl, NULL, (size_t)parasite_size,
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||||
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
|
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
|
||||||
if (!ctl->remote_map) {
|
if (!ctl->remote_map) {
|
||||||
pr_err("Can't allocate memory for parasite blob (pid: %d)\n", pid);
|
pr_err("Can't allocate memory for parasite blob (pid: %d)\n", ctl->pid);
|
||||||
goto err_restore;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctl->map_length = round_up(parasite_size, PAGE_SIZE);
|
ctl->map_length = round_up(parasite_size, PAGE_SIZE);
|
||||||
|
|
||||||
fd = open_proc_rw(pid, "map_files/%p-%p",
|
fd = open_proc_rw(ctl->pid, "map_files/%p-%p",
|
||||||
ctl->remote_map, ctl->remote_map + ctl->map_length);
|
ctl->remote_map, ctl->remote_map + ctl->map_length);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
goto err_restore;
|
return -1;
|
||||||
|
|
||||||
ctl->local_map = mmap(NULL, parasite_size, PROT_READ | PROT_WRITE,
|
ctl->local_map = mmap(NULL, parasite_size, PROT_READ | PROT_WRITE,
|
||||||
MAP_SHARED | MAP_FILE, fd, 0);
|
MAP_SHARED | MAP_FILE, fd, 0);
|
||||||
@ -850,9 +854,32 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
|
|||||||
if (ctl->local_map == MAP_FAILED) {
|
if (ctl->local_map == MAP_FAILED) {
|
||||||
ctl->local_map = NULL;
|
ctl->local_map = NULL;
|
||||||
pr_perror("Can't map remote parasite map");
|
pr_perror("Can't map remote parasite map");
|
||||||
goto err_restore;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct parasite_ctl *ctl;
|
||||||
|
|
||||||
|
ctl = parasite_prep_ctl(pid, vma_area_list);
|
||||||
|
if (!ctl)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inject a parasite engine. Ie allocate memory inside alien
|
||||||
|
* space and copy engine code there. Then re-map the engine
|
||||||
|
* locally, so we will get an easy way to access engine memory
|
||||||
|
* without using ptrace at all.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = parasite_map_exchange(ctl, parasite_size);
|
||||||
|
if (ret)
|
||||||
|
goto err_restore;
|
||||||
|
|
||||||
pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map);
|
pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map);
|
||||||
memcpy(ctl->local_map, parasite_blob, sizeof(parasite_blob));
|
memcpy(ctl->local_map, parasite_blob, sizeof(parasite_blob));
|
||||||
|
|
||||||
@ -884,10 +911,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
|
|||||||
err_restore:
|
err_restore:
|
||||||
parasite_cure_seized(ctl, item);
|
parasite_cure_seized(ctl, item);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err:
|
|
||||||
xfree(ctl);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* CONFIG_X86_64 */
|
#else /* CONFIG_X86_64 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user