almost all of MH relies on the atomic nature of "link()" in Unix.
a link() either works or fails - there is no half-way and filenames
are unique in directories. note it uses link()/unlink(), not rename()
which didn't exist in the good ol' days when MH was born. that also
means it's harder to just "lose" a file because of a metastable state
when it's "nowhere". this works reasonably well for message files.
.mh_sequences are a recent addition, however. Unix file locking has
always been a dubious proposition without the addition of explicit
locking primitives, and on NFS it's famously treacherous.
again, the uniqueness of message files and the link()/unlink() pair
still provides for retention in case of failure (leading to the
spin-lock style code commented on), but attempting to atomically
update .mh_sequences is another matter altogether.
i can never remember which one works with NFS, flock() or fcntl(),
and that assumes the server supports locking, which not all do!
and i don't remember what's supposed to happen with the "working"
primitive if the server doesn't support the lock daemon. and it's
hard to know which is worse - lying about having the lock or
eternally failing to get it. you're screwed either way because
it reduces to the same case.
AFS is its own nest of snakes. why anyone would introduce semantics
such that "close()" can fail is just beyond me. (like WTF are you
supposed to do about it??) after spending some time working on
the Andrew project, Dave Tilbrook later did a wonderful talk on
the tribulations of coding reliable software for the Andrew
things that require atomic updates to files (other than
directories) by user processes are simply to be avoided if
at all possible. it borders on evil.
the one thing you can try, because it leverages the behavior that
makes message files work, is to do the spin-lock thing.
create a random file in the directory containing the file to be updated,
then attempt to link() it to a well-known name, say ".mh_lock",
spinning on that link(). when it succeeds, do the update to
.mh_sequences, then remove the .mh_lock to let the next guy in.
this doesn't address the question of what to do when the .mh_lock
file gets left behind accidently.....
which is why designing things that need locks are basically evil.
Nmh-workers mailing list