mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-02 07:15:31 +00:00
parasite: Code grouping in parasite_infect_seized
- mmap_seized returns only NULL on error, drop redumdant test - setup control block in one group - no need for err_free label, xfree handles NULL easily - prepare registers for munmap_seized call on error path Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Acked-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -551,35 +551,29 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup control block */
|
|
||||||
ctl->pid = pid;
|
|
||||||
|
|
||||||
if (ptrace(PTRACE_GETREGS, pid, NULL, ®s))
|
if (ptrace(PTRACE_GETREGS, pid, NULL, ®s))
|
||||||
pr_err_jmp(err_free);
|
pr_err_jmp(err);
|
||||||
|
|
||||||
vma_area = get_vma_by_ip(vma_area_list, regs.ip);
|
vma_area = get_vma_by_ip(vma_area_list, regs.ip);
|
||||||
if (!vma_area) {
|
if (!vma_area) {
|
||||||
pr_err("No suitable VMA found to run parasite "
|
pr_err("No suitable VMA found to run parasite "
|
||||||
"bootstrap code (pid: %d)\n", pid);
|
"bootstrap code (pid: %d)\n", pid);
|
||||||
goto err_free;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs_orig = regs;
|
regs_orig = regs;
|
||||||
parasite_setup_regs(vma_area->vma.start, ®s);
|
parasite_setup_regs(vma_area->vma.start, ®s);
|
||||||
|
|
||||||
ctl->remote_map = mmap_seized(pid, ®s, NULL, (size_t)parasite_size,
|
ctl->remote_map = mmap_seized(pid, ®s, 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 || (long)ctl->remote_map < 0) {
|
|
||||||
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", pid);
|
||||||
goto err_restore_regs;
|
goto err_restore_regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
||||||
fd = openat(pid_dir, fname, O_RDWR);
|
fd = openat(pid_dir, fname, O_RDWR);
|
||||||
@@ -589,7 +583,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (ctl->local_map == MAP_FAILED) {
|
if (ctl->local_map == MAP_FAILED) {
|
||||||
@@ -602,8 +596,11 @@ 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);
|
/* Setup control block */
|
||||||
ctl->addr_args = (void *)PARASITE_ARGS_ADDR((unsigned long)ctl->local_map);
|
ctl->pid = pid;
|
||||||
|
ctl->parasite_ip = PARASITE_HEAD_ADDR((unsigned long)ctl->remote_map);
|
||||||
|
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) {
|
||||||
@@ -614,7 +611,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, int pid_dir, struct list_
|
|||||||
ret = parasite_set_logfd(ctl, pid);
|
ret = parasite_set_logfd(ctl, pid);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%d: Can't set a logging descriptor\n", pid);
|
pr_err("%d: Can't set a logging descriptor\n", pid);
|
||||||
goto err_munmap_restore;
|
goto err_fini;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctl;
|
return ctl;
|
||||||
@@ -624,17 +621,19 @@ err_fini:
|
|||||||
&args, sizeof(args));
|
&args, sizeof(args));
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_panic("Can't finalize parasite (pid: %d) task\n", ctl->pid);
|
pr_panic("Can't finalize parasite (pid: %d) task\n", ctl->pid);
|
||||||
|
|
||||||
err_munmap_restore:
|
err_munmap_restore:
|
||||||
regs = regs_orig, regs.ip = vma_area->vma.start;
|
regs = regs_orig;
|
||||||
|
parasite_setup_regs(vma_area->vma.start, ®s);
|
||||||
if (munmap_seized(pid, ®s, ctl->remote_map, ctl->map_length))
|
if (munmap_seized(pid, ®s, ctl->remote_map, ctl->map_length))
|
||||||
pr_panic("mmap_seized failed (pid: %d)\n", pid);
|
pr_panic("mmap_seized failed (pid: %d)\n", pid);
|
||||||
|
|
||||||
err_restore_regs:
|
err_restore_regs:
|
||||||
if (ptrace(PTRACE_SETREGS, pid, NULL, ®s_orig))
|
if (ptrace(PTRACE_SETREGS, pid, NULL, ®s_orig))
|
||||||
pr_panic("PTRACE_SETREGS failed (pid: %d)\n", pid);
|
pr_panic("PTRACE_SETREGS failed (pid: %d)\n", pid);
|
||||||
err_free:
|
|
||||||
if (ctl)
|
|
||||||
free(ctl);
|
|
||||||
err:
|
err:
|
||||||
|
xfree(ctl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user