From: Masatake YAMATO Date: Sun, 1 Feb 2026 16:28:17 +0000 (+0900) Subject: lsfd: make pidfd for the target process available while collecting fds X-Git-Tag: v2.43-devel~95^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=11d9efb9fcecda04c8198f81ead6ba8563d8aca4;p=thirdparty%2Futil-linux.git lsfd: make pidfd for the target process available while collecting fds This is a preparation change for adding inspect_target_fd method to file_class. Signed-off-by: Masatake YAMATO --- diff --git a/lsfd-cmd/lsfd.c b/lsfd-cmd/lsfd.c index 39523fa24..c57357057 100644 --- a/lsfd-cmd/lsfd.c +++ b/lsfd-cmd/lsfd.c @@ -843,6 +843,9 @@ static struct proc *new_proc(pid_t pid, struct proc *leader) INIT_LIST_HEAD(&proc->eventpolls); proc->kthread = 0; + + proc->pidfd = -1; + return proc; } @@ -1106,24 +1109,27 @@ static void collect_execve_file(struct path_cxt *pc, struct proc *proc, sockets_only); } -static void collect_pidfs_file(struct proc *proc, bool sockets_only) +static int collect_pidfs_file(struct proc *proc, bool sockets_only) { struct file *f = NULL; int pidfd; if (sockets_only) - return; + return -1; pidfd = pidfd_open(proc->pid, 0); if (pidfd < 0) - return; + return -1; { struct stat sb; const int assoc = ASSOC_PIDFS * -1; - if (fstat(pidfd, &sb) < 0) - goto out; + if (fstat(pidfd, &sb) < 0) { + /* Even fstat fails here, the pidfd is still + * usable in the caller side. */ + return pidfd; + } if ((sb.st_mode & S_IFMT) == S_IFREG) { char *name = NULL; @@ -1151,8 +1157,7 @@ static void collect_pidfs_file(struct proc *proc, bool sockets_only) free(fdinfo); } - out: - close(pidfd); + return pidfd; } static void collect_fs_files(struct path_cxt *pc, struct proc *proc, @@ -2079,6 +2084,7 @@ static void read_process(struct lsfd_control *ctl, struct path_cxt *pc, } if (proc->kthread && !ctl->threads) { free_proc(proc); + proc = NULL; goto out; } @@ -2088,7 +2094,7 @@ static void read_process(struct lsfd_control *ctl, struct path_cxt *pc, || kcmp(proc->leader->pid, proc->pid, KCMP_FS, 0, 0) != 0) collect_fs_files(pc, proc, ctl->sockets_only); - collect_pidfs_file(proc, ctl->sockets_only); + proc->pidfd = collect_pidfs_file(proc, ctl->sockets_only); /* Reading /proc/$pid/mountinfo is expensive. * mnt_namespaces is a table for avoiding reading mountinfo files @@ -2165,6 +2171,11 @@ static void read_process(struct lsfd_control *ctl, struct path_cxt *pc, walk_threads(ctl, pc, pid, proc, parse_proc_syscall); out: + if (proc && proc->pidfd >= 0) { + close(proc->pidfd); + proc->pidfd = -1; + } + /* Let's be careful with number of open files */ ul_path_close_dirfd(pc); } diff --git a/lsfd-cmd/lsfd.h b/lsfd-cmd/lsfd.h index 469e58bce..626027a4a 100644 --- a/lsfd-cmd/lsfd.h +++ b/lsfd-cmd/lsfd.h @@ -189,6 +189,7 @@ struct proc { struct list_head files; unsigned int kthread: 1; struct list_head eventpolls; + int pidfd; }; struct proc *get_proc(pid_t pid);