AW: File-Locking in Shellscripten auf NFS

Autor: Johannes Walch <j.walch_at_nwe.de>
Datum: Wed, 8 Dec 2010 22:46:21 +0100
Hi Raphael,

warum nicht einen resource monitor wie heartbeat verwenden? Müsste man eventuell die helper scripts noch ein wenig anpassen, aber ansonsten sollte das klappen. Falls eine selbstgebaute Lösung zum Einsatz kommt kann man statt TCP service mit PID ausgabe auch SNMP verwenden. Da lassen sich alle Prozesse abfragen. Das führt aber bei N Systemen natürlich zu (N-1)^2! an Abfragen, kann also viel werden.

Johannes

-----Ursprüngliche Nachricht-----
Von: uugrn-bounces_at_uugrn.org [mailto:uugrn-bounces_at_uugrn.org] Im Auftrag von Raphael Eiselstein
Gesendet: Mittwoch, 8. Dezember 2010 21:19
An: UUGRN Mailingliste
Betreff: File-Locking in Shellscripten auf NFS

Hallo zusammen,

für manche Anwendungsfälle möchte man z.B. vermeiden, dass ein Script mehrfach parallel ausgeführt wird, etwa per cron, wenn die Ausführung aus irgendwelchen Gründen länger dauert als die Periode in cron eingestellt ist.

Der IMHO übliche weg ist ein PID-File zu schreiben, welches die Prozess-ID des laufenden Prozesses enthält. Wird das Script (oder
Programm) dann parallel nochmal gestartet, kann man anhand des vorhandenen PID-Files bzw. nach Überprüfung der darin enthaltenen PID herausfinden, ob eine weitere Instanz bereits läuft und entsprechend darauf reagieren, zB nicht nochmal neu starten.

Wie würde man so ewtas implementieren, wenn es mehrere Systeme gibt, die ein bestimmtes Programm periodisch ausführen aber sichergestellt werden soll, dass immer nur eins gleichzeitig ausgeführt wird?

Man könnte hier zwar auch ein PID-File auf ein gemeinsames NFS-Volume schreiben. Das ließe sich dann aber nicht prüfen, d.h. ein vorhandenes PID-File allein genügt nicht um zu überprüfen, ob die darin enthaltene Prozess-ID noch gültig ist (der Prozess läuft ja möglicherweise auf einem fremden System).

Kann man auf NFS eine Datei derart locken, dass der Lock entfernt wird, falls der "sperrende" Prozess abgestürzt ist?

Und wenn ja, wie implementiert man soetwas in einem Shellscript oder mit welchem Standardtool kann man das tun? Wie erkennt man nicht nur, dass ein anderer Prozess gestartet ist sondern dass diese PID auch noch aktiv ist?

Ein Workaround wäre, auf jedem der beteiligten Systeme einen unabhängigen Cronjob zu haben, der alle PID-Files sucht und prüft, ob der entsprechende (lokale) Prozess noch aktiv ist. 

Dabei müsste im PID-File allerdings auch der Hostname enthalten sein, sonst würde der Garbage-Collector-Job auf Host A ein PID-File wegräumen, welches von Host-B aus geschrieben wurde.

Nachteil dieser Methode: stirbt das ganze System (zB Host B), würde das Lock-/PID-File auf dem NFS liegen bleiben und nicht weggeräumt werden, da ja auch der Garbage Collector-Job nicht mehr laufen würde.

Man könnte als Workaround^2 dafür sorgen, dass alle Hosts sich gegenseitig den Garbage Collector Job überwachen. Dazu müsse der GC-Prozess auf jedem System ein Statusfile updaten und jeweils alle GC-Monitoring-Prozesse würden anhand des Dateialters herausfinden, wenn ein GC-Job länger als erlaubt nicht mehr gelaufen ist und damit den jeweiligen Host für tot erklären und entsprechend auch alle PID-Files des für tot erklärten Host automatisch wegräumen.

Diesen Workaround und Workaround^2 halte ich aber insgesamt für zu fragil als dass ich das als sinnvolle Lösung ansehen würde.

Ein anderer Workaround wäre, zB per xinetd einen Service anzubieten, der per einfachem TCP-Connect mit PID als Eingabe mit der Ausgabe "running", "stopped", ... den jeweilgen Prozess-Status (sofern vorhanden) ausgibt.
Damit könnten dann andere Hosts im Netz auch fremde PID-Files verifizieren und ggf. für ungültig erklären.

Das einzige, was in diesem Setup als "hochverfügbar" angesehen werden kann ist der NFS-Server, alle NFS-Clients sind einfache Systeme die unabhängig voneinander funktionieren müssen, d.h. es darf kein anderes "zentrales System" geben.

Gibt es eine *einfache* Lösung basierend auf NFS?

Danke und Gruß
Raphael

-- 
Raphael Eiselstein <rabe@uugrn.org>               http://rabe.uugrn.org/
xmpp:freibyterægmx.de  | https://www.xing.com/profile/Raphael_Eiselstein   
GnuPG:                E7B2 1D66 3AF2 EDC7 9828  6D7A 9CDA 3E7B 10CA 9F2D
.........|.........|.........|.........|.........|.........|.........|..
-- 
UUGRN e.V. http://www.uugrn.org/
http://mailman.uugrn.org/mailman/listinfo/uugrn
Wiki: https://wiki.uugrn.org/UUGRN:Mailingliste
Archiv: http://lists.uugrn.org/
Empfangen am 08.12.2010

Dieses Archiv wurde generiert von hypermail 2.2.0 : 08.12.2010 CET