[CRIU] [PATCH 3/5] fown: Don't fail on dumping files opened with O_PATH

Cyrill Gorcunov gorcunov at gmail.com
Fri Dec 7 15:29:46 MSK 2018


O_PATH opened files are special: they have empty
file operations in kernel space, so there not that
much we can do with them, even setting position is
not allowed. Same applies to a signal number for
owner settings.

Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
 criu/files-reg.c    | 16 +++++++++++-----
 criu/files.c        |  5 ++++-
 criu/pie/parasite.c | 13 +++++++++++++
 3 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/criu/files-reg.c b/criu/files-reg.c
index c4f4e1616a85..a2042a512538 100644
--- a/criu/files-reg.c
+++ b/criu/files-reg.c
@@ -1777,11 +1777,17 @@ static int do_open_reg(int ns_root_fd, struct reg_file_info *rfi, void *arg)
 	if (fd < 0)
 		return fd;
 
-	if ((rfi->rfe->pos != -1ULL) &&
-			lseek(fd, rfi->rfe->pos, SEEK_SET) < 0) {
-		pr_perror("Can't restore file pos");
-		close(fd);
-		return -1;
+	/*
+	 * O_PATH opened files carry empty fops in kernel,
+	 * just ignore positioning at all.
+	 */
+	if (!(rfi->rfe->flags & O_PATH)) {
+		if ((rfi->rfe->pos != -1ULL) &&
+		    lseek(fd, rfi->rfe->pos, SEEK_SET) < 0) {
+			pr_perror("Can't restore file pos");
+			close(fd);
+			return -1;
+		}
 	}
 
 	return fd;
diff --git a/criu/files.c b/criu/files.c
index b12258ad2654..d96358b558b4 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -392,7 +392,10 @@ static int fill_fd_params(struct pid *owner_pid, int fd, int lfd,
 	pr_info("%d fdinfo %d: pos: %#16"PRIx64" flags: %16o/%#x\n",
 			owner_pid->real, fd, p->pos, p->flags, (int)p->fd_flags);
 
-	ret = fcntl(lfd, F_GETSIG, 0);
+	if (p->flags & O_PATH)
+		ret = 0;
+	else
+		ret = fcntl(lfd, F_GETSIG, 0);
 	if (ret < 0) {
 		pr_perror("Can't get owner signum on %d", lfd);
 		return -1;
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index c32e31384fd8..f9e954484615 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -325,6 +325,19 @@ static int fill_fds_opts(struct parasite_drain_fd *fds, struct fd_opts *opts)
 
 		p->flags = (char)flags;
 
+		/*
+		 * For O_PATH opened files there is no owner at all.
+		 */
+		if (flags < 0) {
+			pr_err("fcntl(%d, F_GETFL) -> %d\n", fd, flags);
+			return -1;
+		}
+		flags = sys_fcntl(fd, F_GETFL, 0);
+		if (flags & O_PATH) {
+			p->fown.pid = 0;
+			continue;
+		}
+
 		ret = sys_fcntl(fd, F_GETOWN_EX, (long)&owner_ex);
 		if (ret) {
 			pr_err("fcntl(%d, F_GETOWN_EX) -> %d\n", fd, ret);
-- 
2.17.2



More information about the CRIU mailing list