aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXi Ruoyao <xry111@xry111.site>2024-04-03 15:46:57 +0800
committerXi Ruoyao <xry111@xry111.site>2024-04-03 17:28:37 +0800
commitb1a48efd173c7f37d8df39a84eb25b4440335661 (patch)
treef48f72bf9eaa19cc1ca437bdb8ce4155b005354c
parentbf6645dc1edef09ad378cc5b9eb2c93861408735 (diff)
downloadutil-linux-b1a48efd173c7f37d8df39a84eb25b4440335661.tar.gz
lsfd: Support pidfs
In Linux 6.9 pidfds are moved from the anonymous inode infrastructure to a tiny pseudo filesystem named pidfs. Recognize it properly. Fixes #2865. Signed-off-by: Xi Ruoyao <xry111@xry111.site>
-rw-r--r--misc-utils/lsfd-file.c96
-rw-r--r--misc-utils/lsfd.c3
-rw-r--r--misc-utils/lsfd.h7
3 files changed, 105 insertions, 1 deletions
diff --git a/misc-utils/lsfd-file.c b/misc-utils/lsfd-file.c
index 7287a1de83..35eabb3e45 100644
--- a/misc-utils/lsfd-file.c
+++ b/misc-utils/lsfd-file.c
@@ -45,6 +45,8 @@
#include "procfs.h"
#include "lsfd.h"
+#include "lsfd-pidfd.h"
+#include "pidfd-utils.h"
static size_t pagesize;
@@ -653,6 +655,22 @@ static unsigned long get_minor_for_mqueue(void)
return minor(sb.st_dev);
}
+static unsigned long get_minor_for_pidfs(void)
+{
+ int fd = pidfd_open(getpid(), 0);
+ struct stat sb;
+ unsigned long ret = 0;
+
+ if (fd < 0)
+ return 0;
+
+ if (fstat(fd, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFREG)
+ ret = minor(sb.st_dev);
+
+ close(fd);
+ return ret;
+}
+
static void file_class_initialize(void)
{
unsigned long m;
@@ -667,6 +685,10 @@ static void file_class_initialize(void)
m = get_minor_for_mqueue();
if (m)
add_nodev(m, "mqueue");
+
+ m = get_minor_for_pidfs();
+ if (m)
+ add_nodev(m, "pidfs");
}
const struct file_class file_class = {
@@ -935,3 +957,77 @@ const struct file_class mqueue_file_class = {
.fill_column = mqueue_file_fill_column,
.get_ipc_class = mqueue_file_get_ipc_class,
};
+
+struct pidfs_file {
+ struct file file;
+ struct pidfd_data data;
+};
+
+static void init_pidfs_file_content(struct file *file)
+{
+ struct pidfs_file *pidfs_file = (struct pidfs_file *)file;
+
+ memset(&pidfs_file->data, 0, sizeof(pidfs_file->data));
+}
+
+static int pidfs_file_handle_fdinfo(struct file *file, const char *key, const char *value)
+{
+ struct pidfs_file *pidfs_file = (struct pidfs_file *)file;
+
+ return pidfd_handle_fdinfo(&pidfs_file->data, key, value);
+}
+
+static void pidfs_file_free_content(struct file *file)
+{
+ struct pidfs_file *pidfs_file = (struct pidfs_file *)file;
+
+ pidfd_free(&pidfs_file->data);
+}
+
+static bool pidfs_file_fill_column(struct proc *proc __attribute__((__unused__)),
+ struct file *file,
+ struct libscols_line *ln,
+ int column_id,
+ size_t column_index)
+{
+ struct pidfs_file *pidfs_file = (struct pidfs_file *)file;
+ char *buf = NULL;
+
+ switch(column_id) {
+ case COL_TYPE:
+ if (scols_line_set_data(ln, column_index, "pidfd"))
+ err(EXIT_FAILURE, _("failed to add output data"));
+ return true;
+ case COL_NAME:
+ buf = pidfd_get_name(&pidfs_file->data);
+ break;
+ default:
+ if (!pidfd_fill_column(&pidfs_file->data, column_id, &buf))
+ return false;
+ }
+
+ if (buf &&
+ scols_line_refer_data(ln, column_index, buf))
+ err(EXIT_FAILURE, _("failed to add output data"));
+
+ return true;
+}
+
+const struct file_class pidfs_file_class = {
+ .super = &file_class,
+ .size = sizeof(struct pidfs_file),
+ .initialize_content = init_pidfs_file_content,
+ .handle_fdinfo = pidfs_file_handle_fdinfo,
+ .fill_column = pidfs_file_fill_column,
+ .free_content = pidfs_file_free_content,
+};
+
+bool is_pidfs_dev(dev_t dev)
+{
+ const char *fs = get_nodev_filesystem(minor(dev));
+
+ if (fs && (strcmp (fs, "pidfs") == 0))
+ return true;
+
+ return false;
+}
diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c
index d4d2a99bc9..f042f5caaa 100644
--- a/misc-utils/lsfd.c
+++ b/misc-utils/lsfd.c
@@ -667,6 +667,9 @@ static const struct file_class *stat2class(struct stat *sb)
if (is_mqueue_dev(dev))
return &mqueue_file_class;
+ if (is_pidfs_dev(dev))
+ return &pidfs_file_class;
+
return &file_class;
default:
break;
diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h
index b9a402ad20..217bf45338 100644
--- a/misc-utils/lsfd.h
+++ b/misc-utils/lsfd.h
@@ -220,7 +220,7 @@ struct file_class {
extern const struct file_class abst_class, readlink_error_class, stat_error_class,
file_class, cdev_class, bdev_class, sock_class, unkn_class, fifo_class,
- nsfs_file_class, mqueue_file_class;
+ nsfs_file_class, mqueue_file_class, pidfs_file_class;
/*
* IPC
@@ -299,4 +299,9 @@ bool is_mqueue_dev(dev_t dev);
*/
bool is_multiplexed_by_eventpoll(int fd, struct list_head *eventpolls);
+/*
+ * Pidfs
+ */
+bool is_pidfs_dev(dev_t dev);
+
#endif /* UTIL_LINUX_LSFD_H */