[CRIU] [PATCH] fsnotify: open_handle -- Handle multiple mounts with same s_dev

Cyrill Gorcunov gorcunov at openvz.org
Fri Aug 4 17:20:19 MSK 2017


From: Cyrill Gorcunov <gorcunov at virtuozzo.com>

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 <gorcunov at virtuozzo.com>
---
 criu/fsnotify.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/criu/fsnotify.c b/criu/fsnotify.c
index 54f70e698c57..c26e5c6ec387 100644
--- a/criu/fsnotify.c
+++ b/criu/fsnotify.c
@@ -196,6 +196,7 @@ static char *alloc_openable(unsigned int s_dev, unsigned long i_ino, FhEntry *f_
 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;
 }
-- 
2.7.5



More information about the CRIU mailing list