[CRIU] [PATCH 2/3] fsnotify: dump tmpfs notify watchers by names

Andrey Vagin avagin at openvz.org
Mon Feb 24 06:11:29 PST 2014


Currently file handles are used for dumping {i,fs}notify watchers.

But inode numbers are not restored for tmpfs content, so watchers can't
be opened by handles.

Pavel found, that tmpfs cache is not pruned, so a handle can be opened,
and readlink(/proc/PID/fd/X) will return a corect path to the file.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 fsnotify.c | 43 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/fsnotify.c b/fsnotify.c
index 3f5ef62..c91f184 100644
--- a/fsnotify.c
+++ b/fsnotify.c
@@ -13,6 +13,7 @@
 #include <sys/types.h>
 #include <sys/inotify.h>
 #include <sys/vfs.h>
+#include <linux/magic.h>
 #include <sys/wait.h>
 #include <sys/poll.h>
 #include <sys/mman.h>
@@ -40,6 +41,7 @@
 
 #include "protobuf.h"
 #include "protobuf/fsnotify.pb-c.h"
+#include "protobuf/mnt.pb-c.h"
 
 #undef	LOG_PREFIX
 #define LOG_PREFIX "fsnotify: "
@@ -127,13 +129,46 @@ out:
 int check_open_handle(unsigned int s_dev, unsigned long i_ino,
 		FhEntry *f_handle)
 {
-	int fd;
+	int fd = -1;
 	char *path;
 
 	fd = open_handle(s_dev, i_ino, f_handle);
 	if (fd >= 0) {
-		close(fd);
+		struct mount_info *mi;
+
 		pr_debug("\tHandle %x:%lx is openable\n", s_dev, i_ino);
+
+		mi = lookup_mnt_sdev(s_dev);
+		if (mi == NULL) {
+			pr_err("Unable to lookup a mount by dev %x\n", s_dev);
+			goto err;
+		}
+
+		/*
+		 * Inode numbers are not restored for tmpfs content, but we can
+		 * get file names, becasue tmpfs cache is not pruned.
+		 */
+		if (mi->fstype->code == FSTYPE__TMPFS) {
+			char p[PATH_MAX];
+			int s;
+
+			snprintf(p, sizeof(p), "/proc/self/fd/%d", fd);
+			s = readlink(p, p, sizeof(p) - 1);
+			if (s < 0) {
+				pr_perror("Unable to readlink(%s)", p);
+				goto err;
+			}
+			p[s] = 0;
+			close_safe(&fd);
+
+			path = xstrdup(p);
+			if (path == NULL)
+				return -1;
+
+			goto out;
+		}
+
+		close(fd);
 		return 0;
 	}
 
@@ -144,9 +179,13 @@ int check_open_handle(unsigned int s_dev, unsigned long i_ino,
 		return -1;
 	}
 
+out:
 	pr_debug("\tDumping %s as path for handle\n", path);
 	f_handle->path = path;
 	return 0;
+err:
+	close_safe(&fd);
+	return -1;
 }
 
 static int dump_inotify_entry(union fdinfo_entries *e, void *arg)
-- 
1.8.3.1



More information about the CRIU mailing list