187 lines
4.6 KiB
Diff
187 lines
4.6 KiB
Diff
|
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
|
||
|
|