[CRIU] [PATCH 1/2] fsnotify: Do not track deleted watchees

Cyrill Gorcunov gorcunov at openvz.org
Wed Feb 26 01:36:40 PST 2014


If the watchee is deleted we might be able to open in by file
handle at checkpoint time but fail on restore.

Deleted watchees are special -- if the dumpee has a mark
on such path assigned and watching for delete event, the
delete event might be in events queue but it'll be the
last one since no more events longer come from this source.

Still we don't support queued events c/r events yet thus
for us such watchee would be stale one which we would not
be able to open. Thus simply ignore such watchee and
don't restore it. Either the application read the queued
events by self either the queued events all are lost.

Note one should distinguish between watchees we've file
descriptor on in a dumpee process or "external" pathes. If
the dumpee has a file descriptor to deleted watchee, we're
able to restore such watchees via ghost-file engine.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 fsnotify.c | 39 +++++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/fsnotify.c b/fsnotify.c
index 641abcf216c5..a81c2420bd34 100644
--- a/fsnotify.c
+++ b/fsnotify.c
@@ -134,9 +134,32 @@ int check_open_handle(unsigned int s_dev, unsigned long i_ino,
 
 	fd = open_handle(s_dev, i_ino, f_handle);
 	if (fd >= 0) {
+		struct stat st;
+
+		/*
+		 * WARNING
+		 *
+		 * The file might be accessible via dentry
+		 * cache but still deleted, which means we
+		 * might be fail on restore procedure. Thus
+		 * check for number of links. If the file
+		 * is deleted then we should simply ignore
+		 * it.
+		 *
+		 * FIXME Once the kernel will be updated
+		 * and c/r for fsnotify queue is implemented
+		 * need to fix this place as well.
+		 */
+		if (fstat(fd, &st) < 0) {
+			pr_perror("Can't stat fd %d", fd);
+			close(fd);
+			return -1;
+		}
 		close(fd);
-		pr_debug("\tHandle %x:%lx is openable\n", s_dev, i_ino);
-		return 0;
+		pr_debug("\tHandle %x:%lx is openable (st_nlink %lu -> %s)\n",
+			 s_dev, i_ino, st.st_nlink,
+			 st.st_nlink > 0 ? "present" : "ignored");
+		return st.st_nlink > 0 ? 0 : 1;
 	}
 
 	pr_warn("\tHandle %x:%lx cannot be opened\n", s_dev, i_ino);
@@ -154,6 +177,7 @@ int check_open_handle(unsigned int s_dev, unsigned long i_ino,
 static int dump_inotify_entry(union fdinfo_entries *e, void *arg)
 {
 	InotifyWdEntry *we = &e->ify;
+	int ret;
 
 	we->id = *(u32 *)arg;
 	pr_info("wd: wd 0x%08x s_dev 0x%08x i_ino 0x%16"PRIx64" mask 0x%08x\n",
@@ -162,8 +186,11 @@ static int dump_inotify_entry(union fdinfo_entries *e, void *arg)
 			we->f_handle->bytes, we->f_handle->type,
 			we->f_handle->handle[0], we->f_handle->handle[1]);
 
-	if (check_open_handle(we->s_dev, we->i_ino, we->f_handle))
+	ret = check_open_handle(we->s_dev, we->i_ino, we->f_handle);
+	if (ret < 0)
 		return -1;
+	else if (ret == 1)
+		return 0;
 
 	return pb_write_one(fdset_fd(glob_fdset, CR_FD_INOTIFY_WD), we, PB_INOTIFY_WD);
 }
@@ -208,6 +235,7 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
 	fme->id = fsn_params->id;
 
 	if (fme->type == MARK_TYPE__INODE) {
+		int ret;
 
 		BUG_ON(!fme->ie);
 
@@ -218,8 +246,11 @@ static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
 			fme->ie->f_handle->bytes, fme->ie->f_handle->type,
 			fme->ie->f_handle->handle[0], fme->ie->f_handle->handle[1]);
 
-		if (check_open_handle(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle))
+		ret = check_open_handle(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle);
+		if (ret < 0)
 			return -1;
+		else if (ret == 1)
+			return 0;
 	}
 
 	if (fme->type == MARK_TYPE__MOUNT) {
-- 
1.8.3.1



More information about the CRIU mailing list