Bug#43651: debian-policy: [PROPOSAL] mailbox locking
Package: debian-policy
Version: 3.0.1.1
Severity: normal
The Debian policy is not very clear in the definition of the way,
mailbox locking should be implemented. It only points to a "reference
implementation" (liblockfile), which is said to be NFS-safe, but it
isn't with Linux kernel 2.2.* (see other messages in debian-policy and
debian-devel about this problem).
So I propose to change the following paragraph:
All Debian MUAs and MTAs have to use the `maillock' and `mailunlock'
functions provided by the `liblockfile' packages to lock and unlock
mail boxes. These functions implement a NFS-safe locking mechanism.
(It is ok if MUAs and MTAs don't link against liblockfile but use a
_compatible_ mechanism. Please compare the mechanisms very carefully!)
I had a look over the mailbox locking programs and there are <25%
which use liblockfile, all others implement locking themselves (some
of them in a compatible way, some without...).
So I think we should change the above paragraph to something which
explicitly says, how locking has to be implemented:
All Debian MUAs, MTAs, MDAs and other mailbox accessing programs
(like IMAP daemons) have to lock the mailbox in a NFS-safe way.
This means that fcntl() locking has to be combined with dot
locking. To avoid dead locks, a program has to use fcntl() first
and dot locking after this or alternatively implement the two
locking methods in a non blocking way[1]. Using the functions
`maillock' and `mailunlock' provided by the `liblockfile*'[2]
packages is the recommended way to realize this.
Footnotes:
[1] If it is not possible to establish both locks, the system
shouldn't wait for the second lock to be established, but
remove the first lock, wait a (random) time, and start over
locking again.
[2] liblockfile version >= .... (fill in a version number here,
which implements the above noted non blocking mechanism
without blocking).
Thomas Roessler <roessler@guug.de> posted a skeleton of maillock() to
debian-devel, maybe we should place this somewhere in the policy or in
/usr/[share/]doc/debian-policy/ or take this as a basis for a new
version of liblockfile:
int do_lock (const char *path, int fd, int retries)
{
int i;
int rv;
for (i = 0; i < retries; i++)
{
if ((rv = do_fcntl_lock (fd)) == -1 && errno != EAGAIN)
return -1;
else if (rv == 0)
{
if (do_dotlock (path) == 0)
return 0;
do_fcntl_unlock (fd);
}
sleep (rand() % 10);
}
return -1;
}
Ciao
Roland
Reply to: