[CRIU] [PATCH] mnt: Map opts.root to match root mountpoints in stat resolving

Cyrill Gorcunov gorcunov at openvz.org
Fri Nov 27 09:25:54 PST 2015


When opening mountpoint with __open_mountpoint() helper we try
to detect potential overmounts comparing devices obtained
from stat() call with one got from image or mountinfo parsing.

This works well for static cases while underlied device doesn't
change its device ID. But device can easily change in case
of container's migration causing restore to fail (in particular
we noticed this problem trying to restore an inotify object which
bound to device:inode pair when opening it via file handle).

Thus for a simple case when only toplevel root is migrating
or changing lets try to handle it gracefully -- if opts.root
passed we remember the new root device ID and then in
__open_mountpoint() test if the changed device can still
be used.

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

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 mount.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/mount.c b/mount.c
index 25fbc134ebe1..7e5667333537 100644
--- a/mount.c
+++ b/mount.c
@@ -64,6 +64,9 @@ static struct ext_mount *ext_mount_lookup(char *key)
  */
 struct mount_info *mntinfo;
 
+/* New root device from command line */
+static unsigned int opts_root_dev;
+
 static void mntinfo_add_list(struct mount_info *new)
 {
 	if (!mntinfo)
@@ -1010,9 +1013,13 @@ int __open_mountpoint(struct mount_info *pm, int mnt_fd)
 
 	dev = phys_stat_resolve_dev(pm->nsid, st.st_dev, pm->ns_mountpoint + 1);
 	if (dev != pm->s_dev) {
-		pr_err("The file system %#x (%#x) %s %s is inaccessible\n",
-		       pm->s_dev, (int)dev, pm->fstype->name, pm->ns_mountpoint);
-		goto err;
+		if (is_root_mount(pm) && dev == opts_root_dev)
+			/* A migrated root */ ;
+		else {
+			pr_err("The file system %#x (%#x) %s %s is inaccessible\n",
+			       pm->s_dev, (int)dev, pm->fstype->name, pm->ns_mountpoint);
+			goto err;
+		}
 	}
 
 	return mnt_fd;
@@ -2750,6 +2757,14 @@ int prepare_mnt_ns(void)
 			pr_perror("chdir(%s) failed", opts.root ? : "/");
 			return -1;
 		}
+
+		/*
+		 * New root mount from option, need to save it
+		 * to be able to open mounts which @s_dev from
+		 * image doesn't match run-time one.
+		 */
+		opts_root_dev = mi->s_dev;
+		pr_debug("mnt: opts_root_dev %#x\n", opts_root_dev);
 	}
 
 	free_mntinfo(old);
-- 
2.5.0



More information about the CRIU mailing list