[CRIU] [PATCH] fsnotify: Use longest mount point for inotify watchee

Cyrill Gorcunov gorcunov at openvz.org
Sat Oct 10 01:07:08 PDT 2015


In debian-8 container we faced the problem -- systemd
creates nested mount namespaces and inotify watchee
are resolved into a path which is inaccessbile on
restore (because we're operating in task's mount
namespace). So here is a dirty hack for now -- choose
the widest mount point as a reference. The proper
fix requires kernel patching.

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

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

Guys, I'm looking forward to patch the kernel because
lack of @mnt_id in kernel output still beat us: we can't
be sure the longest mount point will always be enough
and need a precise knowing where watchee has been opened
at. But the patch unblocks our tests so I would love
having it merged for this sake.

 fsnotify.c      | 10 +++++++++-
 include/mount.h |  1 +
 mount.c         | 19 +++++++++++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fsnotify.c b/fsnotify.c
index 76d73980d854..381626b43cb2 100644
--- a/fsnotify.c
+++ b/fsnotify.c
@@ -118,7 +118,15 @@ static int open_handle(unsigned int s_dev, unsigned long i_ino,
 	pr_debug("Opening fhandle %x:%Lx...\n",
 			s_dev, (unsigned long long)handle.__handle[0]);
 
-	mntfd = open_mount(s_dev);
+	/*
+	 * FIXME: That's a dirty hack: we lookup for a mount
+	 * with longest path which get opened on the
+	 * restore. Such trick works for containers
+	 * we're working on now but proper fix seems
+	 * to be adding @mnt_id into the procfs output
+	 * via kernel patching.
+	 */
+	mntfd = open_mount_widest(s_dev);
 	if (mntfd < 0) {
 		pr_err("Mount root for 0x%08x not found\n", s_dev);
 		goto out;
diff --git a/include/mount.h b/include/mount.h
index b56aafd4d569..38f6388136ae 100644
--- a/include/mount.h
+++ b/include/mount.h
@@ -94,6 +94,7 @@ extern int mntns_get_root_fd(struct ns_id *ns);
 extern int mntns_get_root_by_mnt_id(int mnt_id);
 extern struct ns_id *lookup_nsid_by_mnt_id(int mnt_id);
 
+extern int open_mount_widest(unsigned int s_dev);
 extern int open_mount(unsigned int s_dev);
 extern struct fstype *find_fstype_by_name(char *fst);
 extern bool add_fsname_auto(const char *names);
diff --git a/mount.c b/mount.c
index 8936eda59db5..8e1a90f2a567 100644
--- a/mount.c
+++ b/mount.c
@@ -1043,6 +1043,25 @@ err:
 	return -1;
 }
 
+int open_mount_widest(unsigned int s_dev)
+{
+	struct mount_info *m, *t = NULL;
+	int rlen = -1;
+
+	for (m = mntinfo; m; m = m->next) {
+		int len = strlen(m->root);
+		if (m->s_dev != s_dev)
+			continue;
+		if (rlen > 0 && rlen < len)
+			continue;
+		t = m, rlen = len;
+	}
+
+	if (!t)
+		return -ENOENT;
+	return __open_mountpoint(t, -1);
+}
+
 int open_mount(unsigned int s_dev)
 {
 	struct mount_info *m;
-- 
2.4.3



More information about the CRIU mailing list