【发布时间】:2015-04-15 12:18:07
【问题描述】:
Windows (NtQueryObject)、Linux (/proc/self/fd/x) 和 OS X (F_GETPATH) 都有检索当前打开文件描述符路径的方法。据说 FreeBSD 也是如此,通过类似以下代码:
size_t len;
int mib[4]={CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC, getpid()};
BOOST_AFIO_ERRHOS(sysctl(mib, 4, NULL, &len, NULL, 0));
std::vector<char> buffer(len*2);
BOOST_AFIO_ERRHOS(sysctl(mib, 4, buffer.data(), &len, NULL, 0));
for(char *p=buffer.data(); p<buffer.data()+len;)
{
struct kinfo_file *kif=(struct kinfo_file *) p;
if(kif->kf_fd==fd)
{
lock_guard<pathlock_t> g(pathlock);
_path=path::string_type(kif->kf_path);
return _path;
}
p+=kif->kf_structsize;
}
这对于几乎所有类型的文件描述符除了返回空路径的常规文件都有效,至少在 FreeBSD 10 中是这样。我认为这是检查内核代码时的疏忽返回路径似乎微不足道,尽管可能出于性能原因不这样做。
procstat 使用与上述相同的 API,因此也只返回除常规文件之外的所有内容的路径。使用 statfs() 我至少可以获取文件挂载点的路径,但是检索挂载点和实际文件之间的路径片段是问题。
所以让我问这个问题:是否可以要求 UFS 或 ZFS 从 inode 返回路径片段,也许使用一些神奇的 ioctl 或 sysctl,甚至是一些实用程序库?有问题的代码不需要打开文件描述符的 路径,它只需要 some 当前可以找到文件描述符的规范路径(这是为了处理跟踪proposed Boost.AFIO 的第三方文件重命名)。
在此先感谢您的帮助。 FreeBSD 是该功能的主要操作系统中唯一的亮点,没有它,编写文件系统竞争安全检测代码是不可能的:(
编辑:我在http://comments.gmane.org/gmane.os.solaris.opensolaris.zfs/38277 找到了关于让 ZFS 将 inode 转换为路径的讨论。显然有一个 ZFS_IOC_OBJ_TO_PATH ioctl,但从谷歌来看,这不是一个很好的代码路径
【问题讨论】:
-
不管你怎么做都会很慢。我猜你不想做这样的事情......
find . -inum 6811865 -
遗憾的是,这需要非常快速的操作。尤其需要使用 openat/statat/unlinkat 快速解决其他文件系统竞争。