Eu tenho um aplicativo python2 que precisa trabalhar em arquivos via NFS. Infelizmente, o aplicativo usa bloqueios flock () como este:
#!/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()
que falha:
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
Se eu alterar o fcntl.flock()
para fcntl.fcntl()
, o bloqueio funcionará. No entanto, este é apenas o código de teste. Eu não posso alterar qualquer código do aplicativo de produção. Isso é não um problema de código, então acredito que ele pertence aqui.
Eu montei o compartilhamento NFS com nolock
e / ou local_lock=all
.
De acordo com nfs (5) :
When using the nolock option, applications can lock files, but such locks provide exclusion only against other applications running on the same client.
(veja também D10 aqui )
e:
Specifies whether to use local locking for any or both of the flock and the POSIX locking mechanisms. [...] The Linux NFS client provides a way to make locks local. This means, the applications can lock files, but such locks provide exclusion only against other applications running on the same client.
Não sei ao certo qual é a diferença entre eles, mas essas opções não devem permitir bloqueios somente locais (o que é bom para mim) e evitar erros de E / S?
flock (2) diz:
In Linux kernels up to 2.6.11, flock() does not lock files over NFS (i.e., the scope of locks was limited to the local system). [...] Since Linux 2.6.12, NFS clients support flock() locks by emulating them as byte-range locks on the entire file.
O servidor NFS e o cliente NFS estão executando Scientific Linux 7.4 (muito semelhante ao CentOS) com o Kernel 3.10.
O Kernel 3.10 não deveria ser capaz de bloquear arquivos NFS com flock ()?
Eu tentei montar o compartilhamento NFS em um host Ubuntu 16.04 (Kernel 4.4.0) e o bloqueio funciona bem!
Então atualizei o Cliente Linux Scientific para o kernel 4.4.91 e ele funciona também!
Embora isso seja ótimo, eu estaria muito mais confortável executando o cliente de produção com seu kernel 3.10.
Pergunta : Como montar o compartilhamento com bloqueios locais ( sem atualizar o kernel) no kernel 3.10?
Bônus : por que as opções nolock
e local_lock=all
mount não fazem o que dizem? Estou entendendo mal as páginas do manual?
Por que o flock()
não funciona no kernel > 2.6.11 mesmo que a página do homem diga que sim?
Por que a atualização para o kernel 4.4 corrige o problema?