diff --git a/cr-dump.c b/cr-dump.c index b2df6b0d3..96e147ca0 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -1529,7 +1529,7 @@ static int dump_one_task(struct pstree_item *item) } ret = -1; - parasite_ctl = parasite_infect_seized(pid, &vma_area_list); + parasite_ctl = parasite_infect_seized(pid, item, &vma_area_list); if (!parasite_ctl) { pr_err("Can't infect (pid: %d) with parasite\n", pid); goto err; diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h index bf9792ec4..e94032044 100644 --- a/include/parasite-syscall.h +++ b/include/parasite-syscall.h @@ -46,7 +46,10 @@ extern int parasite_drain_fds_seized(struct parasite_ctl *ctl, extern int parasite_get_proc_fd_seized(struct parasite_ctl *ctl); extern int parasite_cure_seized(struct parasite_ctl *ctl); + +struct pstree_item; extern struct parasite_ctl *parasite_infect_seized(pid_t pid, + struct pstree_item *item, struct list_head *vma_area_list); 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 29b5f63f0..cdfaac6ef 100644 --- a/include/parasite.h +++ b/include/parasite.h @@ -44,6 +44,8 @@ struct parasite_init_args { int p_addr_len; struct sockaddr_un p_addr; + + int nr_threads; }; struct parasite_log_args { diff --git a/parasite-syscall.c b/parasite-syscall.c index dd67c4b6b..bc0139f73 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -348,7 +348,7 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid) return 0; } -static int parasite_init(struct parasite_ctl *ctl, pid_t pid) +static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads) { struct parasite_init_args *args; static int sock = -1; @@ -358,6 +358,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid) pr_info("Putting tsock into pid %d\n", pid); args->h_addr_len = gen_parasite_saddr(&args->h_addr, 0); args->p_addr_len = gen_parasite_saddr(&args->p_addr, pid); + args->nr_threads = nr_threads; if (sock == -1) { int rst = -1; @@ -713,7 +714,7 @@ int parasite_cure_seized(struct parasite_ctl *ctl) return ret; } -struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_area_list) +struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct list_head *vma_area_list) { struct parasite_ctl *ctl = NULL; struct vma_area *vma_area; @@ -798,7 +799,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct list_head *vma_are ctl->addr_cmd = (unsigned int *)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, item->nr_threads); if (ret) { pr_err("%d: Can't create a transport socket\n", pid); goto err_restore; diff --git a/parasite.c b/parasite.c index ffb71f0e8..18140aabf 100644 --- a/parasite.c +++ b/parasite.c @@ -20,6 +20,18 @@ static void *brk_start, *brk_end, *brk_tail; static int tsock = -1; +static struct tid_state_s { + pid_t tid; + bool use_sig_blocked; + k_rtsigset_t sig_blocked; +} *tid_state; + +static unsigned int nr_tid_state; +#define TID_STATE_SIZE(n) \ + (ALIGN(sizeof(struct tid_state_s) * n, PAGE_SIZE)) + +#define thread_leader (&tid_state[0]) + #define MAX_HEAP_SIZE (10 << 20) /* Hope 10MB will be enough... */ static int brk_init(void) @@ -341,10 +353,22 @@ static int init(struct parasite_init_args *args) k_rtsigset_t to_block; int ret; + if (!args->nr_threads) + return -EINVAL; + ret = brk_init(); if (ret < 0) return ret; + tid_state = (void *)sys_mmap(NULL, TID_STATE_SIZE(args->nr_threads), + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + if ((long)tid_state < 0) + return -ENOMEM; + + nr_tid_state = args->nr_threads; + tsock = sys_socket(PF_UNIX, SOCK_DGRAM, 0); if (tsock < 0) return tsock; @@ -505,6 +529,8 @@ static int fini(void) if (reset_blocked == 1) sys_sigprocmask(SIG_SETMASK, &old_blocked, NULL, sizeof(k_rtsigset_t)); + sys_munmap(tid_state, TID_STATE_SIZE(nr_tid_state)); + log_set_fd(-1); sys_close(tsock); brk_fini();