Message ID | 20181207122948.26683-4-gorcunov@gmail.com |
---|---|
State | New |
Series | "fown: Handle dead pids and O_PATH" |
Headers | show |
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);
On Fri, Dec 07, 2018 at 03:29:46PM +0300, Cyrill Gorcunov wrote: > 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@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) > if (flags < 0) { pr_err("fcntl(%d, F_GETFD) -> %d\n", fd, flags); return -1; } > 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; > + } We already have the same code > + 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 >
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@gmail.com> --- criu/files-reg.c | 16 +++++++++++----- criu/files.c | 5 ++++- criu/pie/parasite.c | 13 +++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-)