Bug 22416 - Failover entfernt alte Desktopzuweisung und führt zu doppelten Instanzen
Summary: Failover entfernt alte Desktopzuweisung und führt zu doppelten Instanzen
Status: CLOSED FIXED
Alias: None
Product: Z_UCS DVS
Classification: Unclassified
Component: DVS Sessions
Version: UCS DVS 1.0
Hardware: Other Linux
: P5 normal
Target Milestone: UCS DVS 1.0
Assignee: Philipp Hahn
QA Contact: Felix Botner
URL:
Keywords:
Depends on: 22677
Blocks:
  Show dependency treegraph
 
Reported: 2011-05-05 11:58 CEST by Tim Petersen
Modified: 2023-03-25 06:53 CET (History)
4 users (show)

See Also:
What kind of report is it?: ---
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Customer ID:
Max CVSS v3 score:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tim Petersen univentionstaff 2011-05-05 11:58:13 CEST
Im Falle eines erfolgreichen Failover wird die entsprechende Desktop-Instanz auf einem verfügbaren Node neu definiert und gestartet.
Die Zuordnung am Benutzer wird in diesem Fall auf den neuen Node aktualisiert.

Dies führt in der Folge dazu, dass bei Wiedererreichbarkeit des zuvor gecrashten Nodes zwei gleichnamige Desktop-Instanzen mit gleichen Netzwerkeinstellungen existieren, wobei die "Ausgangs-Instanz" des gecrashed Nodes nicht mehr über den User im DVS-Desktops Modul sichtbar ist.

Es wäre hier vermutlich hilfreich, wenn die alte Zuweisung (deprecated?) mit entsprechendem Status weiterhin einsehbar wäre - so hätte man einfach die Möglichkeit, die "alte" Instanz zu löschen.
Comment 1 Tim Petersen univentionstaff 2011-05-05 13:59:13 CEST
Desweiteren ist aufgefallen, dass die "alte" Intanz weiterhin am LDAP-Objekt gespeichert ist -> univentionDVSUuid wird beim Failover nicht angepasst.

Das führt scheinbar dazu, dass bei Wiedererreichbarkeit des Nodes und erneuter Anmeldung am Desktop, wieder die "alte", als deprecated gemarkte Sitzung gestartet wird.
Comment 2 Tim Petersen univentionstaff 2011-05-06 09:51:49 CEST
Das Problem ist an der Stelle vermutlich doch kritischer:
Je nachdem, wie ein Node ausfäällt, wird der Failover ja wie erwähnt dazu, führen, dass bei Wiedererreichbarkeit zwei gleiche Instanzen laufen.

Dies betrifft allerdings nicht nur die Netzwerkeinstellungen - beide Instanzen werden auch auf das gleiche Cloneimage schreiben - ich könnte mir vorstellen, dass so das Image zerstört wird.

Evt. sollte man im Falle eines Failover besser das Clone-Image in einen neuen Namen kopieren und das alte löschen?
Comment 3 Stefan Gohmann univentionstaff 2011-05-12 14:41:15 CEST
Ganz einfache Idee:

- im Failover wird die Instanz als zu löschen markiert

- beim Boot des Servers prüft dieser, ob im LDAP des Masters markiert ist, dass diese Instanz gelöscht werden soll

- zusätzlich wird dies per Listener Modul geprüft
Comment 4 Arvid Requate univentionstaff 2011-05-24 20:19:09 CEST
Das Quellpaket univention-virtual-machine-manager-schema definiert jetzt ein weiteres LDAP-Attribut univentionVirtualMachineReplacedBy, das an Objekten der Klasse univentionVirtualMachine erlaubt ist. Dieses neue LDAP-Attribut wird im UDM Modul uvmm/info als UDM property 'replacedby' verfügbar gemacht.

Bei Failover einer DVS-Instanz auf einen anderen DVS-Node notiert der univention-dvs-sessionbroker jetzt die neue UUID der DVS-Instanz an dem "alten" univentionVirtualMachine Objekt und legt außerdem ein neues an.

Das Paket univention-dvs-node bring zusätzlich das Listener Modul dvs-suspend-replaced-vm mit, das virsh managedsave aufruft, falls univentionVirtualMachineReplacedBy an einem univentionVirtualMachine objekt auftaucht und die alte UUID auf dem lokalen System definiert ist.
Comment 5 Stefan Gohmann univentionstaff 2011-06-01 06:31:12 CEST
Es gibt jetzt den ungünstigen Fall, dass eine neue Instanz bei einem kurzfristigen Netzwerkausfall angelegt wird und dann ggf. zwei Nodes auf das NFS-Image schreiben, sobald das Netzwerkproblem behoben ist. Das führt zu schwerwiegenden Fehlern innerhalb der Instanz.

Wenn es zu einem Nodeausfall kommt (Totalausfall oder temporäres Netzwerkproblem), sich dann ein Benutzer anmeldet und die VM eigentlich auf dem Node läuft, dann sollte von dem Image eine Kopie erstellt werden und dann auf einem neuen Node gestartet werden. Sobald der alte Node wieder am Netz ist, kann dieser das alte Image und die Einstellungen des virtuellen Desktops löschen. Sollte der Node nur ein temporäres Problem haben und dann noch Änderungen in das Image schreiben, so sollte das die Kopie nicht berühren. Sollte der alte Node wieder kommen, während der Kopievorgang noch läuft, so kann auf dem alten Image weitergearbeitet werden.

Da das Kopieren einige Zeit dauern kann, muss dem Benutzer eine Meldung angezeigt werden. In der Meldung sollte stehen, dass der Node ausgefallen ist und dass nun eine Kopie der Desktop Instanz angelegt wird, damit verhindert wird, dass die Desktop Instanz kaputt geht.

Wenn ein Node ganz normal heruntergefahren wird und sich dann ein Benutzer anmeldet, dann sollte diese Kopie nicht erstellt werden, da es in diesem Fall reicht die Instanz auf einem anderen Rechner zu starten. Demnach müssten die Nodes sich beim Session Broker abmelden.
Comment 6 Philipp Hahn univentionstaff 2011-06-09 14:45:26 CEST
1. Nodes setzen nun beim Herunterfahren im LDAP das Attribute univentionDvsNodeAvailable=FALSE und nach dem Starten auf TRUE.

2. Das Attribut wird beim berechnen des Ausweichhosts ("determination") berücksichtigt

3. Das Protokoll zwischen SB und SBC trennt nun zwischen /select und /alive und ermöglicht das Übertragen von Status-Updates während dem /select

svn24811, univention-dvs_4.0.26-1.54.201106091427
svn24812, univention-dvs-common_2.0.24-1.35.201106091428
svn24814, univention-dvs-node_2.0.29-3.85.201106091428
svn24810, univention-dvs-sessionbroker_1.0.148-1.193.201106091429
Comment 7 Philipp Hahn univentionstaff 2011-06-10 21:46:08 CEST
> TODO A: Failover
> 
>  0. Der Sessionbroker überprüft den Zustand, der unten in "TODO C: Reboot von 
DVS-Nodes#2 beschrieben ist. Falls der DVS-Node A sauber ausgeschaltet ist, geht er direkt zu Punkt 4. weiter.

Wenn der Knoten im LDAP dvs-available=FALSE ist, werden keine Images kopiert

> 1. Das Image, das in der XML-Beschreibung notiert ist muss auf dem Storage kopiert werden (im Pfad UCR:dvs/desktop/directory)

Das Image wird im selben Verzeichnis belassen.

>   * Ein neuer, eindeutiger Dateiname  muss dafür verwendet werden, z.B. durch anhängen einer Zahl, analog zur _unique_computername Funktion in univention-dvs-create-desktop

Die letzte Zahl wird solange erhöht, bis der Name eindeutig ist.

>    * Das eigentliche kopieren der Datei würde dann vermutlich der 
> Sessionbroker selbst übernehmen (anders als bei univention-dvs-create-desktop, was ja auch dem DVS-Node ausgeführt wird).

Der SB forked ein "cp -p" und beobachtet per stat() den Fortschritt.

>  2. Dann sollte der SB erneut prüfen, ob DVS-Node A nicht wieder erreichbar ist. Damit man darauf schnell reagieren kann, ohne auf Abschluss des Kopiervorgangs zu warten, ist es vermutlich sinnvoll entweder diese Überprüfung oder den Kopiervorgang selbst in einem separaten Thread zu starten. und

Nach jeder Image-Datei wird per libvirt erneut probiert, die Domain zu starten. Wenn das klappt, werden die kopierten Images gelöscht und die ganze Prozedur erneut aufgerufen.
 
>   * Nach starten des Kopiervorgangs dem Benutzer feedback zum DVS-Node-
Problem geben

Wird per Long-Term-HTTP als status=100 mit %-Fortschritt angezeigt.

>  * Danach regelmässig prüfen ob DVS-Node A wieder verfügbar ist

s.o.

> 3.a) Falls der DVS-Node A wieder erreichbar ist, sollte die VM normal in Zustand START versetzt werden (wie sonst auch), der Kopiervorgang abgebrochen werden und das gerade kopierte Fallback-Image wieder gelöscht werden. Dann muss dem Client normal die Info zu seinem Desktop übergeben werden, damit er rdp/x2go starten kann. Ende.

Das sollte jetzt so sein.

> 3.b) Falls der DVS-Node A weiterhin nicht erreichbar ist, muss der alte Pfad muss in der XML-Beschreibung durch den neuen Pfad ersetzt werden

Aus der XML-Beschreibung wird die UUID gelöscht und die neuen Pfade eingetragen.

> 4. das XML  muss an DVS-Node B zum Starten der VM übergeben werden, die neue UUID notiert werden etc. (dieser Code ist schon da)

wurde so auch übernommen.

> 5. das alte Image sollte dann gelöscht werden (DVS-Node A hat die Datei zwar ggf. noch offen, aber die Datei kann vermutlich trotzdem schon entfernt werden.) 

Falls bis zum Ende der Kopieraktion Knoten A nicht reagiert, werden die altem Images gelöscht.

> Falls DVS-Node A einen temporären Netzwerkausfall hatte, dann wird der Listener kurze Zeit später sehen, dass die Maschine suspended werden soll. Ggf. muss das ersetzt werden durch ein DESTROY/Ausschalten der VM. 

Das habe ich mir jetzt nicht explizit angeguckt, was mit einem revoverten A passiert.

> TODO B: Benutzerfeedback
> "Da das Kopieren einige Zeit dauern kann, muss dem Benutzer eine Meldung angezeigt werden. In der Meldung sollte stehen, dass der Node ausgefallen ist und dass nun eine Kopie der Desktop Instanz angelegt wird, damit verhindert wird, dass die Desktop Instanz kaputt geht."
>
>  * Der SB-Client muss eine Meldung zum DVS-Node-Ausfall verstehen können und eine entsprechende Meldung ausgeben können. Meiner Meinung nach, ist es sinnvoll dafür den PyQT-Code zu verwenden, der im SB-Client schon für die Windows-GUI drin ist. Dieser Funktioniert auch unter Linux (option --gui).
>
> * die i386 Pakete für pyQT und Abhängigkeiten muss von univention-thin-client-dvs mitgebracht werden (siehe univention-thin-client-download-debs in debian/rules).
>
>  * Das ermöglicht, dass man auch bei längerem Warten auf den Start (ohne DVS-Node-Ausfall) dem Benutzer ein Message-Box anzeigen kann (da gibt es schon einen Bug zu, der ist aber nicht mehr auf DVS 1.0 getaggt).

Macht SG an Bug #22677.

> TODO C: Reboot von DVS-Nodes
> "Wenn ein Node ganz normal heruntergefahren wird und sich dann ein Benutzer anmeldet, dann sollte diese Kopie nicht erstellt werden, da es in diesem Fall reicht die Instanz auf einem anderen Rechner zu starten. Demnach müssten die Nodes sich beim Session Broker abmelden."
>
>  * Ein rc*.d/K* Skript müsste dafür sorgen, dass dem SB signalisiert wird, dass der DVS-Node normal ausgeschaltet ist. Das kann entweder per HTTP-Kommunikation mit dem SB geschehen oder noch besser durch setzen eines LDAP-Attributs

u-d-node bringt nun das init-Skript /etc/init.d/univention-dvs-node mit, das bei start und stop das dvs-available-Attribut am Host selber setzt.
Hier ist nochmal zu testen, was passiert, wenn das Netz nicht verfügbar ist.

> * Der SB muss auf dieses Signal prüfen, bevor er direkt mit Punkt 4. aus TODO A (Failover) loslegt. (siehe oben).

Der SB wertet das Flag aus, setzt es aber nicht selbständig falls er erkennt, das was mit dem Host nicht stimmt.

svn24847, univention-dvs-common_2.0.25-1.36.201106102129
svn24848, univention-dvs-sessionbroker_1.0.150-1.196.201106102131

Zum Testen: Den Failover-Fall kann man leicht horvorrufen, wenn man per "virsh destroy $VM" und "virsh undefine $VM" einfach lokal auf dem Host die VM entfernt. Dann wird sie weder von UVMM noch von libvirt gefunden und beim nächsten Aufruf vom SB neu angelegt.
Comment 8 Philipp Hahn univentionstaff 2011-06-17 13:24:45 CEST
s/SBERetry/SBRetry/

svn24956, svn24957, univention-dvs-sessionbroker_1.0.166-2.228.201106171254
Comment 9 Felix Botner univentionstaff 2011-06-17 17:13:05 CEST
Das starten einer Instanz wenn der Original DVS Node ordentlich runtergefahren wurde, klappt noch nicht. 

</domain>
2011-06-17 17:09:42,312 - SessionBroker - INFO - cc929b00-98f3-11e0-a012-5254005c4f99: New instance faac1924-1cd9-d395-5f18-ff690a21af96
2011-06-17 17:09:42,782 - SessionBroker - DEBUG - Deprecating domain 71735605-12ae-c430-801e-44887aec9646 in instance cache.
2011-06-17 17:09:42,803 - SessionBroker - DEBUG - Saving definition for new domain faac1924-1cd9-d395-5f18-ff690a21af96 in dvsdb...
2011-06-17 17:09:42,829 - SessionBroker - DEBUG - Storing new uuid faac1924-1cd9-d395-5f18-ff690a21af96 in UDM.
2011-06-17 17:09:42,861 - SessionBroker - ERROR - cc929b00-98f3-11e0-a012-5254005c4f99: starting 71735605-12ae-c430-801e-44887aec9646 fallback on qemu://xen15.dvs10pt.local/system failed: local variable 'images' referenced before assignment
Traceback (most recent call last):
  File "/usr/sbin/univention-dvs-sessionbroker", line 731, in _next
    for src, dest, stat in images:
UnboundLocalError: local variable 'images' referenced before assignment
2011-06-17 17:09:42,871 - SessionBroker - ERROR - ERROR: Failed to start instance 71735605-12ae-c430-801e-44887aec9646 for session cc929b00-98f3-11e0-a012-5254005c4f99.
Traceback (most recent call last):
  File "/usr/sbin/univention-dvs-sessionbroker", line 757, in _next
    raise SBException("ERROR: Failed to start instance %s for session %s." % (instance_uuid, self.session_id))
SBException: ERROR: Failed to start instance 71735605-12ae-c430-801e-44887aec9646 for session cc929b00-98f3-11e0-a012-5254005c4f99.
2011-06-17 17:10:11,876 - SessionBroker - INFO - Looking up DVS Node for host felix-vm.
2011-06-17 17:10:11,885 - SessionBroker - INFO - Pausing host felix-vm on DVS Node qemu://xen15.dvs10pt.local/syste
Comment 10 Philipp Hahn univentionstaff 2011-06-17 17:58:09 CEST
images wird nun schon früher gesetzt, so daß es auch im Fall einer Ausnahme definiert ist.

svn24979, univention-dvs-sessionbroker_1.0.170-1.232.201106171755
Comment 11 Stefan Gohmann univentionstaff 2011-06-20 22:51:54 CEST
Nach sehr viel Debug konnten Arvid und ich folgendes feststellen:

Teilweise läuft der Failover problemlos durch. Zwingend erforderlich ist, dass der UVMMd die Nodes richtig erkennt. Wenn nur zwei Nodes vorhanden sind und die Nodes immer wieder abwechselnd verfügbar sind, so kommt der UVMMd nicht nach.

Wenn der Client jetzt eine Verbindung aufbauen will und der Node gerade ausgefallen ist, so ist der Node per UVMM noch erreichbar. Der Session Broker versucht die Instanz zu starten und bleibt hier stehen:

 uvmmd.set_state(node_uri, instance_uuid, 'RUN') # in function _next

Dadurch wird auch der UVMMd blockiert und er aktualisiert seine Node-Informationen nicht mehr.

Im netstat sieht man die Verbindung vom uvmmd zum libvirtd auf dem Node
tcp        0    900 10.201.165.2:39313      10.201.165.15:16514     VERBUNDEN   31287/python2.4

Nach ca. 5 Minuten geht es dann doch weiter: Allerdings hat der Client dann schon ein Read Error bekommen.

Der UVMMd sollte auf jeden Fall nicht so lange blockieren. Ggf. können wir im SessionBroker den Timeout für diese Anfrage verkürzen?

http://stackoverflow.com/questions/675130/tls-connection-with-timeouts-and-a-few-other-difficulties
Comment 12 Stefan Gohmann univentionstaff 2011-06-21 06:47:28 CEST
Durch den implementierten Timeout funktioniert der Failover bei mir jetzt zuverlässig. 

Ich glaube es kann Situationen geben, in denen der Suspend mit dem Failover in Konflikt gerät, deshalb sollte der Idletimeout auf einen Wert > 1 Minute gesetzt werden. Ich denke das ist aber eh sinnvoll, damit längere  Wartezeiten bei der Anmeldung vermieden werden.

@Moritz, bitte im Handbuch auf einen sinnvollen Wertebereich für den Idletimeout hinweisen.
Comment 13 Moritz Muehlenhoff univentionstaff 2011-06-21 10:08:56 CEST
(In reply to comment #12)
> Durch den implementierten Timeout funktioniert der Failover bei mir jetzt
> zuverlässig. 
> 
> Ich glaube es kann Situationen geben, in denen der Suspend mit dem Failover in
> Konflikt gerät, deshalb sollte der Idletimeout auf einen Wert > 1 Minute
> gesetzt werden. Ich denke das ist aber eh sinnvoll, damit längere  Wartezeiten
> bei der Anmeldung vermieden werden.
> 
> @Moritz, bitte im Handbuch auf einen sinnvollen Wertebereich für den
> Idletimeout hinweisen.

Wurde in Revision 9134 integriert und von Arvid QAt.
Comment 14 Felix Botner univentionstaff 2011-06-21 11:36:37 CEST
Ausfall eines Nodes (Kabel gezogen):
   * Image wird kopiert (altes Image wird gelöscht)
   * neue Instanz wird auf verfügbarem Node angelegt und gestartet
   * replacedby wird am UVMM Info Objekt der alten Instanz gesetzt
   * ist der ausgefallene Rechner wieder verfügbar, wird die alte Instanz gelöscht

Temporärer Netzwerkausfall:
   * Nach dem Kopieren des Image wird das neue Image mit dem alten verglichen,
     gibt es Unterschiede (wenn zwischenzeitlich die Instanz auf dem 
     ausgefallenem Rechner wieder auf die Platte schreiben konnte) wird das
     neue Image gelöscht und die alte Instanz gestartet

Rechner herunterfahren:
   * IsAvailable wird am DVS Node entsprechend gesetzt
   * wird eine Session gestartet, die auf einem ordentlich ausgeschalteten 
     Rechner lief, wird auf einem verfügbarem Node eine neue Instanz erzeugt, 
     das Image wird aber nicht kopiert
   * Die Instanz auf dem ausgeschalteten Rechner wird beim starten entfernt
Comment 15 Philipp Hahn univentionstaff 2011-08-19 11:13:59 CEST
(In reply to comment #5)
> Es gibt jetzt den ungünstigen Fall, dass eine neue Instanz bei einem
> kurzfristigen Netzwerkausfall angelegt wird und dann ggf. zwei Nodes auf das
> NFS-Image schreiben, sobald das Netzwerkproblem behoben ist. Das führt zu
> schwerwiegenden Fehlern innerhalb der Instanz.

libvirt und qemu scheinen (inzwischen?) eigenen Mechanismus gegen die Doppelbenutzung zu haben:
<http://libvirt.org/locking.html>
<https://fedorahosted.org/sanlock/>