[CRIU] [PATCH v4 04/12] gc: implement link remaps deletion
Pavel Emelyanov
xemul at virtuozzo.com
Wed Oct 12 01:54:14 PDT 2016
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?
> 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?
> 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?
> 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>
> ---
> 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);
>
>
More information about the CRIU
mailing list