[CRIU] [PATCH] mount: Find NS_ROOT for cr-time mount on restore

Kirill Tkhai ktkhai at virtuozzo.com
Fri May 19 05:13:09 PDT 2017


After commit 2e8970beda5b "mount: create a mount point
for the root mount namespace in the roots yard", top
of the tree of mount_infos points to the fake mount.
So, when we're looking for appropriate place for
binfmt_misc, we can't find "xxx/proc/sys/fs/binfmt_misc".
Fix that by finding real NS_ROOT manually.

https://jira.sw.ru/browse/PSBM-66457

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/mount.c |   34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/criu/mount.c b/criu/mount.c
index 634491310..cef7e7437 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -42,7 +42,7 @@
 #undef	LOG_PREFIX
 #define LOG_PREFIX "mnt: "
 
-#define BINFMT_MISC_HOME "/proc/sys/fs/binfmt_misc"
+#define BINFMT_MISC_HOME "proc/sys/fs/binfmt_misc"
 #define CRTIME_MNT_ID 0
 
 /* A helper mount_info entry for the roots yard */
@@ -1194,15 +1194,41 @@ int open_mountpoint(struct mount_info *pm)
 static __maybe_unused int add_cr_time_mount(struct mount_info *root, char *fsname, const char *path, unsigned int s_dev)
 {
 	struct mount_info *mi, *t, *parent;
+	bool add_slash = false;
+	int len;
+
+	if (!root->nsid) {
+		/* On restore we have fake top mount_info. Find real NS_ROOT */
+		list_for_each_entry(t, &root->children, siblings)
+			if (t->nsid->type == NS_ROOT) {
+				root = t;
+				break;
+			}
+		if (!root->nsid) {
+			pr_err("Can't find NS_ROOT\n");
+			return -1;
+		}
+	}
 
 	mi = mnt_entry_alloc();
 	if (!mi)
 		return -1;
-	mi->mountpoint = xmalloc(strlen(path) + 2);
+
+	len = strlen(root->mountpoint);
+	/* It may be "./" or "./path/to/dir" */
+	if (root->mountpoint[len - 1] != '/') {
+		add_slash = true;
+		len++;
+	}
+
+	mi->mountpoint = xmalloc(len + strlen(path) + 1);
 	if (!mi->mountpoint)
 		return -1;
 	mi->ns_mountpoint = mi->mountpoint;
-	sprintf(mi->mountpoint, ".%s", path);
+	if (!add_slash)
+		sprintf(mi->mountpoint, "%s%s", root->mountpoint, path);
+	else
+		sprintf(mi->mountpoint, "%s/%s", root->mountpoint, path);
 	mi->mnt_id = CRTIME_MNT_ID;
 	mi->flags = mi->sb_flags = 0;
 	mi->root = xstrdup("/");
@@ -3243,7 +3269,7 @@ int collect_mnt_namespaces(bool for_dump)
 		}
 
 		if (ns) {
-			ret = mount_cr_time_mount(ns, &s_dev, "binfmt_misc", BINFMT_MISC_HOME,
+			ret = mount_cr_time_mount(ns, &s_dev, "binfmt_misc", "/" BINFMT_MISC_HOME,
 						  "binfmt_misc");
 			if (ret == -EPERM)
 				pr_info("Can't mount binfmt_misc: EPERM. Running in user_ns?\n");



More information about the CRIU mailing list