Commit af0f5f1f authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

criu: dump: prepare parasite control for threads at infect time

Currently parasite_thread_ctl for non-leader threads is initialized after we
stop the compel daemon. Moving this initialization earlier will allow us to
make stack pointers of all threads available during memory dump.
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
parent 8fae87ee
......@@ -841,6 +841,7 @@ static int collect_file_locks(void)
static int dump_task_thread(struct parasite_ctl *parasite_ctl,
const struct pstree_item *item, int id)
{
struct parasite_thread_ctl *tctl = dmpi(item)->thread_ctls[id];
struct pid *tid = &item->threads[id];
CoreEntry *core = item->core[id];
pid_t pid = tid->real;
......@@ -851,7 +852,7 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl,
pr_info("Dumping core for thread (pid: %d)\n", pid);
pr_info("----------------------------------------\n");
ret = parasite_dump_thread_seized(parasite_ctl, id, tid, core);
ret = parasite_dump_thread_seized(tctl, parasite_ctl, id, tid, core);
if (ret) {
pr_err("Can't dump thread for pid %d\n", pid);
goto err;
......
......@@ -21,6 +21,7 @@ struct parasite_dump_cgroup_args;
struct rt_sigframe;
struct parasite_ctl;
struct parasite_thread_ctl;
extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct pstree_item *);
extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *);
......@@ -32,8 +33,9 @@ extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc
extern int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc);
extern int parasite_dump_creds(struct parasite_ctl *ctl, struct _CredsEntry *ce);
extern int parasite_dump_thread_leader_seized(struct parasite_ctl *ctl, int pid, struct _CoreEntry *core);
extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
struct pid *tid, struct _CoreEntry *core);
extern int parasite_dump_thread_seized(struct parasite_thread_ctl *tctl,
struct parasite_ctl *ctl, int id,
struct pid *tid, struct _CoreEntry *core);
extern int dump_thread_core(int pid, CoreEntry *core,
const struct parasite_dump_thread *dt);
......
......@@ -56,6 +56,7 @@ struct dmp_info {
struct ns_id *netns;
struct page_pipe *mem_pp;
struct parasite_ctl *parasite_ctl;
struct parasite_thread_ctl **thread_ctls;
};
static inline struct dmp_info *dmpi(const struct pstree_item *i)
......
......@@ -162,7 +162,8 @@ int parasite_dump_thread_leader_seized(struct parasite_ctl *ctl, int pid, CoreEn
return dump_thread_core(pid, core, args);
}
int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
int parasite_dump_thread_seized(struct parasite_thread_ctl *tctl,
struct parasite_ctl *ctl, int id,
struct pid *tid, CoreEntry *core)
{
struct parasite_dump_thread *args;
......@@ -171,7 +172,6 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
CredsEntry *creds = tc->creds;
struct parasite_dump_creds *pc;
int ret;
struct parasite_thread_ctl *tctl;
BUG_ON(id == 0); /* Leader is dumped in dump_task_core_all */
......@@ -180,10 +180,6 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
pc = args->creds;
pc->cap_last_cap = kdat.last_cap;
tctl = compel_prepare_thread(ctl, pid);
if (!tctl)
return -1;
tc->has_blk_sigset = true;
memcpy(&tc->blk_sigset, compel_thread_sigmask(tctl), sizeof(k_rtsigset_t));
ret = compel_get_thread_regs(tctl, save_task_regs, core);
......@@ -468,12 +464,39 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe *
return construct_sigframe(sf, rtsf, bs, (CoreEntry *)arg);
}
static int parasite_prepare_threads(struct parasite_ctl *ctl,
struct pstree_item *item)
{
struct parasite_thread_ctl **thread_ctls;
int i;
thread_ctls = xzalloc(sizeof(*thread_ctls) * item->nr_threads);
if (!thread_ctls)
return -1;
for (i = 0; i < item->nr_threads; i++) {
struct pid *tid = &item->threads[i];
if (item->pid->real == tid->real)
continue;
thread_ctls[i] = compel_prepare_thread(ctl, tid->real);
if (!thread_ctls[i])
return -1;
}
dmpi(item)->thread_ctls = thread_ctls;
return 0;
}
struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
struct vm_area_list *vma_area_list)
{
struct parasite_ctl *ctl;
struct infect_ctx *ictx;
unsigned long p;
int ret;
BUG_ON(item->threads[0].real != pid);
......@@ -487,6 +510,10 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
if (!ctl)
return NULL;
ret = parasite_prepare_threads(ctl, item);
if (ret)
return NULL;
ictx = compel_infect_ctx(ctl);
ictx->open_proc = do_open_proc;
......@@ -532,4 +559,3 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
return ctl;
}
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