如何在eBPF探针的nfs_getattr函数中从path结构体获取客户端挂载点?
可行实现方案与指引
1. 结合vfsmount与用户态mountinfo匹配挂载点
内核中struct vfsmount的mnt_ns字段指向所属的挂载命名空间,mnt_mountpoint则指向该挂载在父命名空间中的入口dentry。你可以按以下步骤处理:
- 在eBPF探针中,通过
bpf_core_read安全读取path->mnt->mnt_ns->ns.inum(命名空间的inode编号,作为唯一标识),同时提取NFS共享的源信息(比如从path->mnt->mnt_sb->s_fs_info指向的nfs_server结构体中获取hostname和export_path,拼接成127.0.0.1:/nfs-share格式)。 - 用户态遍历
/proc/self/mountinfo文件,每行的第4列是命名空间ID,第10列是挂载源,第5列是挂载点路径。匹配eBPF传递的命名空间ID和NFS源信息,即可得到对应的/mnt/nfs-mount。
2. 利用vfsmount指针关联用户态挂载信息
6.3.0内核的/proc/self/mountinfo中,部分版本会在第11列输出vfsmount结构体的指针值。你可以:
- 在eBPF中记录
path->mnt的指针地址(作为挂载实例的唯一标识)。 - 用户态遍历
mountinfo,匹配指针值对应的行,直接读取第5列的挂载点路径。
3. 注意事项
- 必须使用
bpf_core_read系列函数访问内核结构体,避免因内核版本偏移导致的非法访问错误,同时要确保eBPF程序中包含6.3.0内核对应的结构体定义。 - 挂载命名空间隔离:不同命名空间下同一NFS共享可能对应不同挂载点,必须携带命名空间标识才能准确匹配,不能仅依赖NFS源信息。
- 用户态解析优先选择
/proc/self/mountinfo,它比/proc/mounts提供了更丰富的层级、命名空间信息,匹配准确性更高。
内容的提问来源于stack exchange,提问作者Daniel Katz
相关产品推荐
相关产品推荐

