mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-29 13:28:27 +00:00
parasite: execute only one parasite commend for dumping per-thread data
We use two commands to get task registers safely. The first command blocked signals, then crtools dumped registers and all per-thread data and the the second command unblocks signals. Currently signals can be blocked with help SETSIGMASK, so we need only one command to dump per-thread data. Signed-off-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
f68f37a11f
commit
45ed5c0ee5
@ -24,7 +24,7 @@ enum {
|
|||||||
PARASITE_CMD_ACK,
|
PARASITE_CMD_ACK,
|
||||||
|
|
||||||
PARASITE_CMD_INIT,
|
PARASITE_CMD_INIT,
|
||||||
PARASITE_CMD_INIT_THREAD,
|
PARASITE_CMD_DUMP_THREAD,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These two must be greater than INITs.
|
* These two must be greater than INITs.
|
||||||
@ -34,7 +34,6 @@ enum {
|
|||||||
|
|
||||||
PARASITE_CMD_CFG_LOG,
|
PARASITE_CMD_CFG_LOG,
|
||||||
PARASITE_CMD_FINI,
|
PARASITE_CMD_FINI,
|
||||||
PARASITE_CMD_FINI_THREAD,
|
|
||||||
|
|
||||||
PARASITE_CMD_MPROTECT_VMAS,
|
PARASITE_CMD_MPROTECT_VMAS,
|
||||||
PARASITE_CMD_DUMPPAGES,
|
PARASITE_CMD_DUMPPAGES,
|
||||||
@ -164,7 +163,6 @@ struct parasite_dump_creds {
|
|||||||
struct parasite_dump_thread {
|
struct parasite_dump_thread {
|
||||||
unsigned int *tid_addr;
|
unsigned int *tid_addr;
|
||||||
pid_t tid;
|
pid_t tid;
|
||||||
k_rtsigset_t blocked;
|
|
||||||
u32 tls;
|
u32 tls;
|
||||||
stack_t sas;
|
stack_t sas;
|
||||||
};
|
};
|
||||||
|
@ -506,7 +506,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = parasite_execute_trap_by_pid(PARASITE_CMD_INIT_THREAD, ctl,
|
ret = parasite_execute_trap_by_pid(PARASITE_CMD_DUMP_THREAD, ctl,
|
||||||
pid, ®s_orig,
|
pid, ®s_orig,
|
||||||
ctl->r_thread_stack,
|
ctl->r_thread_stack,
|
||||||
(k_rtsigset_t *) &core->thread_core->blk_sigset);
|
(k_rtsigset_t *) &core->thread_core->blk_sigset);
|
||||||
@ -516,18 +516,10 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = get_task_regs(pid, regs_orig, core);
|
ret = get_task_regs(pid, regs_orig, core);
|
||||||
if (ret)
|
if (ret) {
|
||||||
pr_err("Can't obtain regs for thread %d\n", pid);
|
pr_err("Can't obtain regs for thread %d\n", pid);
|
||||||
|
|
||||||
if (parasite_execute_trap_by_pid(PARASITE_CMD_FINI_THREAD, ctl,
|
|
||||||
pid, ®s_orig,
|
|
||||||
ctl->r_thread_stack,
|
|
||||||
(k_rtsigset_t *) &core->thread_core->blk_sigset)) {
|
|
||||||
pr_err("Can't init thread in parasite %d\n", pid);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
BUG_ON(!core->thread_core->sas);
|
BUG_ON(!core->thread_core->sas);
|
||||||
copy_sas(core->thread_core->sas, &args->sas);
|
copy_sas(core->thread_core->sas, &args->sas);
|
||||||
@ -536,7 +528,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
|
|||||||
tid->virt = args->tid;
|
tid->virt = args->tid;
|
||||||
core_put_tls(core, args->tls);
|
core_put_tls(core, args->tls);
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
|
int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
|
||||||
|
@ -203,41 +203,21 @@ static int drain_fds(struct parasite_drain_fd *args)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_thread(struct parasite_dump_thread *args)
|
static int dump_thread(struct parasite_dump_thread *args)
|
||||||
{
|
{
|
||||||
k_rtsigset_t to_block;
|
|
||||||
pid_t tid = sys_gettid();
|
pid_t tid = sys_gettid();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ksigfillset(&to_block);
|
|
||||||
ret = sys_sigprocmask(SIG_SETMASK, &to_block,
|
|
||||||
&args->blocked,
|
|
||||||
sizeof(k_rtsigset_t));
|
|
||||||
if (ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
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)
|
||||||
goto err;
|
return ret;
|
||||||
|
|
||||||
args->tid = tid;
|
args->tid = tid;
|
||||||
args->tls = arch_get_tls();
|
args->tls = arch_get_tls();
|
||||||
|
|
||||||
ret = sys_sigaltstack(NULL, &args->sas);
|
ret = sys_sigaltstack(NULL, &args->sas);
|
||||||
if (ret)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
err:
|
|
||||||
sys_sigprocmask(SIG_SETMASK, &args->blocked,
|
|
||||||
NULL, sizeof(k_rtsigset_t));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fini_thread(struct parasite_dump_thread *args)
|
|
||||||
{
|
|
||||||
return sys_sigprocmask(SIG_SETMASK, &args->blocked,
|
|
||||||
NULL, sizeof(k_rtsigset_t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init(struct parasite_init_args *args)
|
static int init(struct parasite_init_args *args)
|
||||||
@ -569,10 +549,8 @@ int __used parasite_service(unsigned int cmd, void *args)
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case PARASITE_CMD_INIT:
|
case PARASITE_CMD_INIT:
|
||||||
return init(args);
|
return init(args);
|
||||||
case PARASITE_CMD_INIT_THREAD:
|
case PARASITE_CMD_DUMP_THREAD:
|
||||||
return init_thread(args);
|
return dump_thread(args);
|
||||||
case PARASITE_CMD_FINI_THREAD:
|
|
||||||
return fini_thread(args);
|
|
||||||
case PARASITE_CMD_CFG_LOG:
|
case PARASITE_CMD_CFG_LOG:
|
||||||
return parasite_cfg_log(args);
|
return parasite_cfg_log(args);
|
||||||
case PARASITE_CMD_DAEMONIZE:
|
case PARASITE_CMD_DAEMONIZE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user