]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: add inspect_target_fd method to file_class
authorMasatake YAMATO <yamato@redhat.com>
Mon, 1 Dec 2025 21:19:27 +0000 (06:19 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Tue, 3 Feb 2026 20:23:17 +0000 (05:23 +0900)
lsfd has mainly used the following information sources:
* stat(2) of readlink(/proc/$pid/fd/$fd),
* values in /proc/$pid/fdinfo/$fd, and
* netlink diag.

The new method adds a new information source, file descriptors
imported from the target process. lsfd uses pidfd_getfd(2) to import
the specified fd from the target process.

In the inspect_target_fd method, the imported file descriptor can be
used freely. For example, you can call ioctl(2) on it to obtain extra
information.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
lsfd-cmd/lsfd.c
lsfd-cmd/lsfd.h
lsfd-cmd/util.c

index c5735705758eebc65d37634361ae7b2e6ecb60fd..334efd3284db279a3c9302a10a99bd57df5e9f23 100644 (file)
@@ -882,6 +882,21 @@ static void read_fdinfo(struct file *file, FILE *fdinfo)
        }
 }
 
+static int call_inspect_target_fd_method(int fd, void *data)
+{
+       struct file *f = data;
+
+       f->class->inspect_target_fd(f, fd);
+       return 0;
+}
+
+static void inspect_target_fd(struct file *f, struct proc *proc)
+{
+       if (proc->pidfd >= 0)
+               call_with_foreign_fd_via_pidfd(proc->pidfd, f->association,
+                                              call_inspect_target_fd_method, f);
+}
+
 static struct file *collect_file_symlink(struct path_cxt *pc,
                                         struct proc *proc,
                                         const char *name,
@@ -941,6 +956,12 @@ static struct file *collect_file_symlink(struct path_cxt *pc,
                        read_fdinfo(f, fdinfo);
                        fclose(fdinfo);
                }
+
+               if (f->class->needs_target_fd &&
+                   f->class->needs_target_fd(f)) {
+                       assert(f->class->inspect_target_fd);
+                       inspect_target_fd(f, proc);
+               }
        }
 
        return f;
index 553546d8b5fd8160eae584a28fa21e870da04bde..665cdad612a74e2c3074fab8d6b7564ca3c81769 100644 (file)
@@ -242,6 +242,12 @@ struct file_class {
                            int column_id,
                            size_t column_index);
        int  (*handle_fdinfo)(struct file *file, const char *key, const char* value);
+
+       /* The lsfd core calls inspect_target_fd only if needs_target_fd()
+        * returns TRUE. */
+       bool (*needs_target_fd)(struct file *file);
+       void (*inspect_target_fd)(struct file *file, int fd);
+
        void (*attach_xinfo)(struct file *file);
        void (*initialize_content)(struct file *file);
        void (*free_content)(struct file *file);
@@ -343,5 +349,7 @@ bool is_pidfs_dev(dev_t dev);
  */
 int call_with_foreign_fd(pid_t target_pid, int target_fd,
                         int (*fn)(int, void*), void *data);
+int call_with_foreign_fd_via_pidfd(int pidfd, int target_fd,
+                                  int (*fn)(int, void*), void *data);
 
 #endif /* UTIL_LINUX_LSFD_H */
index f3e3a727c6cb3187b6aa2110c9fc2b175566e870..78f94c20f9c274bb4e9dc5767d12baddcf5b8736 100644 (file)
@@ -21,8 +21,8 @@
 #include "lsfd.h"              /* prototype decl for call_with_foreign_fd */
 #include "pidfd-utils.h"
 
-static int call_with_foreign_fd_via_pidfd(int pidfd, int target_fd,
-                                         int (*fn)(int, void*), void *data)
+int call_with_foreign_fd_via_pidfd(int pidfd, int target_fd,
+                                  int (*fn)(int, void*), void *data)
 {
        int tfd, r;