Fast jeder Linux-Rechner hat einen MTA, einen Mail Transfer Agent installiert. Sei es Postfix, Exim oder gar Sendmail. Er nimmt E-Mails entweder lokal, zum Beispiel über einen Fetchmail-Prozess, oder über TCP entgegen. Stellt der MTA fest, dass die Mail an einen lokalen Benutzer adressiert ist, gibt er sie an den Local Delivery Agent (LDA) weiter. Dieser schreibt sie - eventuell nach einem kurzen Umweg über Filter wie Procmail - in eine Mailbox-Datei.
Verschwundene E-Mails
Kommen zwei E-Mails gleichzeitig an, gibt der MTA sie an zwei verschiedene LDA-Prozesse weiter. Jeder Prozess versucht in dieselbe Mailbox zu schreiben (siehe Abbildung 1). Im günstigsten Fall landen die Mails in der falschen Reihenfolge in der Datei. Wahrscheinlicher ist es jedoch, dass eine der E-Mails verloren geht, weil beide Prozesse ihre Daten gegenseitig überschreiben.
Abbildung 1: Ohne Locking würde bei zwei gleichzeitig ankommenden E-Mails eine verloren gehen. Denn der eine LDA-Prozess merkt nicht, was der andere tut.
Der erste Prozess öffnet die Datei, danach auch der zweite. Dann schreibt die erste Instanz des LDA die E-Mail in die Datei und schließt diese. Die andere Instanz hat die Mailbox aber noch geöffnet und überschreibt einfach die Daten der ersten Mail. Nach dem Schließen der Datei ist die erste Mail verschwunden.
Locks sorgen für Ordnung
So genannte Locks sind die gängige Lösung für dieses Problem. Ein Lock (Schloss) sperrt eine Ressource, solange ein Prozess sie nutzt. Wer zum Beispiel auf eine gelockte Datei zugreifen will, erhält eine Fehlermeldung, oder die Funktion zum Öffnen der Datei wartet eine Weile. Erst wenn der aktuelle Prozess sie wieder freigibt, kehrt die Funktion in das Programm zurück und der nächste darf die Datei öffnen.
Locks lösen so unter anderem das Problem der gleichzeitig ankommenden E-Mails: Der LDA mit der ersten E-Mail sperrt die Mailbox. Der zweite LDA erhält eine Fehlermeldung beim Öffnen, wartet ein Weilchen und versucht es später noch einmal. Ist die erste Mail komplett ausgeliefert, die Mailbox sicher geschlossen und das Lock entfernt, flattert die zweite Nachricht an.
Mit Datei-Locks ist man aber gleich wieder neuen Problemen ausgeliefert. Eines der kleinsten ist die Tatsache, dass sie die Reihenfolge von scheinbar offensichtlichen Abläufen durcheinander bringen. Folgendes Szenario verdeutlicht die Bredouille: Der LDA stellt eine E-Mail zu und hat die Mailbox gelockt, ein zweiter Prozess wartet auf die Freigabe der Datei, um eine zweite E-Mail zuzustellen. Just in dem Moment, in dem der LDA die Mailbox wieder freigibt, trudelt eine dritte E-Mail ein und der dritte Prozess lockt die Datei. Der zweite Prozess muss sich wieder hinten anstellen. Eine klassische Race Condition.
Ein gravierenderes Problem sind Stale Locks, wörtlich übersetzt also abgestandene oder veraltete Locks. Sie entstehen, wenn ein Prozess seine Dateien nicht ordnungsgemäß freigibt, weil er abgestürzt ist oder ein Benutzer ihn mit dem »kill«-Kommando abgeschossen hat.