[PATCH 6/7] inotify: Use ghost files if the watchee is a deleted file, v2

Cyrill Gorcunov gorcunov at openvz.org
Mon Dec 3 09:18:45 EST 2012


The watch target might be a deleted file. In this case we can't
re-create it on restore procedure.

A typical scenario
------------------

 fd = inotify_init1()
 wd = open(path)
 inotify_add_watch(path)
 unlink(path)
 ... checkpoint ...

here we have a @path which is unlinked but still present in inotify
watch list because inode is not yet freed. And if the program is killed
after checkpoint the last reference to a path get eliminated and inode
get freed from the kernel memory.

Thus any furher attempts to open the path via file handle (note that file
handle can't be used to create new file, the kernel doesn't permit that)
will simply fail.

So if plain opening via file handle failed we assume that at least
the file might be in our ghost files list (we're optimists, right?)
and if we successed we simply use a path generated by ghost file
engine for us.

v2 [by xemul@]:
 - gather reference to ghost file early

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 inotify.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/inotify.c b/inotify.c
index d410ce3..a5f7f0d 100644
--- a/inotify.c
+++ b/inotify.c
@@ -29,6 +29,7 @@
 #include "image.h"
 #include "util.h"
 #include "files.h"
+#include "files-reg.h"
 #include "file-ids.h"
 #include "log.h"
 #include "list.h"
@@ -43,6 +44,7 @@
 struct inotify_wd_info {
 	struct list_head		list;
 	InotifyWdEntry			*iwe;
+	struct ghost_file		*gf;
 };
 
 struct inotify_file_info {
@@ -108,9 +110,10 @@ int dump_inotify(struct fd_parms *p, int lfd, const struct cr_fdset *set)
 	return do_dump_gen_file(p, lfd, &inotify_ops, set);
 }
 
-static int restore_one_inotify(int inotify_fd, InotifyWdEntry *iwe)
+static int restore_one_inotify(int inotify_fd, struct inotify_wd_info *info)
 {
-	char path[32];
+	InotifyWdEntry *iwe = info->iwe;
+	char buf[32], *path = buf;
 	int mntfd = -1, ret = -1;
 	int wd, target = -1;
 	fh_t handle = { };
@@ -131,12 +134,15 @@ static int restore_one_inotify(int inotify_fd, InotifyWdEntry *iwe)
 
 	target = sys_open_by_handle_at(mntfd, (void *)&handle, 0);
 	if (target < 0) {
-		pr_perror("Can't open file handle for 0x%08x:0x%016lx",
-			  iwe->s_dev, iwe->i_ino);
-		goto err;
-	}
+		if (!info->gf) {
+			pr_perror("Can't open file handle for 0x%08x:0x%016lx",
+				  iwe->s_dev, iwe->i_ino);
+			goto err;
+		}
+		path = info->gf->remap.path;
+	} else
+		snprintf(buf, sizeof(buf), "/proc/self/fd/%d", target);
 
-	snprintf(path, sizeof(path), "/proc/self/fd/%d", target);
 	pr_debug("\t\tRestore watch for 0x%08x:0x%016lx\n", iwe->s_dev, iwe->i_ino);
 
 	/*
@@ -162,6 +168,9 @@ static int restore_one_inotify(int inotify_fd, InotifyWdEntry *iwe)
 		inotify_rm_watch(inotify_fd, wd);
 	}
 
+	if (info->gf)
+		ghost_file_put(info->gf);
+
 err:
 	close_safe(&mntfd);
 	close_safe(&target);
@@ -184,7 +193,7 @@ static int open_inotify_fd(struct file_desc *d)
 
 	list_for_each_entry(wd_info, &info->marks, list) {
 		pr_info("\tRestore inotify for 0x%08x\n", wd_info->iwe->id);
-		if (restore_one_inotify(tmp, wd_info->iwe)) {
+		if (restore_one_inotify(tmp, wd_info)) {
 			close_safe(&tmp);
 			break;
 		}
@@ -208,6 +217,7 @@ static int collect_mark(struct inotify_wd_info *mark)
 	list_for_each_entry(p, &info_head, list) {
 		if (p->ife->id == mark->iwe->id) {
 			list_add(&mark->list, &p->marks);
+			mark->gf = lookup_ghost_file_st(mark->iwe->s_dev, mark->iwe->i_ino);
 			return 0;
 		}
 	}
-- 
1.8.0.1


--bajzpZikUji1w+G9--


More information about the CRIU mailing list