这个问题现在基本上让我抓狂了。我有一台 Ubuntu 16.04 NFS 服务器,它使用以下配置运行良好:
/etc/fstab:
UUID=b6bd34a3-f5af-4463-a515-be0b0b583f98 /data2 xfs rw,relatime 0 0
/data2 /srv/nfs/cryodata none defaults,bind 0 0
/usr/local /srv/nfs/local none defaults,bind 0 0
和
/etc/exports
/srv/nfs 192.168.159.31(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs/cryodata 192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/local 192.168.159.31(rw,sync,no_subtree_check)
到目前为止,使用此配置的一个 nfs 客户端上使用以下客户端 /etc/fstab 条目,所有这一切都已经正常运行了几个月:
kraken.bio.univ.edu:/local /usr/local nfs4 _netdev,auto 0 0
kraken.bio.univ.edu:/cryodata /cryodata nfs4 _netdev,auto 0 0
但是,由于这是一台非常大的存储服务器,因此决定它需要容纳多个实验室。因此,我将分散在 /data2 分区中的所有内容移至 /data2/cryodata 子目录中,并更新服务器上的 /etc/fstab 和 /etc/exports,如下所示:
/etc/fstab:
...
/data2/cryodata /srv/nfs/cryodata none defaults,bind 0 0
/data2/xray /srv/nfs/xray none defaults,bind 0 0
/data2/EM /srv/nfs/EM none defaults,bind 0 0
/usr/local /srv/nfs/local none defaults,bind 0 0
和
/etc/exports
/srv/nfs 192.168.159.31(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs/cryodata 192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/EM 192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/xray 192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/local 192.168.159.31(rw,sync,no_subtree_check)
这根本行不通!当我尝试使用相同的客户端 /etc/fstab 条目在客户端上安装新挂载时:
{nfs client} /etc/fstab:
...
kraken.bio.univ.edu:/local /usr/local nfs4 _netdev,auto 0 0
kraken.bio.univ.edu:/cryodata /cryodata nfs4 _netdev,auto 0 0
。
# mount -v /cryodata
mount.nfs4: timeout set for Sat Feb 24 09:24:38 2018
mount.nfs4: trying text-based options 'addr=192.168.41.171,clientaddr=192.168.159.31'
mount.nfs4: mount(2): Stale file handle
mount.nfs4: trying text-based options 'addr=192.168.41.171,clientaddr=192.168.159.31'
mount.nfs4: mount(2): Stale file handle
mount.nfs4: trying text-based options 'addr=128.83.41.171,clientaddr=129.116.159.31'
...
/usr/local 继续挂载,没有出现问题。第一次尝试时,我确实忘记在进行exportfs -var
更改之前取消导出/导出文件系统,但从那时起,我就来回切换,小心地取消导出和卸载所有内容,其间多次重新启动服务器。整个分区的绑定挂载的原始挂载始终有效,而子目录的绑定挂载每次都会失败,并显示过时的 nfs 句柄消息。我尝试启用从未挂载过这些分区的其他 nfs 客户端,并收到完全相同的错误消息:在这种情况下,这肯定是服务器端的问题。我检查了 /var/lib/nfs/etab,以确保在挂载尝试之间清除了它,等等。
我以为绑定挂载到 nfs 服务器根目录的技术可以解决所有这些问题,但显然不是?奇怪的是 /usr/local 是另一个分区的子目录,它总是挂载正常。它位于 ext3 md raid 1 上,尽管我无法想象这有什么关系。
我花了好几个小时来寻找解决方案,几乎用尽了谷歌搜索,但都无济于事。
答案1
请注意,我仅导出绑定挂载的文件系统。本节来自出口手册页相关:
fsid=数字|根|uuid
NFS 需要能够识别它导出的每个文件系统。通常,它会使用文件系统的 UUID(如果文件系统有 UUID)或保存文件系统的设备的设备号(如果文件系统存储在设备上)。
我错误的假设是绑定挂载的文件系统具有 NFS 可以自动使用的某种 UUID;并且这两个绑定挂载的导出在没有 fsid 的情况下都能正常工作,这一事实进一步证实了我的假设:
/srv/nfs 192.168.159.31(rw,sync,fsid=0,crossmnt,no_subtree_check)
/srv/nfs/cryodata 192.168.159.31(rw,sync,no_subtree_check)
/srv/nfs/local 192.168.159.31(rw,sync,no_subtree_check)
但是,这会导致行为不一致。我添加了一个 bind mounted /opt:
/etc/fstab:
/data1/opt /srv/nfs/opt none defaults,bind 0 0
/etc/exports:
/srv/nfs/opt 192.168.159.3(rw,sync,no_subtree_check)
导致行为不一致;例如,可以在一台机器上更改导出 IP 并挂载,但在另一台机器上却被拒绝许可。解决方案是添加一个 fsid:
/etc/exports:
/srv/nfs/opt 192.168.159.3(rw,sync,fsid=20,no_subtree_check)
因此解决方案是始终添加 fsid 来导出绑定挂载的文件系统。