From 616b96421eaf1aa2e57a7cc89c9d6dd00f52ebc3 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 12 Nov 2012 17:42:48 +0400 Subject: [PATCH] parasite: Rework init/fini to reserve/free space for per-thread data The per-thread information requires own space in parasite data. In particular we will keep the blocked signals bound to thread pids. For this sake the caller need to provide the parasite how many threads will be used to calculate space. Signed-off-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov --- cr-dump.c | 2 +- include/parasite-syscall.h | 3 +++ include/parasite.h | 2 ++ parasite-syscall.c | 7 ++++--- parasite.c | 26 ++++++++++++++++++++++++++ 5 files changed, 36 insertions(+), 4 deletions(-) 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();