[CRIU] [PATCH 4/5] parasite: remove struct parasite_thread_ctl
Andrey Vagin
avagin at openvz.org
Mon May 27 08:38:52 EDT 2013
It was required for daemonized threads.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
arch/arm/crtools.c | 4 +-
arch/x86/crtools.c | 4 +-
cr-exec.c | 2 +-
include/parasite-syscall.h | 30 ++++-----
include/parasite.h | 4 --
parasite-syscall.c | 159 ++++++++++++---------------------------------
6 files changed, 60 insertions(+), 143 deletions(-)
diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c
index ae92043..031fb81 100644
--- a/arch/arm/crtools.c
+++ b/arch/arm/crtools.c
@@ -65,7 +65,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
unsigned long arg5,
unsigned long arg6)
{
- user_regs_struct_t regs = ctl->threads[0].regs_orig;
+ user_regs_struct_t regs = ctl->regs_orig;
int err;
regs.ARM_r7 = (unsigned long)nr;
@@ -78,7 +78,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
parasite_setup_regs(ctl->syscall_ip, 0, ®s);
err = __parasite_execute_trap(ctl, ctl->pid.real, ®s,
- &ctl->threads[0].regs_orig, 0);
+ &ctl->regs_orig, 0);
if (err)
return err;
diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c
index dbcb0da..bab502a 100644
--- a/arch/x86/crtools.c
+++ b/arch/x86/crtools.c
@@ -89,7 +89,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
unsigned long arg5,
unsigned long arg6)
{
- user_regs_struct_t regs = ctl->threads[0].regs_orig;
+ user_regs_struct_t regs = ctl->regs_orig;
int err;
regs.ax = (unsigned long)nr;
@@ -102,7 +102,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
parasite_setup_regs(ctl->syscall_ip, 0, ®s);
err = __parasite_execute_trap(ctl, ctl->pid.real, ®s,
- &ctl->threads[0].regs_orig, 0);
+ &ctl->regs_orig, 0);
if (err)
return err;
diff --git a/cr-exec.c b/cr-exec.c
index c2e3bea..bfd4a5e 100644
--- a/cr-exec.c
+++ b/cr-exec.c
@@ -110,7 +110,7 @@ int cr_exec(int pid, char **opt)
goto out_unseize;
}
- ctl = parasite_prep_ctl(pid, &vmas, 1);
+ ctl = parasite_prep_ctl(pid, &vmas);
if (!ctl) {
pr_err("Can't prep ctl %d\n", pid);
goto out_unseize;
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index bb88fa8..4a41228 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -5,19 +5,6 @@
#include "pstree.h"
-struct parasite_thread_ctl
-{
- pid_t tid;
- user_regs_struct_t regs_orig; /* original registers */
-
- k_rtsigset_t sig_blocked;
- bool use_sig_blocked;
-
- void *rstack;
- struct rt_sigframe *sigframe;
- struct rt_sigframe *rsigframe; /* address in a parasite */
-};
-
/* parasite control block */
struct parasite_ctl {
struct pid pid;
@@ -25,7 +12,18 @@ struct parasite_ctl {
void *local_map;
unsigned long map_length;
+ /* thread leader data */
bool daemonized;
+ user_regs_struct_t regs_orig; /* original registers */
+
+ k_rtsigset_t sig_blocked;
+ bool use_sig_blocked;
+
+ void *rstack; /* thread leader stack*/
+ struct rt_sigframe *sigframe;
+ struct rt_sigframe *rsigframe; /* address in a parasite */
+
+ void *r_thread_stack; /* stack for non-leader threads */
unsigned long parasite_ip; /* service routine start ip */
unsigned long syscall_ip; /* entry point of infection */
@@ -38,9 +36,6 @@ struct parasite_ctl {
struct list_head pre_list;
struct page_pipe *mem_pp;
-
- int nr_threads;
- struct parasite_thread_ctl threads[0];
};
struct cr_fdset;
@@ -84,8 +79,7 @@ extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
struct vm_area_list *vma_area_list,
struct parasite_drain_fd *dfds);
extern struct parasite_ctl *parasite_prep_ctl(pid_t pid,
- struct vm_area_list *vma_area_list,
- unsigned int nr_threads);
+ struct vm_area_list *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);
diff --git a/include/parasite.h b/include/parasite.h
index 8fae002..0e5720f 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -63,16 +63,12 @@ struct ctl_msg {
(struct ctl_msg){.cmd = _cmd, .ack = _cmd, .err = _err, }
struct parasite_init_args {
- int id;
-
int h_addr_len;
struct sockaddr_un h_addr;
int p_addr_len;
struct sockaddr_un p_addr;
- int nr_threads;
-
k_rtsigset_t sig_blocked;
struct rt_sigframe *sigframe;
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 6397394..258be82 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -230,21 +230,10 @@ static int parasite_execute_trap_by_pid(unsigned int cmd,
return ret;
}
-static int parasite_execute_trap_by_id(unsigned int cmd, struct parasite_ctl *ctl, int id)
-{
- struct parasite_thread_ctl *thread = &ctl->threads[id];
- pid_t pid = thread->tid;
- int ret;
-
- ret = parasite_execute_trap_by_pid(cmd, ctl, pid, &thread->regs_orig,
- thread->rstack, thread->use_sig_blocked);
-
- return ret;
-}
-
static int parasite_execute_trap(unsigned int cmd, struct parasite_ctl *ctl)
{
- return parasite_execute_trap_by_id(cmd, ctl, 0);
+ return parasite_execute_trap_by_pid(cmd, ctl, ctl->pid.real, &ctl->regs_orig,
+ ctl->rstack, ctl->use_sig_blocked);
}
static int __parasite_send_cmd(int sockfd, struct ctl_msg *m)
@@ -395,9 +384,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
pr_info("Putting tsock into pid %d\n", pid);
args->h_addr_len = gen_parasite_saddr(&args->h_addr, getpid());
args->p_addr_len = gen_parasite_saddr(&args->p_addr, pid);
- args->nr_threads = nr_threads;
- args->sigframe = ctl->threads[0].rsigframe;
- args->id = 0;
+ args->sigframe = ctl->rsigframe;
if (sock == -1) {
int rst = -1;
@@ -444,8 +431,8 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
goto err;
}
- ctl->threads[0].sig_blocked = args->sig_blocked;
- ctl->threads[0].use_sig_blocked = true;
+ ctl->sig_blocked = args->sig_blocked;
+ ctl->use_sig_blocked = true;
if (connect(sock, (struct sockaddr *)&args->p_addr, args->p_addr_len) < 0) {
pr_perror("Can't connect a transport socket");
@@ -459,21 +446,16 @@ err:
return -1;
}
-static int parasite_daemonize(struct parasite_ctl *ctl, int id)
+static int parasite_daemonize(struct parasite_ctl *ctl)
{
- struct parasite_thread_ctl *thread = &ctl->threads[id];
- pid_t pid = thread->tid;
+ pid_t pid = ctl->pid.real;
user_regs_struct_t regs;
struct ctl_msg m = { };
- struct parasite_init_args *args;
*ctl->addr_cmd = PARASITE_CMD_DAEMONIZE;
- args = parasite_args(ctl, struct parasite_init_args);
- args->id = id;
-
- regs = thread->regs_orig;
- parasite_setup_regs(ctl->parasite_ip, thread->rstack, ®s);
+ regs = ctl->regs_orig;
+ parasite_setup_regs(ctl->parasite_ip, ctl->rstack, ®s);
if (ptrace(PTRACE_SETREGS, pid, NULL, ®s)) {
pr_perror("Can't set registers (pid: %d)", pid);
@@ -482,7 +464,7 @@ static int parasite_daemonize(struct parasite_ctl *ctl, int id)
if (ptrace(PTRACE_CONT, pid, NULL, NULL)) {
pr_perror("Can't continue (pid: %d)\n", pid);
- ptrace(PTRACE_SETREGS, pid, NULL, thread->regs_orig);
+ ptrace(PTRACE_SETREGS, pid, NULL, ctl->regs_orig);
goto err;
}
@@ -525,7 +507,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
ret = parasite_execute_trap_by_pid(PARASITE_CMD_INIT_THREAD, ctl,
pid, ®s_orig,
- ctl->threads[id].rstack, false);
+ ctl->r_thread_stack, false);
if (ret) {
pr_err("Can't init thread in parasite %d\n", pid);
return -1;
@@ -537,7 +519,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
if (parasite_execute_trap_by_pid(PARASITE_CMD_FINI_THREAD, ctl,
pid, ®s_orig,
- ctl->threads[id].rstack, true)) {
+ ctl->r_thread_stack, true)) {
pr_err("Can't init thread in parasite %d\n", pid);
return -1;
}
@@ -834,53 +816,6 @@ int parasite_get_proc_fd_seized(struct parasite_ctl *ctl)
return fd;
}
-int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *item)
-{
- struct parasite_init_args *args;
- int ret = 0, i;
-
- args = parasite_args(ctl, struct parasite_init_args);
-
- for (i = 1; i < item->nr_threads; i++) {
- pid_t tid = item->threads[i].real;
- user_regs_struct_t *regs_orig = &ctl->threads[i].regs_orig;
-
- ctl->threads[i].tid = tid;
- ctl->nr_threads++;
-
- args->id = i;
- args->sigframe = ctl->threads[i].rsigframe;
-
- ret = ptrace(PTRACE_GETREGS, tid, NULL, regs_orig);
- if (ret) {
- pr_perror("Can't obtain registers (pid: %d)", tid);
- goto err;
- }
-
- ret = parasite_execute_trap_by_id(PARASITE_CMD_INIT_THREAD, ctl, i);
- if (ret) {
- pr_err("Can't init thread in parasite %d\n", tid);
- goto err;
- }
-
- ret = get_task_regs(tid, *regs_orig, item->core[i]);
- if (ret) {
- pr_err("Can't obtain regs for thread %d\n", tid);
- goto err;
- }
-
- ctl->threads[i].sig_blocked = args->sig_blocked;
- ctl->threads[i].use_sig_blocked = true;
-
- if (parasite_daemonize(ctl, i))
- goto err;
- }
-
- return 0;
-err:
- return -1 ;
-}
-
static int parasite_fini_seized(struct parasite_ctl *ctl)
{
pid_t pid = ctl->pid.real;
@@ -949,7 +884,7 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
}
}
- ctl->threads[0].use_sig_blocked = false;
+ ctl->use_sig_blocked = false;
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
if (ret) {
@@ -994,7 +929,7 @@ int parasite_cure_remote(struct parasite_ctl *ctl)
ret = -1;
}
- if (ptrace(PTRACE_SETREGS, ctl->pid.real, NULL, &ctl->threads[0].regs_orig)) {
+ if (ptrace(PTRACE_SETREGS, ctl->pid.real, NULL, &ctl->regs_orig)) {
pr_err("Can't restore registers (pid: %d)\n", ctl->pid.real);
ret = -1;
}
@@ -1028,35 +963,31 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
return ret;
}
-struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_list, unsigned int nr_threads)
+struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_list)
{
struct parasite_ctl *ctl = NULL;
struct vma_area *vma_area;
- BUG_ON(nr_threads == 0);
-
if (!arch_can_dump_task(pid))
goto err;
/*
* Control block early setup.
*/
- ctl = xzalloc(sizeof(*ctl) + nr_threads * sizeof(ctl->threads[0]));
+ ctl = xzalloc(sizeof(*ctl));
if (!ctl) {
pr_err("Parasite control block allocation failed (pid: %d)\n", pid);
goto err;
}
ctl->tsock = -1;
- ctl->nr_threads = 1;
- ctl->threads[0].tid = pid;
- if (ptrace(PTRACE_GETREGS, pid, NULL, &ctl->threads[0].regs_orig)) {
+ if (ptrace(PTRACE_GETREGS, pid, NULL, &ctl->regs_orig)) {
pr_err("Can't obtain registers (pid: %d)\n", pid);
goto err;
}
- vma_area = get_vma_by_ip(&vma_area_list->h, REG_IP(ctl->threads[0].regs_orig));
+ vma_area = get_vma_by_ip(&vma_area_list->h, REG_IP(ctl->regs_orig));
if (!vma_area) {
pr_err("No suitable VMA found to run parasite "
"bootstrap code (pid: %d)\n", pid);
@@ -1131,16 +1062,16 @@ static unsigned long parasite_args_size(struct vm_area_list *vmas, struct parasi
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
struct vm_area_list *vma_area_list, struct parasite_drain_fd *dfds)
{
- int ret, i;
+ int ret;
struct parasite_ctl *ctl;
- unsigned long p;
+ unsigned long p, map_exchange_size;
BUG_ON(item->threads[0].real != pid);
if (pstree_alloc_cores(item))
return NULL;
- ctl = parasite_prep_ctl(pid, vma_area_list, item->nr_threads);
+ ctl = parasite_prep_ctl(pid, vma_area_list);
if (!ctl)
return NULL;
@@ -1152,9 +1083,11 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
*/
ctl->args_size = parasite_args_size(vma_area_list, dfds);
- ret = parasite_map_exchange(ctl, parasite_size + ctl->args_size +
- item->nr_threads * RESTORE_STACK_SIGFRAME +
- item->nr_threads * PARASITE_STACK_SIZE);
+ map_exchange_size = parasite_size + ctl->args_size;
+ map_exchange_size += RESTORE_STACK_SIGFRAME + PARASITE_STACK_SIZE;
+ if (item->nr_threads > 1)
+ map_exchange_size += PARASITE_STACK_SIZE;
+ ret = parasite_map_exchange(ctl, map_exchange_size);
if (ret)
goto err_restore;
@@ -1167,14 +1100,18 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
ctl->addr_args = parasite_sym(ctl->local_map, __export_parasite_args);
p = parasite_size + ctl->args_size;
- for (i = 0; i < item->nr_threads; i++) {
- struct parasite_thread_ctl *thread = &ctl->threads[i];
- thread->rstack = ctl->remote_map + p;
- thread->rsigframe = ctl->remote_map + p + PARASITE_STACK_SIZE;
- thread->sigframe = ctl->local_map + p + PARASITE_STACK_SIZE;
+ ctl->rsigframe = ctl->remote_map + p;
+ ctl->sigframe = ctl->local_map + p;
+
+ p += RESTORE_STACK_SIGFRAME;
+
+ ctl->rstack = ctl->remote_map + p;
+ p += PARASITE_STACK_SIZE;
- p += PARASITE_STACK_SIZE + RESTORE_STACK_SIGFRAME;
+ if (item->nr_threads > 1) {
+ ctl->r_thread_stack = ctl->remote_map + p;
+ p += PARASITE_STACK_SIZE;
}
ret = parasite_init(ctl, pid, item->nr_threads);
@@ -1183,7 +1120,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
goto err_restore;
}
- ret = get_task_regs(pid, ctl->threads[0].regs_orig, item->core[0]);
+ ret = get_task_regs(pid, ctl->regs_orig, item->core[0]);
if (ret) {
pr_err("Can't obtain regs for thread %d\n", pid);
goto err_restore;
@@ -1195,24 +1132,14 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
goto err_restore;
}
- if (parasite_daemonize(ctl, 0))
- goto err_restore;
-
- for (i = 0; i < 1; i++) {
- struct parasite_thread_ctl *thread = &ctl->threads[0];
+ memcpy(&item->core[0]->tc->blk_sigset,
+ &ctl->sig_blocked, sizeof(k_rtsigset_t));
- if (i == 0)
- memcpy(&item->core[i]->tc->blk_sigset,
- &thread->sig_blocked, sizeof(k_rtsigset_t));
- else {
- memcpy(&item->core[i]->thread_core->blk_sigset,
- &thread->sig_blocked, sizeof(k_rtsigset_t));
- item->core[i]->thread_core->has_blk_sigset = true;
- }
+ if (construct_sigframe(ctl->sigframe, ctl->rsigframe, item->core[0]))
+ goto err_restore;
- if (construct_sigframe(thread->sigframe, thread->rsigframe, item->core[i]))
- goto err_restore;
- }
+ if (parasite_daemonize(ctl))
+ goto err_restore;
return ctl;
--
1.8.2
More information about the CRIU
mailing list