自从我们的客户从 Ubuntu 12.04 更新到 Ubuntu 14.04 后,我们就遇到了麻烦。
行为:
在客户端 AI 上更改 nfs 共享上的现有文件 foo。在客户端 BI 上执行 cat foo。
安装后第一次运行成功。cat 显示 foo 的内容。但如果我再次在客户端 A 上更改 foo,并在 BI 上执行 cat,则会收到错误:cat: foo: 没有这样的文件或目录
在 B 上执行 a 操作ls
可以解决问题,并cat foo
再次显示新内容。但如果我再次在客户端 A 上更改 foo,客户端 B 上的 cat 将无法正常工作。
分析:
如果 B 上的程序首先执行系统调用“stat”,则一切正常。但如果像 cat 这样的程序直接使用系统调用 open,它将找不到该文件!
使用 tcpdump 和 wireshark 我可以看到 Ubuntu 12.04 使用正确的(更新的)文件句柄调用“PUTFH”下的 NFS 数据包,但是在 14.04 中文件句柄是错误的(等于系统 A 上更改之前的旧文件句柄)。
现在到了非常有趣的部分:如果我在服务器站点上的 nfs 共享位于 ext4 文件系统上,并且我通过 /etc/exports 共享它,则 nfs 服务器将使用错误代码 NFS4ERR_STALE 进行响应。客户端 (B) 将使用正确的文件句柄执行第二个请求,并且一切正常。即使在 14.04 上也是如此。
如果我在服务器站点上的 nfs 共享位于 ZFS 文件系统(ZoL 0.6.4.1、CentOS 7 和 Ubuntu 14.04)上,并且我通过 sharefs 选项或 /etx/exports 共享它,则 nfs 服务器将使用错误代码 NFS4ERR_NOENT 进行响应。客户端将失败。
问题: 1. 如何让较新的客户端 (14.04+) 像 12.04 一样正确更新文件句柄 2. (或者) 如何让服务器在 ZFS 文件系统上以 NFS4ERR_STALE 进行应答?或者根据规范,服务器的应答应该是什么样子?
问候 Joerg
答案1
在 Linux 上的 ZFS 中修补:
https://github.com/zfsonlinux/zfs/pull/3404
获取 git 版本并编译:
git clone https://github.com/zfsonlinux/zfs.git