3

I have an python2 application which needs work on files over NFS. Unfortunately the application uses flock() locks like this:

#!/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()

which fails:

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

If I change the fcntl.flock() to fcntl.fcntl() the locking works. However this is only test code. I cannot change any code from the production application. This is not a code problem so I believe it belongs here.

I've mounted the NFS share with nolock and/or local_lock=all.
According to 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.

(also see D10 here)

and:

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.

I'm not quite sure what is the difference between them, but shouldn't those option enable local-only locks (which is fine for me) and prevent IO-errors ?

flock(2) says:

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.

The NFS server and the NFS client are both running Scientific Linux 7.4 (very similar to CentOS) with Kernel 3.10.
Shouldn't Kernel 3.10 be able to lock NFS files with flock() ?

I tried mounting the NFS share on an Ubuntu 16.04 (Kernel 4.4.0) host and the locking works fine!
I then updated the Scientific Linux Client to kernel 4.4.91 and it works too!
While this is great I would be much more comfortable running the production client with its stock kernel 3.10.

Question: How can I mount the share with working local locks (without updating the kernel) on stock kernel 3.10 ?

Bonus: Why don't the nolock and local_lock=all mount options do what they say? Am I misunderstanding the man pages?
Why doesn't flock() work on kernel > 2.6.11 even though the man page says it does?
Why does upgrading to kernel 4.4 fix the problem ?

0

I reported this behaviour to RedHat. It was actually caused by a bug in the RedHat Kernel and was fixed in kernel-3.10.0-693.18.1.el7. At least for NFSv3. For NFSv4 this seems to be the desired behaviour.

If you have a RedHat Subscription you can look up the Ticket: Ticket 01951116

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.