[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