Commit 75a3932b authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

dump: Return signal mask from parasite on initialization

This mask should be put into sigframe (used by parasite, coming
soon) thus we have to pull one from dumpee early.

Plus, check that signals are blocked for each thread separately
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 595b772a
...@@ -78,7 +78,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -78,7 +78,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
parasite_setup_regs(ctl->syscall_ip, 0, &regs); parasite_setup_regs(ctl->syscall_ip, 0, &regs);
err = __parasite_execute_trap(ctl, ctl->pid.real, &regs, err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
&ctl->threads[0].regs_orig); &ctl->threads[0].regs_orig, 0);
if (err) if (err)
return err; return err;
......
...@@ -102,7 +102,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -102,7 +102,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
parasite_setup_regs(ctl->syscall_ip, 0, &regs); parasite_setup_regs(ctl->syscall_ip, 0, &regs);
err = __parasite_execute_trap(ctl, ctl->pid.real, &regs, err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
&ctl->threads[0].regs_orig); &ctl->threads[0].regs_orig, 0);
if (err) if (err)
return err; return err;
......
...@@ -655,8 +655,6 @@ static int dump_task_core_all(struct parasite_ctl *ctl, ...@@ -655,8 +655,6 @@ static int dump_task_core_all(struct parasite_ctl *ctl,
strncpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN); strncpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN);
core->tc->flags = stat->flags; core->tc->flags = stat->flags;
BUILD_BUG_ON(sizeof(core->tc->blk_sigset) != sizeof(k_rtsigset_t));
memcpy(&core->tc->blk_sigset, &misc->blocked, sizeof(k_rtsigset_t));
core->tc->task_state = TASK_ALIVE; core->tc->task_state = TASK_ALIVE;
core->tc->exit_code = 0; core->tc->exit_code = 0;
...@@ -1080,10 +1078,10 @@ static int collect_file_locks(void) ...@@ -1080,10 +1078,10 @@ static int collect_file_locks(void)
static int dump_task_thread(struct parasite_ctl *parasite_ctl, static int dump_task_thread(struct parasite_ctl *parasite_ctl,
const struct pstree_item *item, int id) const struct pstree_item *item, int id)
{ {
int ret = -1, fd_core;
struct pid *tid = &item->threads[id]; struct pid *tid = &item->threads[id];
CoreEntry *core = item->core[id]; CoreEntry *core = item->core[id];
pid_t pid = tid->real; pid_t pid = tid->real;
int ret = -1, fd_core;
pr_info("\n"); pr_info("\n");
pr_info("Dumping core for thread (pid: %d)\n", pid); pr_info("Dumping core for thread (pid: %d)\n", pid);
...@@ -1099,8 +1097,6 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl, ...@@ -1099,8 +1097,6 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl,
goto err; goto err;
} }
core->thread_core->has_blk_sigset = true;
ret = dump_sched_info(pid, core->thread_core); ret = dump_sched_info(pid, core->thread_core);
if (ret) if (ret)
goto err; goto err;
......
...@@ -12,6 +12,9 @@ struct parasite_thread_ctl ...@@ -12,6 +12,9 @@ struct parasite_thread_ctl
bool daemonized; bool daemonized;
k_rtsigset_t sig_blocked;
bool use_sig_blocked;
void *rstack; void *rstack;
}; };
...@@ -26,8 +29,6 @@ struct parasite_ctl { ...@@ -26,8 +29,6 @@ struct parasite_ctl {
unsigned long syscall_ip; /* entry point of infection */ unsigned long syscall_ip; /* entry point of infection */
u8 code_orig[BUILTIN_SYSCALL_SIZE]; u8 code_orig[BUILTIN_SYSCALL_SIZE];
int signals_blocked;
unsigned int *addr_cmd; /* addr for command */ unsigned int *addr_cmd; /* addr for command */
void *addr_args; /* address for arguments */ void *addr_args; /* address for arguments */
unsigned long args_size; unsigned long args_size;
...@@ -102,7 +103,8 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret, ...@@ -102,7 +103,8 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
extern int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid, extern int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
user_regs_struct_t *regs, user_regs_struct_t *regs,
user_regs_struct_t *regs_orig); user_regs_struct_t *regs_orig,
bool signals_blocked);
extern bool arch_can_dump_task(pid_t pid); extern bool arch_can_dump_task(pid_t pid);
extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid, extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
......
...@@ -73,6 +73,8 @@ struct parasite_init_args { ...@@ -73,6 +73,8 @@ struct parasite_init_args {
struct sockaddr_un p_addr; struct sockaddr_un p_addr;
int nr_threads; int nr_threads;
k_rtsigset_t sig_blocked;
}; };
struct parasite_log_args { struct parasite_log_args {
...@@ -128,7 +130,6 @@ struct parasite_dump_itimers_args { ...@@ -128,7 +130,6 @@ struct parasite_dump_itimers_args {
struct parasite_dump_misc { struct parasite_dump_misc {
unsigned long brk; unsigned long brk;
k_rtsigset_t blocked;
u32 pid; u32 pid;
u32 sid; u32 sid;
......
...@@ -65,7 +65,8 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned ...@@ -65,7 +65,8 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned
/* we run at @regs->ip */ /* we run at @regs->ip */
int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid, int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
user_regs_struct_t *regs, user_regs_struct_t *regs,
user_regs_struct_t *regs_orig) user_regs_struct_t *regs_orig,
bool signals_blocked)
{ {
siginfo_t siginfo; siginfo_t siginfo;
int status; int status;
...@@ -112,7 +113,7 @@ retry_signal: ...@@ -112,7 +113,7 @@ retry_signal:
pr_debug("** delivering signal %d si_code=%d\n", pr_debug("** delivering signal %d si_code=%d\n",
siginfo.si_signo, siginfo.si_code); siginfo.si_signo, siginfo.si_code);
if (ctl->signals_blocked) { if (signals_blocked) {
pr_err("Unexpected %d task interruption, aborting\n", pid); pr_err("Unexpected %d task interruption, aborting\n", pid);
goto err; goto err;
} }
...@@ -210,7 +211,8 @@ static int parasite_execute_trap_by_id(unsigned int cmd, struct parasite_ctl *ct ...@@ -210,7 +211,8 @@ static int parasite_execute_trap_by_id(unsigned int cmd, struct parasite_ctl *ct
parasite_setup_regs(ctl->parasite_ip, thread->rstack, &regs); parasite_setup_regs(ctl->parasite_ip, thread->rstack, &regs);
ret = __parasite_execute_trap(ctl, pid, &regs, &thread->regs_orig); ret = __parasite_execute_trap(ctl, pid, &regs, &thread->regs_orig,
thread->use_sig_blocked);
if (ret == 0) if (ret == 0)
ret = (int)REG_RES(regs); ret = (int)REG_RES(regs);
...@@ -432,6 +434,9 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads) ...@@ -432,6 +434,9 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
goto err; goto err;
} }
ctl->threads[0].sig_blocked = args->sig_blocked;
ctl->threads[0].use_sig_blocked = true;
if (connect(sock, (struct sockaddr *)&args->p_addr, args->p_addr_len) < 0) { if (connect(sock, (struct sockaddr *)&args->p_addr, args->p_addr_len) < 0) {
pr_perror("Can't connect a transport socket"); pr_perror("Can't connect a transport socket");
goto err; goto err;
...@@ -498,7 +503,6 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id, ...@@ -498,7 +503,6 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
ret = parasite_execute_daemon_by_id(PARASITE_CMD_DUMP_THREAD, ctl, id); ret = parasite_execute_daemon_by_id(PARASITE_CMD_DUMP_THREAD, ctl, id);
memcpy(&core->thread_core->blk_sigset, &args->blocked, sizeof(args->blocked));
CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(args->tid_addr); CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(args->tid_addr);
tid->virt = args->tid; tid->virt = args->tid;
core_put_tls(core, args->tls); core_put_tls(core, args->tls);
...@@ -820,6 +824,9 @@ int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *i ...@@ -820,6 +824,9 @@ int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *i
goto err; goto err;
} }
ctl->threads[i].sig_blocked = args->sig_blocked;
ctl->threads[i].use_sig_blocked = true;
if (parasite_daemonize(ctl, i)) if (parasite_daemonize(ctl, i))
goto err; goto err;
} }
...@@ -911,7 +918,6 @@ int parasite_cure_remote(struct parasite_ctl *ctl) ...@@ -911,7 +918,6 @@ int parasite_cure_remote(struct parasite_ctl *ctl)
int ret = 0; int ret = 0;
if (ctl->parasite_ip) { if (ctl->parasite_ip) {
ctl->signals_blocked = 0;
ret = parasite_fini_threads_seized(ctl); ret = parasite_fini_threads_seized(ctl);
parasite_fini_seized(ctl); parasite_fini_seized(ctl);
} }
...@@ -1122,8 +1128,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -1122,8 +1128,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
goto err_restore; goto err_restore;
} }
ctl->signals_blocked = 1;
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);
...@@ -1137,6 +1141,19 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -1137,6 +1141,19 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
if (ret) if (ret)
goto err_restore; goto err_restore;
for (i = 0; i < item->nr_threads; i++) {
struct parasite_thread_ctl *thread = &ctl->threads[i];
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;
}
}
return ctl; return ctl;
err_restore: err_restore:
......
...@@ -120,7 +120,6 @@ static int dump_itimers(struct parasite_dump_itimers_args *args) ...@@ -120,7 +120,6 @@ static int dump_itimers(struct parasite_dump_itimers_args *args)
static int dump_misc(struct parasite_dump_misc *args) static int dump_misc(struct parasite_dump_misc *args)
{ {
args->brk = sys_brk(0); args->brk = sys_brk(0);
args->blocked = thread_leader->sig_blocked;
args->pid = sys_getpid(); args->pid = sys_getpid();
args->sid = sys_getsid(); args->sid = sys_getsid();
...@@ -179,18 +178,13 @@ static int drain_fds(struct parasite_drain_fd *args) ...@@ -179,18 +178,13 @@ static int drain_fds(struct parasite_drain_fd *args)
static int dump_thread(struct parasite_dump_thread *args) static int dump_thread(struct parasite_dump_thread *args)
{ {
struct tid_state_s *s = &tid_state[args->id];
pid_t tid = sys_gettid(); pid_t tid = sys_gettid();
int ret; int ret;
if (!s->use_sig_blocked)
return -EINVAL;
ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &args->tid_addr, 0, 0, 0); ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &args->tid_addr, 0, 0, 0);
if (ret) if (ret)
return ret; return ret;
args->blocked = s->sig_blocked;
args->tid = tid; args->tid = tid;
args->tls = arch_get_tls(); args->tls = arch_get_tls();
...@@ -212,8 +206,11 @@ static int init_thread(struct parasite_init_args *args) ...@@ -212,8 +206,11 @@ static int init_thread(struct parasite_init_args *args)
ret = sys_sigprocmask(SIG_SETMASK, &to_block, ret = sys_sigprocmask(SIG_SETMASK, &to_block,
&tid_state[next_tid_state].sig_blocked, &tid_state[next_tid_state].sig_blocked,
sizeof(k_rtsigset_t)); sizeof(k_rtsigset_t));
if (ret >= 0) if (ret)
tid_state[next_tid_state].use_sig_blocked = true; return -1;
tid_state[next_tid_state].use_sig_blocked = true;
args->sig_blocked = tid_state[next_tid_state].sig_blocked;
tid_state[next_tid_state].id = next_tid_state; tid_state[next_tid_state].id = next_tid_state;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment