From: | Giles Lean <giles(at)nemeton(dot)com(dot)au> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | PostgreSQL Development <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: On file locking |
Date: | 2003-02-03 08:19:39 |
Message-ID: | 1100.1044260379@nemeton.com.au |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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't unlock
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
From | Date | Subject | |
---|---|---|---|
Next Message | Dave Page | 2003-02-03 08:47:14 | Re: Interactive Documentation - how do you want it towork? |
Previous Message | alex avriette | 2003-02-03 06:13:05 | Re: Irix 6.2, Postgres 7.3.1, some brokenness |