[CRIU] [PATCH v4 04/12] gc: implement link remaps deletion

Eugene Batalov eabatalov89 at gmail.com
Tue Oct 25 11:51:37 PDT 2016


2016-10-25 15:50 GMT+03:00 Pavel Emelyanov <xemul at virtuozzo.com>:

> On 10/24/2016 11:57 PM, Eugene Batalov wrote:
> > 2016-10-12 11:54 GMT+03:00 Pavel Emelyanov <xemul at virtuozzo.com <mailto:
> xemul at virtuozzo.com>>:
> >
> >     On 09/11/2016 08:14 PM, Eugene Batalov wrote:
> >     > We reuse minimal subset of criu restore command logic sufficient
> >     > to locate all the link remaps in all ps tree mnt namespaces.
> >     > No ps tree processes are created but all the ps tree mnt
> >     > namespaces and mountpoints are created. After creation of ps
> >     > tree mnt namespaces each link remap is deleted in its namespace.
> >     >
> >     > Exact logic is the following:
> >     > 1. check_img_inventory() - prepare_pstree(). These calls are
> needed to
> >     >    initialize root_ns_mask that is used during ps tree mnt
> namespaces
> >     >    creation.
> >
> >     The root_ns_mask() is set up only in prepare_pstree() (which does
> much
> >     more than just this). But what is check_img_inventory() for?
> >
> >
> > check_img_inventory() call is intended to check that criu dump files
> that we pass to criu gc are supported and somewhat valid.
> > check_img_inventory() is also called in the beginning of criu restore
> and cr_lazy_pages.
> > So it looks like we should have it in cr-gc.
>
> OK
>
> >
> >
> >     > 2. prepare_shared_fdinfo() - collect_remaps_and_regfiles(). These
> calls
> >     >    are needed to collect information about link remaps and reg
> files of
> >     >    ps tree from dump.
> >
> >     Why prepare_shared_fdinfo() needed?
> >
> >
> > prepare_shared_fdinfo() is needed because during
> collect_remaps_and_regfiles() call collect_one_regfile() is called
> > and collect_one_regfile() calls file_desc_add().
>
> Got it. Please, rename prepare_shared_fdinfo() into prepare_files() :)
>

Ok.


>
> >
> >
> >     > 3. gc_setup_mntns() (if needed) creates all the ps tree mnt
> namespaces
> >     >    and performs mounting of proper fs hierachies into them.
> >
> >     The read_mntns_img() does this, no?
> >
> >
> > No. The whole logic of gc_setup_mntns() does this. The main component of
> gc_setup_mntns() is prepare_mnt_ns() call that instantiates
> > all the ps tree mnt namespaces and their root file systems.
> >
>
> Mm... So what exact objects do you need initialized by this?
>

So we need to delete link remaps. Link remaps are created by criu dump.
They are created on some fs mounted on some mount point that belong to fs
hierarchy of some mnt namespace. Process tree may have many mnt namespaces.
We have information about all the link remaps in dump files. Each link
remap information has path from root of namespace where link remaps fs is
mounted.
So if we recreate all the mnt namespaces and fs hierarchies then we'll be
able to delete all the link remaps. We do the same on criu restore so let's
reuse the logic. The logic is reused by gc_setup_mntns().

gc_setup_mntns() does:
1. Call mntns_maybe_create_roots(). It creates root yard if it is needed.
This allows to create fs hierarchies of non root ps tree (nested) mnt
namespaces.
2. read_mnt_ns_img() - to read information about all the mountpoints in all
the ps tree mnt namespaces from dump files.
3. if (root_ns_mask & CLONE_NEWNS) { unshare(CLONE_NEWNS); } because the
next call to prepare_mnt_ns() expects that root mnt ns  is created and
current process is in it.
4. Call prepare_mnt_ns()  to create all the non root ps tree mnt namespaces
and setup all fs hierarchies in all the mnt namespaces.

After that all the ps tree mnt namespaces are created and we can delete
link remaps inside them.


> >
> >
> >     > 4. prepare_remaps() call is needed to associate link remaps and reg
> >     >    files structs we've read from dump. It also works with ps tree
> fs
> >     >    so mnt namespaces should be created before this call.
> >     >
> >     > 5. gc_link_remaps() - delete all the link remaps in their mnt
> namespaces.
> >     >
> >     > Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com <mailto:
> eabatalov89 at gmail.com>>
> >     > ---
> >     >  criu/cr-gc.c             | 104 ++++++++++++++++++++++++++++++
> ++++++++++++++++-
> >     >  criu/files-reg.c         |  37 +++++++++++++++++
> >     >  criu/include/files-reg.h |   1 +
> >     >  3 files changed, 141 insertions(+), 1 deletion(-)
> >     >
> >     > diff --git a/criu/cr-gc.c b/criu/cr-gc.c
> >     > index bdd3723..e248e66 100644
> >     > --- a/criu/cr-gc.c
> >     > +++ b/criu/cr-gc.c
> >     > @@ -1,6 +1,108 @@
> >     > +#include <sched.h>
> >     > +#include <unistd.h>
> >     > +
> >     > +#include "criu-log.h"
> >     >  #include "crtools.h"
> >     > +#include "pstree.h"
> >     > +#include "files.h"
> >     > +#include "files-reg.h"
> >     > +#include "mount.h"
> >     > +#include "namespaces.h"
> >     > +#include "util.h"
> >     >
> >     > -int cr_gc(void)
> >     > +static int root_mntns = -1;
> >     > +
> >     > +static int gc_setup_mntns(void)
> >     > +{
> >     > +     if (mntns_maybe_create_roots() < 0)
> >     > +             return -1;
> >     > +
> >     > +     if (read_mnt_ns_img() < 0)
> >     > +             return -1;
> >     > +
> >     > +     if (root_ns_mask & CLONE_NEWNS) {
> >     > +             /* prepare_mnt_ns() expects that root mnt ns is
> already created */
> >     > +             if (unshare(CLONE_NEWNS)) {
> >     > +                     pr_perror("Couldn't create root mount
> namespace\n");
> >     > +                     return -1;
> >     > +             }
> >     > +
> >     > +             root_mntns = open_proc(PROC_SELF, "ns/mnt");
> >     > +             if (root_mntns < 0)
> >     > +                     return -1;
> >     > +     }
> >     > +
> >     > +     if (prepare_mnt_ns() < 0)
> >     > +             return -1;
> >     > +
> >     > +     return 0;
> >     > +}
> >     > +
> >     > +static int gc_cleanup_mntns(void)
> >     > +{
> >     > +     int ret = depopulate_roots_yard(root_mntns, false);
> >     > +
> >     > +     if ((root_mntns != -1) && close(root_mntns)) {
> >     > +             pr_perror("Couldn't close root mntns fd");
> >     > +             ret = -1;
> >     > +     }
> >     > +
> >     > +     return ret;
> >     > +}
> >     > +
> >     > +static int gc_do(void)
> >     >  {
> >     > +     if (gc_link_remaps() < 0)
> >     > +             return -1;
> >     > +
> >     >       return 0;
> >     >  }
> >     > +
> >     > +int cr_gc(void)
> >     > +{
> >     > +     int ret = 0;
> >     > +
> >     > +     if (check_img_inventory() < 0) {
> >     > +             ret = -1;
> >     > +             goto exit;
> >     > +     }
> >     > +
> >     > +     if (prepare_task_entries() < 0) {
> >     > +             ret = -1;
> >     > +             goto exit;
> >     > +     }
> >     > +
> >     > +     if (prepare_pstree() < 0) {
> >     > +             ret = -1;
> >     > +             goto exit;
> >     > +     }
> >     > +
> >     > +     if (prepare_shared_fdinfo() < 0) {
> >     > +             ret = -1;
> >     > +             goto exit;
> >     > +     }
> >     > +
> >     > +     if (collect_remaps_and_regfiles()) {
> >     > +             ret = -1;
> >     > +             goto exit;
> >     > +     }
> >     > +
> >     > +     if (gc_setup_mntns()) {
> >     > +             ret = -1;
> >     > +             goto exit;
> >     > +     }
> >     > +
> >     > +     if (prepare_remaps() < 0) {
> >     > +             ret = -1;
> >     > +             goto exit;
> >     > +     }
> >     > +
> >     > +     if (gc_do())
> >     > +             ret = -1;
> >     > +
> >     > +exit:
> >     > +     if (gc_cleanup_mntns())
> >     > +             ret = -1;
> >     > +
> >     > +     return ret;
> >     > +}
> >     > diff --git a/criu/files-reg.c b/criu/files-reg.c
> >     > index 45100f9..07e9772 100644
> >     > --- a/criu/files-reg.c
> >     > +++ b/criu/files-reg.c
> >     > @@ -712,6 +712,43 @@ static void __rollback_link_remaps(bool
> do_unlink)
> >     >  void delete_link_remaps(void) { __rollback_link_remaps(true); }
> >     >  void free_link_remaps(void) { __rollback_link_remaps(false); }
> >     >
> >     > +int gc_link_remaps(void)
> >     > +{
> >     > +     struct remap_info *ri;
> >     > +     struct file_remap *remap;
> >     > +
> >     > +     list_for_each_entry(ri, &remaps, list) {
> >     > +             if (ri->rfe->remap_type != REMAP_TYPE__LINKED)
> >     > +                     continue;
> >     > +
> >     > +             remap = ri->rfi->remap;
> >     > +             struct ns_id *remap_mntns =
> lookup_nsid_by_mnt_id(remap->rmnt_id);
> >     > +
> >     > +             if (!remap_mntns) {
> >     > +                     pr_err("Can't get remap %s mnt ns %d\n",
> >     > +                                     remap->rpath,
> remap->rmnt_id);
> >     > +                     return -1;
> >     > +             }
> >     > +
> >     > +             if (remap_mntns->nd->cflag != CLONE_NEWNS) {
> >     > +                     pr_err("Wrong clone flag of remap mntns %x
> (id:%d)",
> >     > +                                     remap_mntns->nd->cflag,
> remap->rmnt_id);
> >     > +                     return -1;
> >     > +             }
> >     > +
> >     > +             /*
> >     > +              * We are root ps tree item in restore cmd terms.
> >     > +              * All the mnt namespaces and their fds are created
> >     > +              * by root ps tree item on restore.
> >     > +              * So we can simply use mnt ns fds here.
> >     > +              */
> >     > +             if (clean_one_remap(remap, remap_mntns->mnt.root_fd))
> >     > +                     return -1;
> >     > +     }
> >     > +
> >     > +     return 0;
> >     > +}
> >     > +
> >     >  static int create_link_remap(char *path, int len, int lfd,
> >     >                               u32 *idp, struct ns_id *nsid)
> >     >  {
> >     > diff --git a/criu/include/files-reg.h b/criu/include/files-reg.h
> >     > index 6cc2454..ff54303 100644
> >     > --- a/criu/include/files-reg.h
> >     > +++ b/criu/include/files-reg.h
> >     > @@ -52,6 +52,7 @@ extern void delete_link_remaps(void);
> >     >  extern void free_link_remaps(void);
> >     >  extern int prepare_remaps(void);
> >     >  extern void try_clean_remaps(void);
> >     > +extern int gc_link_remaps(void);
> >     >
> >     >  extern int strip_deleted(struct fd_link *link);
> >     >
> >     >
> >
> >
> >
> >
> > --
> > Best regards,
> > Eugene Batalov.
>
>


-- 
Best regards,
Eugene Batalov.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvz.org/pipermail/criu/attachments/20161025/efcaaa90/attachment-0001.html>


More information about the CRIU mailing list