Ian Jackson writes ("Re: PATCH: Make install-info use fcntl (via perl's flock) 
for locking"):
> So the process of locking and updating would be:
>  1. Attempt to open .lock for writing O_EXCL
>    a.  If this succeeds, write "perl-flock\n"
>    b.  If this fails,
>          i.  open the file for reading; if this fails ENOENT
>               go back to start
>          ii. check whether the file contains only "perl-flock\n"
>               and if not sleep 1 and go back to start
>  2. Lock .lock with Perl's flock
>  3. Read old file contents
>  4. Write new file contents to temporary file
>  5. Unlink old backup file
>  6. link(2) old file to backup file
>  7. rename(2) temporary file to primary file

I should point out that the lack of explicit unlocking and deletion
here is deliberate; the kernel will release the fcntl lock for us.  It
does mean that after any new program has taken out the lock in this
way all old programs will fail thinking the lock is already held.

(Also, there is a bug: in 1(b)(i) you have to open the file O_RDWR
without O_CREAT.)

If this is not acceptable, then you have to unlink the .lock file as
part of unlocking.  When you have this protocol, acquiring the lock
is more complex, to avoid the race where you fcntl lock the lockfile
just as the previous lock holder is unlinking it.  You hold the lock
only if after acquiring the fcntl lock you fstat the file to check the
file you've fcntl locked is still named as the lockfile, and you may
not unlink the lockfile without holding the lock:

  1. Attempt to open .lock for writing O_EXCL
    a.  If this succeeds, write "perl-flock\n"
    b.  If this fails,
          i.  open the file for read+write, without create;
               if this fails ENOENT go back to start
          ii. check whether the file contains only "perl-flock\n"
               and if not sleep 1 and go back to start
    (If we weren't trying to be compatible with an old scheme we could
     just open the file as in 1(b)(i) and not write anything to it.)

  2. Lock .lock with Perl's flock
  3. fstat your fd on .lock and stat .lock; compare dev and inum
     if not identical then race has happened, go back to start
  -- lock is now held --

  4. Read old file contents                     } standard, nearly
  5. Write new file contents to temporary file  }  only, safe method
  6. Unlink old backup file                     }   of updating a file
  7. link(2) old file to backup file            }    on unix
  8. rename(2) temporary file to primary file   }

  -- release lock: --
  9. unlink .lock           } must be done
 10. close our fd on .lock  }  in this order

Ian.


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to