[CRIU] [PATCH 12/21] dump: return signal mask from parasite on initialization
Andrey Vagin
avagin at openvz.org
Fri May 24 08:20:15 EDT 2013
and check that signals are blocked for each thread separately
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
arch/arm/crtools.c | 2 +-
arch/x86/crtools.c | 2 +-
cr-dump.c | 7 +++++--
include/parasite-syscall.h | 8 +++++---
include/parasite.h | 3 ++-
parasite-syscall.c | 31 ++++++++++++++++++++++++-------
pie/parasite.c | 13 +++++--------
7 files changed, 43 insertions(+), 23 deletions(-)
diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c
index 7c9c50e..05abd99 100644
--- a/arch/arm/crtools.c
+++ b/arch/arm/crtools.c
@@ -77,7 +77,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);
+ &ctl->threads[0].regs_orig, 0);
if (err)
return err;
diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c
index 5f525de..7b69599 100644
--- a/arch/x86/crtools.c
+++ b/arch/x86/crtools.c
@@ -101,7 +101,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);
+ &ctl->threads[0].regs_orig, 0);
if (err)
return err;
diff --git a/cr-dump.c b/cr-dump.c
index 33a66e9..00d72f9 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -630,6 +630,7 @@ static int dump_task_core_all(struct parasite_ctl *ctl,
struct vm_area_list *vma_area_list,
const struct cr_fdset *cr_fdset)
{
+ k_rtsigset_t *sig_blocked = &ctl->threads[0].sig_blocked;
int fd_core = fdset_fd(cr_fdset, CR_FD_CORE);
int ret = -1;
pid_t pid = ctl->pid.real;
@@ -655,7 +656,7 @@ static int dump_task_core_all(struct parasite_ctl *ctl,
strncpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN);
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));
+ memcpy(&core->tc->blk_sigset, sig_blocked, sizeof(k_rtsigset_t));
core->tc->task_state = TASK_ALIVE;
core->tc->exit_code = 0;
@@ -1079,10 +1080,11 @@ static int collect_file_locks(void)
static int dump_task_thread(struct parasite_ctl *parasite_ctl,
const struct pstree_item *item, int id)
{
- int ret = -1, fd_core;
+ k_rtsigset_t *sig_blocked = ¶site_ctl->threads[id].sig_blocked;
struct pid *tid = &item->threads[id];
CoreEntry *core = item->core[id];
pid_t pid = tid->real;
+ int ret = -1, fd_core;
pr_info("\n");
pr_info("Dumping core for thread (pid: %d)\n", pid);
@@ -1099,6 +1101,7 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl,
}
core->thread_core->has_blk_sigset = true;
+ memcpy(&core->thread_core->blk_sigset, sig_blocked, sizeof(*sig_blocked));
ret = dump_sched_info(pid, core->thread_core);
if (ret)
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index c736289..ac3bc3f 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -12,6 +12,9 @@ struct parasite_thread_ctl
bool daemonized;
+ k_rtsigset_t sig_blocked;
+ bool use_sig_blocked;
+
void *rstack;
};
@@ -26,8 +29,6 @@ struct parasite_ctl {
unsigned long syscall_ip; /* entry point of infection */
u8 code_orig[BUILTIN_SYSCALL_SIZE];
- int signals_blocked;
-
unsigned int *addr_cmd; /* addr for command */
void *addr_args; /* address for arguments */
unsigned long args_size;
@@ -103,6 +104,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
extern bool arch_can_dump_task(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_orig);
+ user_regs_struct_t *regs_orig,
+ bool signals_blocked);
#endif /* __CR_PARASITE_SYSCALL_H__ */
diff --git a/include/parasite.h b/include/parasite.h
index 9ad3161..5ea6847 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -72,6 +72,8 @@ struct parasite_init_args {
struct sockaddr_un p_addr;
int nr_threads;
+
+ k_rtsigset_t sig_blocked;
};
struct parasite_log_args {
@@ -120,7 +122,6 @@ struct parasite_dump_itimers_args {
struct parasite_dump_misc {
unsigned long brk;
- k_rtsigset_t blocked;
u32 pid;
u32 sid;
diff --git a/parasite-syscall.c b/parasite-syscall.c
index e2824ab..e206fb9 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -63,7 +63,8 @@ static struct vma_area *get_vma_by_ip(struct list_head *vma_area_list, unsigned
/* we run at @regs->ip */
int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
user_regs_struct_t *regs,
- user_regs_struct_t *regs_orig)
+ user_regs_struct_t *regs_orig,
+ bool signals_blocked)
{
siginfo_t siginfo;
int status;
@@ -110,7 +111,7 @@ retry_signal:
pr_debug("** delivering signal %d si_code=%d\n",
siginfo.si_signo, siginfo.si_code);
- if (ctl->signals_blocked) {
+ if (signals_blocked) {
pr_err("Unexpected %d task interruption, aborting\n", pid);
goto err;
}
@@ -208,7 +209,8 @@ static int parasite_execute_trap_by_id(unsigned int cmd, struct parasite_ctl *ct
parasite_setup_regs(ctl->parasite_ip, thread->rstack, ®s);
- ret = __parasite_execute_trap(ctl, pid, ®s, &thread->regs_orig);
+ ret = __parasite_execute_trap(ctl, pid, ®s, &thread->regs_orig,
+ thread->use_sig_blocked);
if (ret == 0)
ret = (int)REG_RES(regs);
@@ -430,6 +432,9 @@ 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;
+
if (connect(sock, (struct sockaddr *)&args->p_addr, args->p_addr_len) < 0) {
pr_perror("Can't connect a transport socket");
goto err;
@@ -496,7 +501,6 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int 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);
tid->virt = args->tid;
core_put_tls(core, args->tls);
@@ -699,6 +703,9 @@ int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *i
goto err;
}
+ ctl->threads[i].sig_blocked = args->sig_blocked;
+ ctl->threads[i].use_sig_blocked = true;
+
if (parasite_daemonize(ctl, i))
goto err;
}
@@ -790,7 +797,6 @@ int parasite_cure_remote(struct parasite_ctl *ctl)
int ret = 0;
if (ctl->parasite_ip) {
- ctl->signals_blocked = 0;
ret = parasite_fini_threads_seized(ctl);
parasite_fini_seized(ctl);
}
@@ -1001,8 +1007,6 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
goto err_restore;
}
- ctl->signals_blocked = 1;
-
ret = parasite_set_logfd(ctl, pid);
if (ret) {
pr_err("%d: Can't set a logging descriptor\n", pid);
@@ -1016,6 +1020,19 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
if (ret)
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;
err_restore:
diff --git a/pie/parasite.c b/pie/parasite.c
index 76e6ee8..8cf0f09 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -119,7 +119,6 @@ static int dump_itimers(struct parasite_dump_itimers_args *args)
static int dump_misc(struct parasite_dump_misc *args)
{
args->brk = sys_brk(0);
- args->blocked = thread_leader->sig_blocked;
args->pid = sys_getpid();
args->sid = sys_getsid();
@@ -178,18 +177,13 @@ static int drain_fds(struct parasite_drain_fd *args)
static int dump_thread(struct parasite_dump_thread *args)
{
- struct tid_state_s *s = &tid_state[args->id];
pid_t tid = sys_gettid();
int ret;
- if (!s->use_sig_blocked)
- return -EINVAL;
-
ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &args->tid_addr, 0, 0, 0);
if (ret)
return ret;
- args->blocked = s->sig_blocked;
args->tid = tid;
args->tls = arch_get_tls();
@@ -211,8 +205,11 @@ static int init_thread(struct parasite_init_args *args)
ret = sys_sigprocmask(SIG_SETMASK, &to_block,
&tid_state[next_tid_state].sig_blocked,
sizeof(k_rtsigset_t));
- if (ret >= 0)
- tid_state[next_tid_state].use_sig_blocked = true;
+ if (ret)
+ 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;
--
1.8.2
More information about the CRIU
mailing list