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

Eugene Batalov eabatalov89 at gmail.com
Sun Sep 11 10:14:43 PDT 2016


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.

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.

3. gc_setup_mntns() (if needed) creates all the ps tree mnt namespaces
   and performs mounting of proper fs hierachies into 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>
---
 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);
 
-- 
1.9.1



More information about the CRIU mailing list