[CRIU] [PATCH 3/5] fown: Don't fail on dumping files opened with O_PATH
Andrey Vagin
avagin at gmail.com
Tue Dec 11 09:19:30 MSK 2018
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 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)
>
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
>
More information about the CRIU
mailing list