Search code examples
multithreadingperllockingnfs

Perl File::NFSLock fails to acquire lock with error EACCESS


I have a file on an NFS mount which is locked and unlocked for every operation done on it. Initially I used flock(filehandle, LOCK_EX|LOCK_NB) but that attempt failed with I/O Error.
On browsing through multiple forums I found a solution to use File::NFSLock to lock/unlock files on a NFS share. However, NFSLock succeeds on the first attempt to lock and unlock the file, however when 2 processes simultaneously tries to access the locks, it fails with EACESS error.
Here is how the code is:

  1. Process 1 acquired lock with the below code and also released the lock once done:
    if ($lock = new File::NFSLock {
      file      => $handle,
      lock_type => LOCK_EX|LOCK_NB,
    }) {
  1. Now 2 processes were spawned with a fork command (Process 2 and Process 3). When Process 2 tried to lock the same file using same above code in Step 1, file locking failed with error Permission Denied. After 15 seconds when Process 3 tried to acquire lock it also failed with Permission Denied error.
    When I executed fuser -v on the file, I could see 2 process IDs (Process 2 and Process 3) which had opened the file for writing.

Few documents on internet suggest that The lock cannot be set because it is blocked by an existing lock on the file. Some systems use EAGAIN in this case, and other systems use EACCES however doesn't seem to be the case in my scenario as Process 1 had released the lock.
Also please note that all the 3 processes were spawned from the same script, so there shouldn't be an issue of different user trying to acquire the lock.

Thank You!


Solution

  • File::NFSLock expects a file path —not a file handle— for its file parameter. Replacing the file handle with a file path solved the issue.

    if ($lock = new File::NFSLock {
      file      => $path,             # Previously, I used file handle here.
      lock_type => LOCK_EX|LOCK_NB,
    }) {