Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!cs.utexas.edu!sun-barr!olivea!tymix!cirrusl!ss168!dhesi From: dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) Newsgroups: comp.mail.elm Subject: Re: Will ELM ever use lockf()? Message-ID: <3032@cirrusl.UUCP> Date: 3 Apr 91 01:42:06 GMT References: <1991Mar25.193741.12360@coplex.uucp> <1991Mar26.055600.27712@ariel.unm.edu> Sender: news@cirrusl.UUCP Organization: Cirrus Logic Inc. Lines: 103 In <1991Mar26.055600.27712@ariel.unm.edu> sfreed@ariel.unm.edu (Steven Freed CIRT) writes: >The reason we are interested in doing something is because of >the locking problems with NFS. Lockf() is the *only* way to guarantee >file locking with NFS. I can point out several scenarios where lock files >will fail. To make the change means that everything that writes any mailboxes >on the system including /bin/mail must use lockf(). It turns out that lockf() uses a lock daemon and, under SunOS at least, this doesn't always work. Lock files, on the other hand, are guaranteed to work if you do them right. Copy of previous Usenet posting follows. ====== Date: 22 Jan 91 07:41:25 GMT From: dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) Newsgroups: comp.lang.perl Subject: Re: Locking files across NFS References: <1991Jan15.203815.25561@uvaarpa.Virginia.EDU> Sender: cirrusl!news Organization: Cirrus Logic Inc. In <1991Jan15.203815.25561@uvaarpa.Virginia.EDU> worley@compass.com (Dale Worley) writes: >Beware that Sun's locking daemons don't always work correctly. Sun's locking daemons have never worked correctly whenever I have tried them. I finally decided that it would be better to rely on the standard reliable UNIX method: create a lock file. I used this successfully for a while. Then discovered with a shock that NFS has no mechanism for ensuring exclusive creation of a file even if the O_EXCL flag is given to open(). NFS does make symbolic links links correctly. I think it may even make hard links correctly. The following algorithm assumes that hard links are correctly created atomically. So the only reliable mechanism that exists to do file locking over NFS is the following or its equivalent. if you want reliable locking that is reasonably immune to locks being held by dead processes, I see no way of making this algorithm any simpler. int get_a_lock() { if (create(symlink called MUTEX that points anywhere) == failed) { die("serious problem -- can't create MUTEX"); } /* reach here when gained exclusive access */ attempts = 0; while (++attempts < SOME_LIMIT) { if (create(some unique temp file called $TMP) == succeeded) { to $TEMP write our host name and pid; break; /* done with while loop */ } else { sleep (a few seconds); } } if (attempts == SOME_LIMIT) { die("serious problem -- can't create mutex"); } try_again: { static int loop_breaker; if (++loop_breaker > SOME_OTHER_LIMIT) { loop_breaker = 0; unlink($TMP); unlink(MUTEX); return LOCK_ATTEMPT_FAILED; /* or die here */ } } if (create(link from $TMP to LOCK) == success) { /* we have the lock!! */ unlink($TMP); /* not needed, link is now LOCK */ unlink(MUTEX); /* not needed, done its work */ return GOT_A_LOCK; } /* failed to create link; see if it's a stray link */ if (LOCK doesn't exist) { unlink($TMP); unlink(MUTEX); die("serious problem, LOCK nonexistent but can't create"); } if (read(contents of LOCK) == failed) { unlink($TMP); unlink(MUTEX); die("serious problem, can't read existing LOCK"); } lock_host = name of host read from LOCK; lock_pid = pid read from LOCK; if (lock_host is our current host) { /* see if process still alive */ if (kill(pid, SIG_SEE_IF_IT'S_THERE) == ENO_SUCH_PROCESS) { unlink(LOCK); /* must have been stray */ goto try_again; } } /* LOCK is already held by existing process on this host or is on some other host */ return LOCK_ATTEMPT_FAILED; } -- Rahul Dhesi UUCP: oliveb!cirrusl!dhesi