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

Pavel Emelyanov xemul at virtuozzo.com
Tue Oct 25 05:50:37 PDT 2016


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() :)

> 
> 
>     > 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?

> 
> 
>     > 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.



More information about the CRIU mailing list