[CRIU] [PATCH 3/6] criu: dump: prepare parasite control for threads at infect time
Mike Rapoport
rppt at linux.vnet.ibm.com
Thu Aug 16 19:30:58 MSK 2018
On Thu, Aug 16, 2018 at 06:08:56PM +0200, Laurent Dufour wrote:
> On 13/08/2018 15:29, Mike Rapoport wrote:
> > 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.
>
> I've to admit that I'm no more accurate on that part, so my question could make
> no sense: What would happen if a thread dies while dumping the memory, which is
> quite a long operation ?
By the time memory dump happens all the threads are anyway stopped.
Currently we just collect thread data late in the process, but threads are
nor running.
> Cheers,
> Laurent.
>
>
> > Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
> > ---
> > criu/cr-dump.c | 3 ++-
> > criu/include/parasite-syscall.h | 6 ++++--
> > criu/include/pstree.h | 1 +
> > criu/parasite-syscall.c | 40 +++++++++++++++++++++++++++++++++-------
> > 4 files changed, 40 insertions(+), 10 deletions(-)
> >
> > diff --git a/criu/cr-dump.c b/criu/cr-dump.c
> > index 6596793..ec5e1e4 100644
> > --- a/criu/cr-dump.c
> > +++ b/criu/cr-dump.c
> > @@ -842,6 +842,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;
> > @@ -852,7 +853,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;
> > diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
> > index 0e9d340..c86a724 100644
> > --- a/criu/include/parasite-syscall.h
> > +++ b/criu/include/parasite-syscall.h
> > @@ -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);
> >
> > diff --git a/criu/include/pstree.h b/criu/include/pstree.h
> > index 508d6df..4913aae 100644
> > --- a/criu/include/pstree.h
> > +++ b/criu/include/pstree.h
> > @@ -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)
> > diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
> > index 267d3fa..366c6c9 100644
> > --- a/criu/parasite-syscall.c
> > +++ b/criu/parasite-syscall.c
> > @@ -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;
> > }
> > -
> >
--
Sincerely yours,
Mike.
More information about the CRIU
mailing list