NFS 文件锁定不起作用,我误解了吗?

use*_*689 5 nfs lock

我计划进行复杂的文件共享设置,并希望确保不会破坏文件锁定。(想在同一数据上使用绑定挂载、nfs、nfs over rdma(InfiniBand 文件共享)和 virtfs(kvm 虚拟机直通文件共享)。)

我刚开始进行健全性检查,只是用一个 nfs 客户端测试 nfs 服务器。两个系统上的最新 Arch,nfs-utils 1.3.2-6,内核 4.1.6-1。

我看到了意想不到的结果。在 nfs 服务器上:

server exports with: /test 192.168.0.0/16(rw,sync,no_subtree_check,
   no_root_squash)
client mount shows: 192.168.1.2:/test on /test type nfs4 (rw,noatime,vers=4.2,
   rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,
   retrans=2,sec=sys,clientaddr=192.168.1.3,local_lock=none,addr=192.168.1.2)
Run Code Online (Sandbox Code Playgroud)

在 /test 中,我有一个以lockFile内容命名的脚本:

#!/bin/bash
filename="lockedFile"
exec 200>$filename
flock -n 200 || exit 1
pid=$$
while true; do
   echo $pid 1>&200
done
Run Code Online (Sandbox Code Playgroud)

如果我在 nfs 服务器上使用两个终端:

1: ./lockFile
2: ./lockFile
Run Code Online (Sandbox Code Playgroud)

然后,终端 1 迅速用它的 pid 填满一个文件,终端 2 立即退出。一切都在预料之中。

但是,如果我在 nfs 服务器和客户端上分别运行一个终端:

server: ./lockFile
client: ./lockFile
Run Code Online (Sandbox Code Playgroud)

两人开心地奔跑,出乎意料。

在此配置中,我的 nfs 服务器运行为sync,这意味着服务器仅在实际写入数据时才说写入数据。我的 nfs 客户端运行为async,这意味着客户端仅在文件关闭时传输写入。

我可以看到正在运行的客户端在async实际传输写入之前可能不会获得锁定,因此我对此进行了测试,将客户端更改为sync.

client mount now shows: 192.168.1.2:/test on /test type nfs4 (rw,noatime,sync,
   vers=4.2,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=0,timeo=600,
   retrans=2,sec=sys,clientaddr=192.168.1.3,local_lock=none,addr=192.168.1.2)
Run Code Online (Sandbox Code Playgroud)

仍然lockFile愉快地在两台机器上运行。

我是否误解了 NFS 文件锁定的工作方式?是否需要处理服务器访问与客户端访问?或者,它仅用于客户端访问还是不同的客户端访问?

roa*_*ima 6

flock不适用于 NFS。(它从来没有,即使在 UNIX 系统上也是如此。)

羊群VS Linux上提供lockf为一个比较lockfflock

这是一个可能的解决方案在 shell 脚本中正确锁定?