Python: blocking a text file in NFS

I have a file results.txton a server accessed by several virtual machines via NFS. The process runs on each of these virtual machines, which reads the file results.txtand modifies it. If there are two processes Aand B, read the file at the same time, then modification A or B will be present in results.txtbased on the order in which the processes are written to the file.

If the process Ahas a write lock on the file, then the process Bwill have to wait until the lock is released to read the file results.txt.

I tried to implement this using Python:

import fcntl


f = open("/path/result.txt")
fcntl.flock(f,fcntl.LOCK_EX)
#code

It works as expected for files on the local drive.

but when I start trying to lock the file on the set path, I get the following error:

Traceback (most recent call last):
  File "lock.py", line 12, in <module>
    fcntl.flock(f,fcntl.LOCK_EX)
IOError: [Errno 45] Operation not supported 

I tried fcntl.fcntland fcntl.flockbut got the same error. Is this a problem with how I use fcntl? Is any configuration required on the server where the file is stored?

Edit:

This is how I use fcntl.fcntl:

f= open("results.txt")
lockdata = struct.pack('hhllhh', fcntl.F_RDLCK,0,0,0,0,0)
rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)

The NFS server version is 3.

+4
source share
1 answer

I found flufl.lock most suitable for my requirement.

Quote from the author of the project page :

[...] O_EXCL NFS, ,          .                   fs (,         pid), (2), . ()         0, . stat (2)          , 2,          .

, . , , .

. .

def lockfile(target,link,timeout=300):                                             
        global lock_owner                                                          
        poll_time=10                                                               
        while timeout > 0:                                                         
                try:                                                               
                        os.link(target,link)                                       
                        print("Lock acquired")                                      
                        lock_owner=True                                            
                        break                                                      
                except OSError as err:                                             
                        if err.errno == errno.EEXIST:                              
                                print("Lock unavailable. Waiting for 10 seconds...")
                                time.sleep(poll_time)                              
                                timeout-=poll_time                                 
                        else:                                                      
                                raise err                                          
        else:                                                                      
                print("Timed out waiting for the lock.") 

def releaselock(link):                          
        try:                                    
                if lock_owner:                  
                        os.unlink(link)         
                        print("File unlocked")   
        except OSError:                         
                print("Error:didn't possess lock.")

, . - . , . .

+2

All Articles