NFS v4 服务器导致文件句柄过时,但仅当绑定挂载是子目录时才会发生

NFS v4 服务器导致文件句柄过时,但仅当绑定挂载是子目录时才会发生

这个问题现在基本上让我抓狂了。我有一台 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 来导出绑定挂载的文件系统。

相关内容