From e6537f3d8d41974e040bb2a7d28d91ecfc03ec01 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Fri, 4 Aug 2017 17:20:00 +0300 Subject: [PATCH] fsnotify: open_handle -- Handle multiple mounts with same s_dev When inotify is laying on uovermounted fs we should walk over all mountpoints with same s_dev to find openable path. Note on restore the path is usually already allocated during dump stage so get_mark_path won't call for open_handle(), in turn on dump stage the positive return from open_handle() will cause fsnotify engine to find openable path, thus there is kind of double work to be optimized in future. For example we got a container where systemd-udevd inside opens inotify for /dev/X entry then overmount ./dev path with slave option and in result irmap engine on predump can't figure out where the inotify is sitting causing migrtion to abort. Signed-off-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov --- criu/fsnotify.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/criu/fsnotify.c b/criu/fsnotify.c index 6098b5b4c..955cd106b 100644 --- a/criu/fsnotify.c +++ b/criu/fsnotify.c @@ -196,6 +196,7 @@ err: static int open_handle(unsigned int s_dev, unsigned long i_ino, FhEntry *f_handle) { + struct mount_info *m; int mntfd, fd = -1; fh_t handle; @@ -204,19 +205,23 @@ 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); - if (mntfd < 0) { - pr_err("Mount root for %#08x not found\n", s_dev); - goto out; - } + for (m = mntinfo; m; m = m->next) { + if (m->s_dev != s_dev || !mnt_is_dir(m)) + continue; - fd = userns_call(open_by_handle, UNS_FDOUT, &handle, sizeof(handle), mntfd); - if (fd < 0) { - pr_perror("Can't open file handle for %#08x:%#016lx", - s_dev, i_ino); - } + mntfd = __open_mountpoint(m, -1); + if (mntfd < 0) { + pr_err("Can't open mount for s_dev %x, continue\n", s_dev); + continue; + } - close(mntfd); + fd = userns_call(open_by_handle, UNS_FDOUT, &handle, sizeof(handle), mntfd); + if (fd >= 0) { + close(mntfd); + goto out; + } + close(mntfd); + } out: return fd; }