\ucsChapter{Listener/Notifier-Mechanismus}

\section{Einleitung}


Die aktiven Univention Directory Listener stehen in permanenter Verbindung zum
Univention Directory Notifier. Registriert der Univention Directory Notifier eine neue
Transaktions-ID, übermittelt er diese zusammen mit dem DN des Objekts
und der Änderungsart. Da der Univention Directory Notifier Kenntnis über den Zustand
der Univention Directory Listener-Dienste hat, kann er unterscheiden, welcher
Univention Directory Listener informiert werden muss 

Der Listener/Notifier-Mechanismus arbeitet transaktionsbasiert. Ein
Univention Directory Listener, der mehrere Transaktionen verpasst hat - weil zum
Beispiel der Rechner ausgeschaltet war - kann vom Univention Directory Notifier alle
fehlenden Transaktionen abfragen. Sobald der Univention Directory Listener eine
Verbindung zum Notifier aufgebaut hat, informiert der Univention Directory Listener
den Univention Directory Notifier über seine höchste Transaktions-ID. Der
Univention Directory Listener erhält vom Univention Directory Notifier die nächste
Transaktions-ID, meldet diese dem Notifier und
bekommt so lange vom Univention Directory Notifier die nächsthöhere Transaktions-ID,
bis er auf dem neuesten Stand ist.

Mit jeder UCS-Systemrolle außer Thin Clients und Basissystemen
wird der Univention Directory Listener installiert. Er hat die Aufgabe, nach Erhalt
einer neuen Transaktion vom Univention Directory Notifier das Objekt dieser
Transaktion aus dem LDAP-Server auszulesen. Im Gegensatz zum
Univention Directory Notifier speichert der Univention Directory Listener nur die letzte
verarbeitete Transaktions-ID. Dabei besitzt der Univention Directory Listener selbst
keine Programmlogik, die auf Grundlage der Attribute eines Objektes
Aktionen ausführen kann. Diesen Teil übernehmen die Listener-Module.

Listener-Module sind Erweiterungen des Univention Directory Listeners, die mit
UCS-Komponenten installiert werden. Bei diesen Modulen handelt es sich um
Programme, welche die Verarbeitung der veränderten Objekte aus dem
LDAP-Server ausführen. 

Der Aufbau aller Listener-Module ist identisch. Jedes Listener-Modul
enthält einen Suchfilter, mit dem anhand der Attribute überprüft wird,
ob das aktuelle Objekt behandelt werden soll. Die Programmlogik
unterscheidet drei Fälle: das Objekt ist neu, das Objekt wurde
verändert, das Objekt wurde gelöscht.



\section{Fehleranalyse}
\subsection{Log-Datei des Univention Directory Listeners}
Die Log-Datei des
Univention Directory Listeners \ucsURL{/var/log/univention/listener.log} ist von
zentraler Bedeutung bei der Fehleranalyse im 
Listener/Notifier-Mechanismus. Sowohl der Listener-Dienst selbst, als
auch die Listener-Module schreiben Statusmeldungen in diese Datei.
Diese beziehen sich überwiegend auf
Starten und Stoppen des Dienstes, Verbindungen zum Notifier und
Initialisierungen der Listener-Module. Von den Listener-Modulen werden
Meldungen innerhalb der Programmlogik erzeugt. Jede Meldung ist in
eine von fünf Kategorien eingeordnet. Die Kategorien sind \emph{ERROR},
\emph{WARN}, \emph{NOTIFICATION}, \emph{INFO} und \emph{DEBUG}. Sie entsprechen jeweils
einem Debug-Level, der über die \ucsUCR{-Variable}
\ucsCommand{\ucsBCindex{listener/debug/level}} auf Werte von \emph{0} (nur Meldungen der Kategorie
\emph{ERROR}) bis \emph{4} (Meldungen aller Kategorien) eingestellt wird. Für
die Fehleranalyse kann es hilfreich sein, den Debug-Level
vorübergehend zu erhöhen. Nachdem der Debug-Level geändert wurde, muss der
Univention Directory Listener neu gestartet werden.

\subsection{Vergleich der Transaktions-IDs}
Im Standard-Betrieb der Domänen-Replikation (keine hohe Last
auf den Systemen, keine Störungen im Netzwerk) ist die Verzögerung
zwischen der Änderung in \ucsUDM{} bis zur Änderung auf dem
Listener-System kaum merkbar. Innerhalb einiger Sekunden können mehrere
Transaktionen vom Listener durchgeführt werden. Werden auf einem
Listener-System Auffälligkeiten beobachtet, die mit dem
Listener/Notifier-Mechanismus in Zusammenhang stehen könnten, kann der
Vergleich der Transaktions-IDs von Listener- und Notifier-Dienst einen
ersten Hinweis liefern.

Auf dem Domänencontroller Master werden die vom Notifier-Dienst
registrierten Transaktionen in aufsteigender Reihenfolge in die
Datei \ucsURL{/var/lib/univention-ldap/notify/transaction}
geschrieben:

\begin{ucsConfigFile}
root@dcmaster:~# tail -1 /var/lib/univention-ldap/notify/transaction
836 cn=dcslave3,cn=dc,cn=computers,dc=firma,dc=de m
root@dcmaster:~# 
\end{ucsConfigFile}

Auf dem Listener-System wird die zuletzt vom Listener empfangene
Transaktion in der Datei \ucsURL{/var/lib/univention-directory-listener/notifier_id}
gespeichert:

\begin{ucsConfigFile}
root@dcslave1:~# cat /var/lib/univention-directory-listener/notifier_id
836
root@dcslave1:~# 
\end{ucsConfigFile}
Weichen die Transaktions-IDs voneinander ab, kann das Problem im
Umfeld des Listeners gesucht werden. Es können sich in der der
Log-Datei des Listener-Dienstes weitere auffällige Einträge finden,
z.B. \ucsMenuEntry{'connection to notifier was closed'}. Über das
Nagios-Plugin \ucsCommand{check\_univention\_replication} können ebenso
Replikationsauffälligkeiten sichtbar gemacht werden.

\subsection{Einspielen nicht replizierter Daten (failed.ldif)}
Die Replikation von Verzeichnisdienst-Inhalten erfolgt über den
Listener/Notifier-Mechanismus. Auf den UCS-Systemrollen
Domänencontroller Backup und Domänencontroller Slave wird mit dem Paket
\ucsName{univention-directory-replication} das Listener-Modul \ucsCommand{replication.py}
installiert. Alle Objekte werden über dieses Listener-Modul dem
lokalen Verzeichnisdienst hinzugefügt. Sollte der lokale LDAP-Server
nicht erreichbar sein, werden alle Objekte im LDIF-Format in eine
Datei geschrieben, um die Änderungen, wenn der LDAP-Server wieder
erreichbar ist, nachträglich einspielen zu können.

Ist der LDAP-Server für den Univention Directory Listener nicht erreichbar, wechselt er
nach mehreren erfolglosen Versuchen in den LDIF-Mode. In der Log-Datei
des Listeners (\ucsURL{/var/log/univention/listener.log}) findet sich ein
Eintrag mit Datum und der Meldung \emph{going into LDIF mode}. Die Datei
\ucsURL{/var/lib/univention-directory-replication/failed.ldif} wird angelegt und es
werden alle folgenden LDAP-Objekte in diese Datei geschrieben. Auch
wenn der lokale LDAP-Server während des Betriebs im LDIF-Modus wieder
erreichbar sein sollte, werden Veränderungen weiterhin in die Datei
\ucsCommand{failed.ldif} geschrieben. Die Replikation kann nur manuell wieder in
den normalen Betrieb überführt werden:

Dies kann entweder über den Neustart des LDAP-Servers,
\begin{ucsConfigFile}
/etc/init.d/slapd restart
\end{ucsConfigFile}
oder mit dem folgenden Befehl erreicht werden:
\begin{ucsConfigFile}
univention-directory-replication-resync \
  /var/lib/univention-directory-replication/failed.ldif
\end{ucsConfigFile}
Durch den Befehl wird vorübergehend der Listener-Dienst angehalten, um weitere
Schreibvorgänge in die Datei \ucsCommand{failed.ldif} zu verhindern. Die
gespeicherten LDAP-Objekte werden dem LDAP-Server nacheinander hinzugefügt.
War die Übernahme erfolgreich, wird die Datei \ucsCommand{failed.ldif}
gelöscht und der Listener-Dienst erneut gestartet.

Sollten einzelne Objekte z.B. bei ausgebliebener Schema-Replikation
oder bei bereits existierenden Objekten nicht eingespielt werden
können, werden diese wiederum in eine LDIF-Datei unterhalb des
\ucsURL{/tmp}-Verzeichnisses geschrieben. In diese Datei werden auch Meldungen
geschrieben, die Hinweise auf den Grund für die Ablehnung durch den
LDAP-Server geben. Der Pfad zur Datei wird von
\ucsCommand{univention-directory-replication-resync} ausgegeben. Nach Prüfung der
einzelnen gespeicherten Objekte und entsprechenden Korrekturen
können die ausstehenden Objekte über das Kommando \ucsCommand{ldapmodify} wieder
eingespielt werden.

\subsection{Re-Initialisieren der Listener-Module}
Falls es zu Problemen bei der Abarbeitung eines Listener-Moduls gekommen ist,
so besteht die Möglichkeit, das Listener-Modul neu zu initialisieren. Dabei
werden alle Objekte, auf die der Filter des Listener-Modul passt, als neue
Objekte übergeben.

Dem Befehl zum erneuten Initialisieren muss der Name des Listener-Moduls
übergeben werden. Die Namen aller installierten Listener-Module sind im
Verzeichnis \ucsURL{/var/lib/univention-directory-listener/handlers/system} zu finden.

Mit dem folgenden Befehl kann beispielsweise das Druckermodul neu
initialisiert werden:
\begin{ucsConfigFile}
univention-directory-listener-ctrl resync cups-printers
\end{ucsConfigFile}
