如何从FreeBSD上的inode获取路径(ZFS和UFS)?

时间:2015-02-14 14:56:50

标签: freebsd bsd inode zfs

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,甚至是一些实用程序库?有问题的代码不需要打开文件描述符的路径,它只需要一些规范路径,当前可以找到文件描述符(这是处理跟踪第三方文件重命名proposed Boost.AFIO)。

我提前感谢您的帮助。 FreeBSD是这个功能的主要操作系统中唯一的showstopper,如果没有它,它将使写入文件系统竞赛安全检测代码变得不可能:(

编辑:我发现了一个关于让ZFS将inode转换为http://comments.gmane.org/gmane.os.solaris.opensolaris.zfs/38277路径的讨论。显然有一个ZFS_IOC_OBJ_TO_PATH ioctl,但从谷歌判断这不是一个很好的代码路径

1 个答案:

答案 0 :(得分:0)

事实证明,KERN_PROC_FILEDESC无法正常工作的事实实际上是FreeBSD内核中的一个错误。我已将其记录在https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197695

KERN_PROC_FILEDESC可以完美地用于目录文件描述符,包括跟踪重命名和删除。它不完美适用于常规文件描述符,有时返回一个路径,然后突然返回一个空路径,然后随后随机返回一个路径。我认为在10.x版本的某个地方某些东西被破坏了:(

希望能帮助其他人同样坚持下去。