Bug 15723 - Reader-Locking-Mechanismus für base.conf
Reader-Locking-Mechanismus für base.conf
Status: RESOLVED DUPLICATE of bug 15720
Product: UCS
Classification: Unclassified
Component: UCR
UCS 3.0
Other Linux
: P2 normal (vote)
: UCS 3.x
Assigned To: UCS maintainers
:
Depends on: 15518
Blocks:
  Show dependency treegraph
 
Reported: 2009-09-24 15:08 CEST by Sönke Schwardt-Krummrich
Modified: 2018-04-14 13:29 CEST (History)
4 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 3: Simply Wrong: The implementation doesn't match the docu
Who will be affected by this bug?: 1: Will affect a very few installed domains
How will those affected feel about the bug?: 4: A User would return the product
User Pain: 0.069
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:
hahn: Patch_Available+


Attachments
Fix UCR locking (21.64 KB, patch)
2012-11-15 08:58 CET, Philipp Hahn
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sönke Schwardt-Krummrich univentionstaff 2009-09-24 15:08:20 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.
Comment 1 Philipp Hahn univentionstaff 2012-11-14 17:59:58 CET
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.
Comment 2 Stefan Gohmann univentionstaff 2012-11-14 20:15:22 CET
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.
Comment 3 Philipp Hahn univentionstaff 2012-11-15 08:58:42 CET
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
Comment 4 Stefan Gohmann univentionstaff 2013-01-02 07:35:50 CET
(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.
Comment 5 Philipp Hahn univentionstaff 2013-01-10 08:53:29 CET
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.
Comment 6 Sönke Schwardt-Krummrich univentionstaff 2013-01-10 09:02:40 CET
(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.
Comment 7 Stefan Gohmann univentionstaff 2013-03-14 07:09:56 CET
(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.
Comment 8 Moritz Muehlenhoff univentionstaff 2013-05-31 10:43:33 CEST
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.
Comment 9 Daniel Tröder univentionstaff 2017-05-02 11:44:01 CEST

*** This bug has been marked as a duplicate of bug 15720 ***