diff --git a/files.c b/files.c index a83cd8326..28faf0b30 100644 --- a/files.c +++ b/files.c @@ -34,6 +34,7 @@ #include "tun.h" #include "fdset.h" #include "fs-magic.h" +#include "proc_parse.h" #include "parasite.h" #include "parasite-syscall.h" @@ -204,6 +205,7 @@ static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd, { int ret; struct statfs fsbuf; + struct fdinfo_common fdinfo; if (fstat(lfd, &p->stat) < 0) { pr_perror("Can't stat fd %d", lfd); @@ -215,16 +217,14 @@ static int fill_fd_params(struct parasite_ctl *ctl, int fd, int lfd, return -1; } + if (parse_fdinfo(lfd, FD_TYPES__UND, NULL, &fdinfo)) + return -1; + p->fs_type = fsbuf.f_type; p->ctl = ctl; p->fd = fd; - p->pos = lseek(lfd, 0, SEEK_CUR); - ret = fcntl(lfd, F_GETFL); - if (ret == -1) { - pr_perror("Unable to get fd %d flags", lfd); - return -1; - } - p->flags = ret; + p->pos = fdinfo.pos; + p->flags = fdinfo.flags; p->pid = ctl->pid.real; p->fd_flags = opts->flags; diff --git a/include/proc_parse.h b/include/proc_parse.h index f6af7d3c8..ac135c369 100644 --- a/include/proc_parse.h +++ b/include/proc_parse.h @@ -153,6 +153,11 @@ union fdinfo_entries { FanotifyMarkEntry ffy; }; +struct fdinfo_common { + off64_t pos; + int flags; +}; + extern int parse_fdinfo(int fd, int type, int (*cb)(union fdinfo_entries *e, void *arg), void *arg); extern int parse_fdinfo_pid(int pid, int fd, int type, diff --git a/proc_parse.c b/proc_parse.c index b8dce14f7..972e3d537 100644 --- a/proc_parse.c +++ b/proc_parse.c @@ -1020,7 +1020,27 @@ static int parse_fdinfo_pid_s(char *pid, int fd, int type, while (fgets(str, sizeof(str), f)) { union fdinfo_entries entry; - if (fdinfo_field(str, "pos") || fdinfo_field(str, "counter")) + if (fdinfo_field(str, "pos") || + fdinfo_field(str, "flags")) { + unsigned long long val; + struct fdinfo_common *fdinfo = arg; + + if (type != FD_TYPES__UND) + continue; + ret = sscanf(str, "%*s %lli", &val); + if (ret != 1) + goto parse_err; + + if (fdinfo_field(str, "pos")) + fdinfo->pos = val; + else if (fdinfo_field(str, "flags")) + fdinfo->flags = val; + + entry_met = true; + continue; + } + + if (type == FD_TYPES__UND) continue; if (fdinfo_field(str, "eventfd-count")) {