Re: On file locking - Mailing list pgsql-hackers
From | Giles Lean |
---|---|
Subject | Re: On file locking |
Date | |
Msg-id | 1100.1044260379@nemeton.com.au Whole thread Raw |
In response to | Re: On file locking (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: On file locking
|
List | pgsql-hackers |
Tom Lane wrote: > On HPUX 10.20, flock doesn't seem to exist (hasn't got a man page nor > any mention in /usr/include). Correct. Still isn't there in later releases. > lockf says > > All locks for a process are released upon > the first close of the file, even if the process still has the file > opened, and all locks held by a process are released when the process > terminates. > > and > > When a file descriptor is closed, all locks on the file from the > calling process are deleted, even if other file descriptors for that > file (obtained through dup() or open(), for example) still exist. > > which seems to imply (but doesn't actually say) that HPUX keeps track of > exactly which process took out the lock, even if the file is held open > by multiple processes. Having done some testing today, I now understand what the standards are trying to say when they talk about locks being "inherited". Or at least I think I understand: standards are tricky, locking is subtle, and I'm prepared to be corrected if I'm wrong! All of these lock functions succeed when the same process asks for a lock that it already has. That is: fcntl(fd, ...); fcntl(fd, ...); /* success -- no error returned */ For flock() only, the lock is inherited by a child process along with the file descriptor so the child can re-issue the flock() call and that will pass, too: flock(fd, ...); pid = fork(); if (pid == 0) flock(fd, ...); /* success -- no error returned */ For fcntl() and lockf() the locks are not inherited, and the call in a child fails: fcntl(fd, ...); pid = fork(); if (pid == 0) fcntl(fd, ...); /* will fail and return -1 */ In no case does just closing the file descriptor in the child lose the parent's lock. I rationalise this as follows: 1. flock() is using a "last close" semantic, so closing the file descriptor is documented not to lose the lock 2. lockf() and fcntl() use a "first close", but because the locks are not inherited by the child process the child can'tunlock them > This all doesn't look good for using file locks in the way I had in > mind :-( ... but considering that all these man pages seem pretty vague, > maybe some direct experimentation is called for. I conjecture that Tom was looking for a facility to lock a file and have it stay locked if the postmaster or any child process was still running. flock() fits the bill, but it's not portable everywhere. One additional warning: this stuff *is* potentially filesystem dependent, per the source code I looked at, which would call filesystem specific routines. I tested with HP-UX 11.00 (VxFS), NetBSD (FFS) and Linux (ext3). I've put the rough and ready test code up for FTP, if anyone wants to check my working: ftp://ftp.nemeton.com.au/pub/pgsql/ Limitations in the testing: I only used whole file locking (no byte ranges) and didn't prove that a lock taken by flock() is still held after a child calls close() as it is documented to be. Regards, Giles
pgsql-hackers by date: