NFS 上的本地文件锁定依赖于 Linux 内核

NFS 上的本地文件锁定依赖于 Linux 内核

我有一个 python2 应用程序,需要通过 NFS 处理文件。不幸的是,应用程序使用了如下的lock()锁:

#!/usr/bin/env python2

import fcntl

print('Opening')
foo = open('file/on/NFS/share')
print('Locking')
fcntl.flock(foo, fcntl.LOCK_EX)
print('Closing')
foo.close()

失败了:

Opening
Locking
Traceback (most recent call last):
  File "./flock_lock.py", line 8, in <module>
    fcntl.flock(foo, fcntl.LOCK_EX)
IOError: [Errno 9] Bad file descriptor

如果我将其更改fcntl.flock()fcntl.fcntl()锁定作品。但这只是测试代码。我不能更改生产应用程序中的任何代码。这是不是代码问题,所以我相信它属于这里。

nolock我已使用和/或挂载了 NFS 共享local_lock=all
根据网络文件系统(5)

使用 nolock 选项时,应用程序可以锁定文件,但此类锁仅提供针对同一客户端上运行的其他应用程序的排除。

(另见 D10这里

和:

指定是否对集群和 POSIX 锁定机制中的任何一个或两者使用本地锁定。 [...]Linux NFS 客户端提供了一种在本地进行锁定的方法。这意味着,应用程序可以锁定文件,但此类锁仅提供针对同一客户端上运行的其他应用程序的排除。

我不太确定它们之间有什么区别,但是这些选项不应该启用仅本地锁(这对我来说很好)并防止 IO 错误吗?

羊群(2)说:

在 2.6.11 之前的 Linux 内核中,flock() 不会通过 NFS 锁定文件(即锁定范围仅限于本地系统)。 [...] 自 Linux 2.6.12 起,NFS 客户端通过将 FC 模拟为整个文件的字节范围锁来支持 Flock() 锁。

NFS服务器和NFS客户端都在运行科学Linux7.4(与 CentOS 非常相似),内核为 3.10。
内核 3.10 不应该能够使用 fancy() 锁定 NFS 文件吗?

我尝试在 Ubuntu 16.04(内核 4.4.0)主机上安装 NFS 共享,并且锁定工作正常!
然后我将 Scientific Linux 客户端更新到内核 4.4.91,它也可以工作了!
虽然这很棒,但我会多得多使用其库存内核 3.10 轻松运行生产客户端。

问题:如何使用工作本地锁挂载共享(没有更新内核)在现有内核 3.10 上?

奖金nolock:为什么和mount 选项不按照local_lock=all他们所说的那样做?我是否误解了手册页?
为什么在内核 > 2.6.11 上不起作用,flock()即使手册页说它可以?
为什么升级到内核 4.4 可以解决该问题?

答案1

我向 RedHat 报告了此行为。它实际上是由 RedHat 内核中的错误引起的,并在 kernel-3.10.0-693.18.1.el7 中修复。至少对于 NFSv3 来说是这样。对于 NFSv4,这似乎是所需的行为。

如果您有 RedHat 订阅,您可以查找票证:门票 01951116

相关内容