File 0003-lsfd-Support-pidfs.patch of Package util-linux
From: Xi Ruoyao <xry111@xry111.site>
Date: Wed, 3 Apr 2024 15:46:57 +0800
Subject: lsfd: Support pidfs
Git-repo: https://github.com/util-linux/util-linux.git
Git-commit: b1a48efd173c7f37d8df39a84eb25b4440335661
Patch-mainline: yes
References: kernel 6.9
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>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
misc-utils/lsfd-file.c | 96 ++++++++++++++++++++++++++++++++++++++++++
misc-utils/lsfd.c | 3 ++
misc-utils/lsfd.h | 7 ++-
3 files changed, 105 insertions(+), 1 deletion(-)
diff --git a/misc-utils/lsfd-file.c b/misc-utils/lsfd-file.c
index 9b91462d..3f330146 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 struct idcache *username_cache;
@@ -492,6 +494,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;
@@ -510,6 +528,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");
}
static void file_class_finalize(void)
@@ -783,3 +805,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 98820ee8..01e88d51 100644
--- a/misc-utils/lsfd.c
+++ b/misc-utils/lsfd.c
@@ -683,6 +683,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 e646758c..f0f17d5b 100644
--- a/misc-utils/lsfd.h
+++ b/misc-utils/lsfd.h
@@ -228,7 +228,7 @@ struct file_class {
};
extern const struct file_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
@@ -307,4 +307,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 */
--
2.45.0