我想向Linux内核添加一个新的系统调用,它将显示有关系统中创建的所有管道的信息。
如何获取pipefs中每个管道的inode(或允许我访问pipe_inode_info的任何其他相关结构)?
我一直在关注struct vfsmount,struct dentry和struct super_block,但我找不到正确的方法。 有什么办法可以获取pipefs中每个文件的文件结构吗?
答案 0 :(得分:1)
首先我去/ proc目录和问题:
ls -al */fd |grep pipe
(尝试取消上面的“管道”,你会了解更多。)结果是(只是一个快照):
l-wx------ 1 root root 64 2011-05-14 23:12 17 -> pipe:[39208]
l-wx------ 1 root root 64 2011-05-14 23:12 2 -> pipe:[16245]
lr-x------ 1 root root 64 2011-05-14 23:12 4 -> pipe:[23406]
l-wx------ 1 root root 64 2011-05-14 23:12 8 -> pipe:[23406]
l-wx------ 1 root root 64 2011-05-14 23:12 17 -> pipe:[39532]
l-wx------ 1 root root 64 2011-05-14 23:12 2 -> pipe:[16245]
lr-x------ 1 root root 64 2011-05-14 23:12 4 -> pipe:[23406]
l-wx------ 1 root root 64 2011-05-14 23:12 8 -> pipe:[23406]
l-wx------ 1 root root 64 2011-05-14 23:12 1 -> pipe:[16245]
lr-x------ 1 root root 64 2011-05-14 23:12 16 -> pipe:[40032]
l-wx------ 1 root root 64 2011-05-14 23:12 17 -> pipe:[40032]
l-wx------ 1 root root 64 2011-05-14 23:12 2 -> pipe:[16245]
lr-x------ 1 root root 64 2011-05-14 23:12 4 -> pipe:[23406]
l-wx------ 1 root root 64 2011-05-14 23:12 8 -> pipe:[23406]
l-wx------ 1 tteikhua tteikhua 64 2011-05-14 23:13 1 -> pipe:[16245]
l-wx------ 1 tteikhua tteikhua 64 2011-05-14 23:13 12 -> pipe:[66674]
lr-x------ 1 tteikhua tteikhua 64 2011-05-14 23:13 13 -> pipe:[66674]
l-wx------ 1 root root 64 2011-05-14 23:30 1 -> pipe:[101794]
如果你想看到创建管道的过程,只需删除“grep”,例如:
这里显示pid = 1的管道fd为6759:
1/fd:
total 0
dr-x------ 2 root root 0 2011-05-14 23:29 .
dr-xr-xr-x 7 root root 0 2011-05-14 22:59 ..
lrwx------ 1 root root 64 2011-05-14 23:29 0 -> /dev/console (deleted)
lrwx------ 1 root root 64 2011-05-14 23:29 1 -> /dev/console (deleted)
lrwx------ 1 root root 64 2011-05-14 23:29 2 -> /dev/console (deleted)
lr-x------ 1 root root 64 2011-05-14 23:29 3 -> pipe:[6759]
并将上面的内容追溯到fs / pipe.c(打印这些内容的linux内核源代码):
/*
* pipefs_dname() is called from d_path().
*/
static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen)
{
return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
dentry->d_inode->i_ino);
}
static const struct dentry_operations pipefs_dentry_operations = {
.d_dname = pipefs_dname,
};
阅读fs / dcache.c:
char *d_path(const struct path *path, char *buf, int buflen)
{
if (path->dentry->d_op && path->dentry->d_op->d_dname)
return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
and since d_path() is an exported symbol,
EXPORT_SYMBOL(d_path);
你应该可以从任何地方调用它,并获取有关路径的信息 - 如果它是一个管道,那么将调用相应的pipefs_dname() - 它依赖于文件系统:
./fs/pipe.c:
.d_dname = pipefs_dname,
读取inode.c:init_inode_always(),你可以看到i_pipe设置为NULL。仅当inode是PIPE时它不为null。
所以你总是可以循环遍历所有进程并获取其打开的文件描述符,并且inode的i_pipe设置为非NULL,你将知道该值是管道的inode编号。
我不认为这些代码会存在于内核源代码中(因此没有必要去寻找它 - 我已经尝试过了)因为它在用户空间中更有效率和更安全(比如“ls -al”) “我之前解释过的命令”然后在内核中 - 通常内核越小安全性越小,因此稳定性越好等。