[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: File-Locking in Shellscripten auf NFS


Hi Raphael,

Am 08.12.2010 um 21:19 Uhr schrieb Raphael Eiselstein <rabe@xxxxxxxxx>:
> fuer manche Anwendungsfaelle moechte man z.B. vermeiden, dass ein Script
> mehrfach parallel ausgefuehrt wird, etwa per cron, wenn die Ausfuehrung
> aus irgendwelchen Gruenden laenger dauert als die Periode in cron
> eingestellt ist.

dafuer ist auch manchmal "lockfile" geeignet, was bei mir in dem 
Paket "procmail" dabei ist.


> Der IMHO uebliche weg ist ein PID-File zu schreiben, welches die
> Prozess-ID des laufenden Prozesses enthaelt. Wird das Script (oder
> Programm) dann parallel nochmal gestartet, kann man anhand des
> vorhandenen PID-Files bzw. nach Ueberpruefung der darin enthaltenen PID
> herausfinden, ob eine weitere Instanz bereits laeuft und entsprechend
> darauf reagieren, zB nicht nochmal neu starten.

Das ist natuerlich der Koenigsweg auf EINEM System.


> Wie wuerde man so ewtas implementieren, wenn es mehrere Systeme gibt, die
> ein bestimmtes Programm periodisch ausfuehren aber sichergestellt werden
> soll, dass immer nur eins gleichzeitig ausgefuehrt wird?

Evtl. sind hierbei PID-Files nichtmehr geeigent, da ja mehrere Systeme daran 
beteiligt sind. Ohne die anderen Systeme "fragen" zu muessen sehe ich nur eine 
Moeglichkeit:
Waehrend "Programm" laeuft das PID-File bzw. Lock-File regelmaessig zu 
aktualisieren (touch file) und anhand vom timstamp der Datei entscheiden 
ob "Programm" noch laeuft oder nicht.


> Man koennte hier zwar auch ein PID-File auf ein gemeinsames NFS-Volume
> schreiben. Das liesse sich dann aber nicht pruefen, d.h. ein vorhandenes
> PID-File allein genuegt nicht um zu ueberpruefen, ob die darin enthaltene
> Prozess-ID noch gueltig ist (der Prozess laeuft ja moeglicherweise auf
> einem fremden System).
> Kann man auf NFS eine Datei derart locken, dass der Lock entfernt wird,
> falls der "sperrende" Prozess abgestuerzt ist?

Soweit ich weiss geht das nicht.


> 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 waere, auf jedem der beteiligten Systeme einen
> unabhaengigen Cronjob zu haben, der alle PID-Files sucht und prueft, ob
> der entsprechende (lokale) Prozess noch aktiv ist.
> Dabei muesste im PID-File allerdings auch der Hostname enthalten sein,
> sonst wuerde der Garbage-Collector-Job auf Host A ein PID-File wegraeumen,
> welches von Host-B aus geschrieben wurde.

hier wuerde ich aber aufpassen, dass es nicht zu kompliziert wird. Wer soll 
soetwas betreuen? Wenn da mal etwas nicht wie erwartet funktioniert wird es 
schwierig herauszufinden wieso etwas nicht geht.


> Nachteil dieser Methode: stirbt das ganze System (zB Host B), wuerde das
> Lock-/PID-File auf dem NFS liegen bleiben und nicht weggeraeumt werden, da
> ja auch der Garbage Collector-Job nicht mehr laufen wuerde.
> Man koennte als Workaround^2 dafuer sorgen, dass alle Hosts sich
> gegenseitig den Garbage Collector Job ueberwachen. Dazu muesse der
> GC-Prozess auf jedem System ein Statusfile updaten und jeweils alle
> GC-Monitoring-Prozesse wuerden anhand des Dateialters herausfinden, wenn
> ein GC-Job laenger als erlaubt nicht mehr gelaufen ist und damit den
> jeweiligen Host fuer tot erklaeren und entsprechend auch alle PID-Files
> des fuer tot erklaerten Host automatisch wegraeumen.
> Diesen Workaround und Workaround^2 halte ich aber insgesamt fuer zu
> fragil als dass ich das als sinnvolle Loesung ansehen wuerde.
> Ein anderer Workaround waere, 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 koennten dann andere Hosts im Netz auch fremde PID-Files
> verifizieren und ggf. fuer ungueltig erklaeren.
> Das einzige, was in diesem Setup als "hochverfuegbar" angesehen werden
> kann ist der NFS-Server, alle NFS-Clients sind einfache Systeme die
> unabhaengig voneinander funktionieren muessen, d.h. es darf kein anderes
> "zentrales System" geben.
> Gibt es eine *einfache* Loesung basierend auf NFS?

Wie oben geschrieben wuerde ich das "Lock-File" auf dem nfs-Server 
waehrend "Programm" ausgefuehrt wird aktualisieren. In der Bash wuerde ich das 
wie folgt machen:

INTERVAL="10"
if [ -e /nfs/lockfile ] \
&& [ "$(($(date +%s)-2*$INTERVAL))" -gt "$(date -r /nfs/lockfile +%s)" ]
then
	echo "already running"
else
	touch /nfs/lockfile
	program &
	PID="$!"
	while [ -d "/proc/$PID" ]
	do
		touch /nfs/lockfile
		sleep $INTERVAL
	done
	wait $PID
fi


-- 
Gruss
                                                          \|/
       eMHa                                              (o o)
------------------------------------------------------oOO--U--OOo--
 Markus Hochholdinger
 e-mail  mailto:Markus@xxxxxxxxxxxxxxxxx             .oooO
 www     http://www.hochholdinger.net                (   )   Oooo.
------------------------------------------------------\ (----(   )-
Ich will die Welt veraendern,                           \_)    ) /
aber Gott gibt mir den Quelltext nicht!                      (_/



-- 
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/