Coda File System

Re: delivering mail to coda in maildir format

From: Jan Harkes <jaharkes_at_cs.cmu.edu>
Date: Mon, 12 Jul 2004 13:01:08 -0400
On Sat, Jul 10, 2004 at 11:06:28PM -0500, Troy Benjegerdes wrote:
> Has anyone tried running a 'production' mailserver that delivers mail
> directly to coda volumes? Obviously you don't want to do this in mbox
> format, but what about maildir?

Hi Troy,

I've been using maildir for a long time now, there is one change that I
had to make to the protocol.

In the original maildir spec, after the mail is written in the tmp
directory, it is hardlinked to a name in new and then the name entry in
tmp is removed. But Coda doesn't support cross-directory hardlinks so
I had to replace the link/unlink sequence with an (atomic) rename().

This is mostly identical, with one exception. If the target of the
rename exists it is silently unlinked, while in the link/unlink case
this would be detected. However, maildir already takes a lot of care
to avoid name-collisions like this. In fact most implementations seem to
use rename already. I haven't had to modify any mail-reading or delivery
apps in a long time.

The only problem that occasionally hits is that resolution sometimes
triggers a conflict. If one server was down then the remaining replica
contains the following resolution logs,

    tmp/ create foo
	store foo
	rename(-src) foo ../new/foo

    new/ rename(-dst) ../tmp/foo foo

After the server comes back, and we check the new/ directory first we
see the rename operation and try to resolve. However the foo object
does not yet exist on both servers, so the resolution fails and both tmp
and new are marked inconsistent. The repair is trivial when starting
with tmp (repair tmp /tmp/fix), the file creation is propagated to both
servers and the rename is performed. The following repair on the new
directory is only needed to clear the inconsistency flag.

This type of rename resolution is the only one that is still almost
guaranteed to give a conflict, if we looked at the tmp directory first
the object would have existed and everything would have been fine, but
programs that poll for new mail don't have a reason to check tmp before
checking new...

As a result my procmail script still uses local dist as a fallback just
in case there was a conflict on the maildir directories or in case my
tokens have expired.

    :0 W
    * ^X-Mailing-List:.*codalist@
    /coda/coda.cs.cmu.edu/.../codalist/

    # If any deliveries failed save it in the retry-delivery folder
    # (local-disk)
    :0:
    * ^X-Mailing-List:.*codalist@
    retry-delivery


> What are the semantics of what happens when you get a conflict? Will the
> files in conflict just not be available, or will my entire maildir
> dissappear?

Typically tmp and new will have a conflict, but any (previously read)
mail in cur is still accessible. Fixing the rename-dst resolution case
should (I hope) make maildir delivery conflict free, but it is a though
one to get right.

Jan
Received on 2004-07-12 13:02:42