在Linux内核模块中,如何从fd inode获取可执行路径?

6
  • 假设一个存在于 /proc/**/fd/* 中的 inode
  • 还有一个需要从符号链接 /proc/**/exe 找到可执行文件路径的 Linux 内核模块

我应该如何实现,以便从 inode 号码获得使用 fd 的可执行文件路径?


1
一个inode可能没有路径,也可能有一个或多个路径,并且命名空间可能会导致不同进程中的不同路径。你需要路径做什么,为什么必须从内核模块中完成? - CL.
1
@CL。在内核模块中实现并非强制要求(我目前正在一个用户空间应用程序中实现它)。你所说的“你需要路径干什么”是什么意思? - ZedTuX
2
所以你要重新实现 lsof - CL.
1
不,我正在开发一个应用层防火墙,因此我正在按进程过滤出站数据包。 - ZedTuX
1
看看 lsof 是如何做到这一点的。 - CL.
显示剩余3条评论
1个回答

0

proc_inode 结构体PROC_I都是内部的。请参见[PATCH 27/28] proc: Make the PROC_I() and PDE() macros internal toprocfs [RFC]

相反,如何遍历 inode 的目录项列表呢?您可以使用 dentry_path_raw() 查找 /*/fd/* 路径名:

//struct inode *proc_inode;

struct dentry *dentry;
pid_t pid;
int found_match = 0;

printk(KERN_DEBUG "superblock type name: %s\n", proc_inode->i_sb->s_type->name);

// An inode's dentry list is protected by the i_lock. See:
// - "dcache->d_inode->i_lock protects: i_dentry, d_u.d_alias, d_inode of aliases"
//   http://lxr.free-electrons.com/source/fs/dcache.c?v=4.0#L48
// - The implementation of d_prune_aliases()
//   http://lxr.free-electrons.com/source/fs/dcache.c?v=4.0#L882
spin_lock(&proc_inode->i_lock);
hlist_for_each_entry(dentry, &proc_inode->i_dentry, d_u.d_alias) {
    char buf[64];
    const char *path_raw;
    char c;

    path_raw = dentry_path_raw(dentry, buf, sizeof(buf));

    // dentry_path_raw() places the path into `buf'. If `buf' is not large
    // enough, then continue on to the next dentry.
    if (!(buf <= path_raw && path_raw <= buf + sizeof(buf) - 1)) {
        printk(KERN_DEBUG "`buf' not large enough, dentry_path_raw() returned %ld\n", PTR_ERR(path_raw));
        continue;
    }

    printk(KERN_DEBUG "path_raw = %s\n", path_raw);

    // We're looking to match: ^/(\d*)/fd/

    if (*path_raw++ != '/') continue;

    pid = 0;
    for (c = *path_raw; c; c = *++path_raw) {
        if ('0' <= c && c <= '9') {
            pid = 10 * pid + (c - '0');
        } else {
            break;
        }
    }

    if (*path_raw++ != '/') continue;
    if (*path_raw++ != 'f') continue;
    if (*path_raw++ != 'd') continue;
    if (*path_raw != '/' && *path_raw != '\0') continue;

    // Found a match. Break the dentry list loop.
    found_match = 1;
    printk(KERN_DEBUG "breaking dentry list loop\n");
    break;
}
spin_unlock(&proc_inode->i_lock);

if (found_match) {
    printk(KERN_DEBUG "pid = %d\n", (int)pid);
}

编辑:我已经将演示项目上传到GitHub:
https://github.com/dtrebbien/so16317923-proc-fs-kernel-module


谢谢!我会看一下。 - ZedTuX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接