This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Mandatory file locking semantics (was: sqlite3: bug with monotone)


On 6/4/2013 02:48, Corinna Vinschen wrote:
On Jun  3 11:36, Warren Young wrote:
Could you add an O_MAND open(2) option as well to turn on the same
feature?  This will avoid a race condition.

If you call F_LCK_MANDATORY right after open in the opening routine,
there won't be (much of) a race.  I know what you mean (it's the
O_CLOEXEC dilemma)

As long as everyone plays by the rules, there actually isn't a race.

For this style of locking to work at all, every program involved has to enable the mandatory locking flag before doing any I/O on the file. In that sense, locking is already atomic.

Adding O_MAND changes the call pattern from:

   fd = open(..., O_RDWR);
   fcntl(fd, F_LCK_MANDATORY, 1);
   fcntl(fd, F_SETLK, &lock);

to:

   fd = open(..., O_RDWR | O_MAND);
   fcntl(fd, F_SETLK, &lock);

Since there are two required calls due to the POSIX design, there's still a hole here, where an uncooperative program could call open(2) for writing on the same file without acquiring the lock. To fix *that* race condition, you'd need an extension to open(2) that lets it acquire the lock on open. That just isn't in the cards.

Or am I missing something? Does mandatory locking on Linux or SysV somehow avoid the "uncooperative program" race?




That having been said, I still think O_MAND works better.

Cygwin's mandatory locking is effectively a flag on the file that, once set, stays with the file descriptor as long as it is open.

You can later unset the flag, but under what condition would that ever be the right thing? That effectively tries to mix locking semantics on the same file descriptor!

The F_LCK_MANDATORY design also allows you to do arbitrary I/O between open() and setting the flag, another thing which can never be correct. It violates the rule laid out above that allows two Cygwin programs to cooperatively enable mandatory file locking "atomically".

If a Cygwin program wants mandatory locking, it should be enabled continuously from open() to close().



If those weren't enough reasons, it now feels weird that you use fcntl() to set the locking flag even when you're going to use flock() or lockf() to do the actual locking.

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]