Univention Bugzilla – Bug 15723
Reader-Locking-Mechanismus für base.conf
Last modified: 2018-04-14 13:29:13 CEST
+++ This bug was initially created as a clone of Bug #15518 +++ Beim gleichzeitigen Ausführen von "ucr set" Befehlen, kann die base.conf überschrieben werden, da kein Locking-Mechanismus implementiert ist. Das ist aktuell sehr massiv beim Thin Client Boot im OpenDVDI-Projekt aufgetreten, weil dort upstart für die parallele Ausführung von init-Skripten verwendet wurde. +++ cut +++ Der an Bug 15518 beschriebene Fix bezieht sich derzeit nur auf eine Racing-Condition zwischen mehreren Writern und stellt sicher, daß alle zu schreibenden Werte ohne Datenverlust in den base*.conf-Dateien landen. Es wird jedoch noch kein Locking bei den Lesern durchgeführt, so daß weiterhin dazu kommen kann, daß ein UCR-Prozess/-Python-Modul (Reader) genau in dem Moment die base.conf ausliest, während ein Writer die Datei gerade ge'truncate'd und ggf. erst wenige Bytes geschrieben hat. Der Reader hat dann nur eine unvollständige oder defekte Datei. Dieser Fall wird eher seltener Auftreten als die Writer-Racing-Condition und ist intern komplexer zu beheben, da es bei falschem Reader-Locking an diversen Stellen zu Deadlocks kommen kann.
Vermutlich erneut aufgetreten bei der Insstallation von UVMM: Dort hat das libvirt-acl-Listener-Module probiert uvmm/managers zu ändern; diese Änderung wurde aber vermutlich von einem anderen parallal laufenden anderen "ucr set" überschrieben bzw. hat der Listener seinen Stand von UCR gerade dann eingelesen, als die Datei geleert war. In /var/log/univention/confi-registry.replog sieht man zwar die "set"-Aufrufe, aber trotzdem war am Ende die Variable nicht gesetzt: root@xen1# grep uvmm/managers /var/log/univention/config-registry.replog 2012-11-14 11:50:52: set uvmm/managers=xen1.virtualisierung.univention.test 2012-11-14 12:10:14: set uvmm/managers=xen2.virtualisierung.univention.test root@xen1# ucr get uvmm/managers xen2.virtualisierung.univention.test root@xen2# grep uvmm/managers /var/log/univention/config-registry.replog 2012-11-14 12:10:12: set uvmm/managers=xen1.virtualisierung.univention.test 2012-11-14 12:10:14: set uvmm/managers='xen1.virtualisierung.univention.test xen2.virtualisierung.univention.test' root@xen2# ucr get uvmm/managers FYI: libvirt-acl verwendet direkt handler_set() und ruft kein externes "ucr set" auf. Vermutlich am besten wäre es backend.py#_ConfigRegistry.lock() backend.py#_ConfigRegistry.load() backend.py#_ConfigRegistry.unlock() backend.py#_ConfigRegistry.save() so anzupassen, daß anstatt eine zusätzliche .lock-Datei zu locken direkt die eigentliche base*.conf-Datei gelockt wird. Die folgenden Skripte rufen direkt ucr.save() auf, ohne ein entsprechendes Locking zu beachten: base/univention-system-setup/umc/python/setup/setup_script.py base/univention-ssl/univention-certificate-check-validity Der Patch ist in meinem Git-Repository: git --git-dir=/home/phahn/GIT/.git log -p remotes/svn/git-svn..ucs-3.1/ucr Ein kurzer Test war erfolgreich.
Ich glaube das Problem ist nicht so kritisch, dass es den Fix für interim-4 rechtfertigt. Da der errata Mechanismus für 3.1 aber deutlich einfacher ist, sollten wir ein entsprechendes Update dafür vorsehen.
Created attachment 4791 [details] Fix UCR locking Der Branch wurde umbenannt: git --git-dir=/home/phahn/GIT/.git log -p remotes/svn/git-svn..ucs-3.1/ucr-15723
(In reply to comment #3) > Created an attachment (id=4791) [details] > Fix UCR locking > > Der Branch wurde umbenannt: > git --git-dir=/home/phahn/GIT/.git log -p > remotes/svn/git-svn..ucs-3.1/ucr-15723 Die Punkte, die nicht direkt das UCR Paket betreffen sollten ausgelagert werden und zu UCS 3.1-1 behoben werden.
Nach Diskussion mit Stefan: - ucr.save() wird ab 3.1-1 deprecated und gibt nur noch eine Warnung aus. Begründung: - inherent unsicher mit nebenläufigen Änderungen - es werden keine Handler aufgerufen - Änderungen sofort bei ucr[key]=value bzw. del ucr[key] auszuführen würde die Performance vermutlich deutlich verschlechtern und kann ggf. negative Auswirkungen bei einigen Anwendungen hervorrufen, die zwar ucr[key] verändern, aber dann doch nicht ucr.save() aufrufen. - Der offizielle Weg ist dann nur noch ucr.handler_set([...]). Das wird entsprechens bis dahin in Univention-System-Setup und ggf. auch noch Univention-SSL angepasst. - ggf. wird es noch eine neue Methode für Transaktionen geben, die es erlaubt, set und unset innerhalb einer Transaktion zu kombinieren. (Bug #26819) - zukünftig wird UCR vermutlich irgendwann auf SQLite/BDB (Bug #15720) umstellen: Das wird zwar nicht das Locking vereinfachen, aber ggf. dann so Performant sein, daß man bei jeder Änderung am Python-ConfigRegistry-Objekt diese Änderung auch direkt persistent machen kann (Auto-Commit statt Transaktion) - wenn UCR ein Singleton wäre, könnte dann auch das load() deprecated werden.
(In reply to comment #5) > - ggf. wird es noch eine neue Methode für Transaktionen geben, die es erlaubt, > set und unset innerhalb einer Transaktion zu kombinieren. (Bug #26819) Das ist vor allem für Situationen interessant, wo viele UCR-Variablen gleichzeitig geändert/gesetzt und entfernt werden sollen (Repository-Konfiguration) und jede Änderung sehr ressourcen-/zeitintensive Folgen hat (Erstellung der sources.list.d-Dateien). > - wenn UCR ein Singleton wäre, könnte dann auch das load() deprecated werden. Das Umzusetzen halte ich gerade für gefährlich, weil z.B. einige Listener-Modulen sich darauf verlassen haben, dass sich der Zustand "ihrer" UCR-Instanz nur dann ändert, wenn sie es auch selbst triggern.
(In reply to comment #5) > Nach Diskussion mit Stefan: > - ucr.save() wird ab 3.1-1 deprecated und gibt nur noch eine Warnung aus. Kann auch mit UCS 3.1-2 erfolgen.
We will not ship a UCS 3.1-2 release; the next UCS release will be UCS 3.2. As such, this bug is moved to the new target milestone.
*** This bug has been marked as a duplicate of bug 15720 ***