[CRIU] [PATCH 1/2] mount: Use path resolving to find mount points

Cyrill Gorcunov gorcunov at openvz.org
Thu Dec 5 12:09:03 PST 2013


Instead of btrfs engine lets use path resolving feature.
Once we find that there is some device which dev_t doesn't
match one obtained from stat call we resolve path to a
mountpoint and if mountpoint is laying on btrfs we use
mount's dev_t for matching (because subvolumes may be
not always reachable from chroot'ed environment).

We use slow lookup here but it will be improved once
all things settle down.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---

Pavel, what do you think, what is the preferred way would be
to speedup the things? Note this patch actually makes btrfs engine
obsolete ;)

 files-reg.c     |  2 +-
 include/mount.h |  2 +-
 mount.c         | 49 ++++++++++++++++++++++++++++++++++++++++++-------
 sk-unix.c       |  2 +-
 4 files changed, 45 insertions(+), 10 deletions(-)

diff --git a/files-reg.c b/files-reg.c
index 728979d266d7..715000d06d49 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -270,7 +270,7 @@ struct file_remap *lookup_ghost_remap(u32 dev, u32 ino)
 
 	mutex_lock(ghost_file_mutex);
 	list_for_each_entry(gf, &ghost_files, list) {
-		if (phys_stat_dev_match(gf->dev, dev) && gf->ino == ino) {
+		if (gf->ino == ino && phys_stat_dev_match(gf->dev, dev, gf->remap.path)) {
 			gf->remap.users++;
 			mutex_unlock(ghost_file_mutex);
 			return &gf->remap;
diff --git a/include/mount.h b/include/mount.h
index 3e4508715c79..b64673c3801d 100644
--- a/include/mount.h
+++ b/include/mount.h
@@ -22,6 +22,6 @@ extern struct mount_info *lookup_mnt_sdev(unsigned int s_dev);
 
 extern struct ns_desc mnt_ns_desc;
 
-extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev);
+extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, const char *path);
 
 #endif /* __CR_MOUNT_H__ */
diff --git a/mount.c b/mount.c
index 3c85cb036619..23d62da527e3 100644
--- a/mount.c
+++ b/mount.c
@@ -98,17 +98,52 @@ struct mount_info *lookup_mnt_sdev(unsigned int s_dev)
 	return NULL;
 }
 
-bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev)
+static struct mount_info *mount_resolve_path(const char *path)
 {
-	if (st_dev == phys_dev)
-		return true;
+	struct mount_info *m, *best = NULL, *root = NULL;
+	size_t pathlen = strlen(path);
+	size_t bestlen = PATH_MAX;
 
 	/*
-	 * BTRFS returns subvolume dev-id instead of
-	 * superblock dev-id so we might need additional
-	 * tests here.
+	 * Find suitable mount point for a @path.
+	 *
+	 * FIXME We need some fast path resolving algorithm here.
+	 * For a while stick with stupid matches.
 	 */
-	return is_btrfs_subvol(phys_dev, st_dev);
+	for (m = mntinfo; m; m = m->next) {
+		size_t n = strlen(m->mountpoint);
+
+		if (!strncmp(m->mountpoint, path, min(n, pathlen))) {
+			if (bestlen > n && !is_root_mount(m)) {
+				best = m;
+				bestlen = n;
+			}
+			if (is_root_mount(m))
+				root = m;
+		}
+	}
+
+	if (!best) {
+		BUG_ON(!root);
+		best = root;
+	}
+
+	pr_debug("Path `%s' resolved to `%s' mountpoint\n", path, best->mountpoint);
+	return best;
+}
+
+bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, const char *path)
+{
+	struct mount_info *m;
+
+	if (st_dev == phys_dev)
+		return true;
+
+	m = mount_resolve_path(path);
+
+	if (!strcmp(m->fstype->name, "btrfs"))
+		return m->s_dev == phys_dev;
+	return false;
 }
 
 /*
diff --git a/sk-unix.c b/sk-unix.c
index df07999d9aa9..21d2de746454 100644
--- a/sk-unix.c
+++ b/sk-unix.c
@@ -355,7 +355,7 @@ static int unix_collect_one(const struct unix_diag_msg *m,
 			}
 
 			if ((st.st_ino != uv->udiag_vfs_ino) ||
-			    !phys_stat_dev_match(st.st_dev, kdev_to_odev(uv->udiag_vfs_dev))) {
+			    !phys_stat_dev_match(st.st_dev, kdev_to_odev(uv->udiag_vfs_dev), name)) {
 				pr_info("unix: Dropping path %s for "
 						"unlinked bound "
 						"sk %#x.%#x real %#x.%#x\n",
-- 
1.8.3.1



More information about the CRIU mailing list