jijothoma has asked for the wisdom of the Perl Monks concerning the following question:

Hi! Here's is my problem. I have a script which spawns multiple instances of a program that updates a central file which is present in an NFS. Now, before I attempt to write into the central file, I create a semaphore file and lock it using system("lockfile -l 10 -s 10 $semaphore_file"); The problem is that I'm not getting any error messages if the locking fails. I know the locking has failed because my central file is corrupted. I tried many ways to lock a file properly. I couldn't. I tried 1. flock - THey say flock won't work on files in NFS 2. fcntl - This doesn't work either. Could any one please tell me How can I lock a file which is in NFS? How can I trap any error if the file wasn't locked properly, by which I can prevent my central file from being corrupted. Please help.
  • Comment on Locking a file in NFS with proper exception handling

Replies are listed 'Best First'.
Re: Locking a file in NFS with proper exception handling
by jbrugger (Parson) on Jun 20, 2005 at 04:57 UTC
    file locking is os dependend, and doesn't always go right. I'd suggest your script itself handles the locking, eg:

    1. check the lock-file when opening the file
    1. write a lock-file when opening the file
    2. check the lock-file before opening the file
    Ah, ... same as described here

    "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.
Re: Locking a file in NFS with proper exception handling
by ambrus (Abbot) on Jun 20, 2005 at 09:38 UTC

    From the Linux manpage open(2):

    O_EXCL
    When used with O_CREAT, if the file already exists it is an error and the open will fail. In this context, a symbolic link exists, regardless of where its points to. O_EXCL is broken on NFS file systems, programs which rely on it for performing locking tasks will contain a race condition. The solution for performing atomic file locking using a lockfile is to create a unique file on the same fs (e.g., incorporating hostname and pid), use link(2) to make a link to the lockfile. If link() returns 0, the lock is successful. Otherwise, use stat(2) on the unique file to check if its link count has increased to 2, in which case the lock is also successful.
Re: Locking a file in NFS with proper exception handling
by bluto (Curate) on Jun 20, 2005 at 19:32 UTC
    File locking on NFS has a very checkered past. I've heard of cases where an NFS vendor claimed to have something working when in reality it didn't. IMHO, even if a vender gets locking to work all of the time, if you write data through NFS then it is only a matter of time before you see data corruption, and this includes lock files, but YMMV.

    There are some interesting hacks for NFS that try to get around this that tend to rely on knowing that there are certain atomic operations in the NFS server like rename/link. Look at CPAN's File::NFSLock if you are interested in this. FWIW, I've never used it, but it sounds like it does something like this. Whatever solution you use make sure you test it thoroughly on the machine/server you expect it to work on.