Diplomarbeit LDAP UBIK - core.ac.uk · Diplomarbeit LDAP UBIK Verfasser: Alexander Merzky Matrikel:...

106
Diplomarbeit LDAP UBIK Verfasser: Alexander Merzky Matrikel: 20561 Email: [email protected] Fakult¨ at f¨ ur Informatik Professur Rechnernetze und verteilte Systeme Betreuer: Dipl.-Inf. Chris H¨ ubsch eingereicht am: 10.4.2005

Transcript of Diplomarbeit LDAP UBIK - core.ac.uk · Diplomarbeit LDAP UBIK Verfasser: Alexander Merzky Matrikel:...

Diplomarbeit

LDAP UBIK

Verfasser: Alexander MerzkyMatrikel: 20561

Email: [email protected]

Fakultat fur Informatik

Professur Rechnernetze und verteilte Systeme

Betreuer: Dipl.-Inf. Chris Hubsch

eingereicht am: 10.4.2005

Inhaltsverzeichnis

1 Einleitung 61.1 Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 Grundlagen 72.1 LDAP - Lightweight Directory Access Protocol . . . . . . . . . . . . . . . . . . . . 7

2.1.1 Einfuhrung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.1.2 Das LDAP-Protokoll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.1.3 Das LDAP-Datenmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.1.4 Einsatzszenarien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.2 Replikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.2.1 Einfuhrung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.2.2 Multi-Master-Replikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.2.3 Single-Master-Replikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.2.4 Die Failover-Konstellation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.2.5 Weitere Aspekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.2.6 Nachteile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 Anforderungen - Top-Down Entwurf 183.1 Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.1.1 Allgemeine Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.1.2 Anforderungen an den Replikationsmechanismus . . . . . . . . . . . . . . . 18

3.2 Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4 Replikationsmodelle - Bottom-Up Entwurf 204.1 Vorhandene LDAP-Replikationsmethoden . . . . . . . . . . . . . . . . . . . . . . . 20

4.1.1 LDAP-slurpd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204.1.2 ixSync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.1.3 LDAP Sync-Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.2 Der UBIK-Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254.2.1 OpenAFS - UBIK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254.2.2 UBIK-Implementierung der Carnegie Mellon University . . . . . . . . . . . 26

4.3 Andere Modelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.3.1 Bayou . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.3.2 Oracle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.4 Replikationsmedium . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284.5 Eignung der Moglichkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

5 Untersuchung der Mechanismen und Modellentwurf 305.1 Bewertung und Wahl der Mechanismen . . . . . . . . . . . . . . . . . . . . . . . . 30

5.1.1 LDAP-slurpd / LDAP-sync . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.1.2 UBIK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

5.2 Modellentwurf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.2.1 Aufgabenverteilung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.2.2 Anpassung der Aktualitatskriterien . . . . . . . . . . . . . . . . . . . . . . . 335.2.3 Anpassung des VOTING-Mechanismus’ . . . . . . . . . . . . . . . . . . . . 365.2.4 Zustandsmapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395.2.5 Das Leseverbot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395.2.6 Berucksichtigung von Teilbaumreplikationen . . . . . . . . . . . . . . . . . . 40

5.2.7 Klientenbenachrichtigung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

6 Design und Implementierung 476.1 Grundlegende Anderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

6.1.1 Anderungen der CMUbik-Bibliothek . . . . . . . . . . . . . . . . . . . . . . 476.1.2 Anderungen / Erweiterungen des slapd . . . . . . . . . . . . . . . . . . . . 48

6.2 Das Kommunikationsmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506.2.1 Kommunikation zwischen slapd und lokalem UBIK . . . . . . . . . . . . . . 506.2.2 Kommunikation zwischen den UBIK-Instanzen . . . . . . . . . . . . . . . . 516.2.3 Das Prozessmodell und Interprozesskommunikation . . . . . . . . . . . . . . 52

6.3 Das Ablaufmodell anhand eines Szenarios . . . . . . . . . . . . . . . . . . . . . . . 546.3.1 Voraussetzungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546.3.2 Der Serverstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546.3.3 Die Masterwahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566.3.4 Klienteninteraktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576.3.5 Ein dritter Server tritt ein . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586.3.6 Ein Serverausfall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606.3.7 Teilbaumreplikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616.3.8 Der RefreshAndPersist-Modus . . . . . . . . . . . . . . . . . . . . . . . . . 626.3.9 Behandlung von ungunstigen Konstellationen . . . . . . . . . . . . . . . . . 63

6.4 Grenzfalle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646.4.1 Klientenaktionen wahrend des Quorum-Timeouts . . . . . . . . . . . . . . . 646.4.2 Updates und Ausfalle im RefreshOnly-Modus . . . . . . . . . . . . . . . . . 64

6.5 Einsatzszenarien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

7 Der Quelltext 657.1 UBIK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

7.1.1 Der ubik loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657.1.2 Die Funktion parse() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707.1.3 Fur die Wahl wichtige Funktionen . . . . . . . . . . . . . . . . . . . . . . . 74

7.2 Modifizierter slapd -Quelltext . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 837.2.1 Die Initialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 837.2.2 Der slapd daemon task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

7.3 Ubiksync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 857.3.1 Ubiksync get sync ctxcsn() . . . . . . . . . . . . . . . . . . . . . . . . . . . 857.3.2 Ubiksync change syncstate() . . . . . . . . . . . . . . . . . . . . . . . . . . 877.3.3 Ubiksync state set master() . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

8 Installation, Konfiguration und Test 938.1 Installation der Quellpakete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

8.1.1 BerkeleyDB 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938.1.2 SASL 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948.1.3 OpenLDAP mit ubiksync . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

8.2 Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948.2.1 Voraussetzung fur den Betrieb von ubiksync . . . . . . . . . . . . . . . . . . 948.2.2 Konfiguration des slapd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 948.2.3 Konfiguration von UBIK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968.2.4 Initialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

8.3 Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 988.3.1 Die Wahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

8.3.2 Eintritt eines nicht-aktuellen Servers . . . . . . . . . . . . . . . . . . . . . . 988.3.3 Ausfall des Masters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998.3.4 Ausfall eines Slaves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998.3.5 Teilbaumreplikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998.3.6 Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

9 Fazit 1009.1 Anforderungskonformitat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1009.2 Verbesserungs- / Optimierungsmoglichkeiten . . . . . . . . . . . . . . . . . . . . . 1029.3 Abschliessende Worte / Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

A Quellen 104

B Abbildungen 105

C Selbststandigkeitserklarung 106

Abkurzungen und Begriffe

Attribute Ein Datenelement, das in einem Entry untergebracht istBaseDN Wurzel des NC, SuffixCSN Change Sequence Number (Zeitstempel der letzten Anderung)ContextCSN CSN des NC’s eines LDAP-ServersCS Client-Server (Kommunikationsmodell zwischen Provider und Consumer)Ctxcsn ContextCSNDAP Directoryx Access ProtocolDIT Directory Information Tree (Naming Context)DN Distinguished Name (Absolute Pfadangabe im DIT)DNS Domain Name ServiceDSA Directory Service Agent (LDAP-Server, kann mehrere NC’s verwalten)DSE DSA specific EntryEntry Knoten oder Blatt im DITEntryCSN CSN eines einzelnen Entries im NC eines LDAP-ServersGPL GNU Public LicenceIMAP Internet Messaging Access ProtocolLAN Local Area NetworkLDAP Lightweight Directory Access ProtocolLDIF LDAP Data Interchange Format (Dateiformat fur Im-/Export von LDAP-Daten)Matching Rule Regel, in welcher Weise Attribute verglichen werdenMIB Management Information BaseNC Naming Context (Eindeutiger NS inklusive rootDN)NDS Netware Directory ServiceNIS Network Information ServiceNS Name Space (gesamter Teilbaum, der unter dem rootDN liegtOID Object ID (eindeutiger Identifikator fur eine Schemadefinition)P2P Peer To Peer (Kommunikationsmodell zwischen gleichberechtigten Hosts)Quorum Menge von Servern, die einen gemeinsamen Master wahlenRDN Relative Distinguished Name (relative Pfadangabe im DIT)Referral URL eines anderen LDAP-Servers, die dem Klienten zuruckgeliefert

wird, wenn der lokale Server die Anfrage nicht verarbeiten kannRootDSE Wurzel eines DITs (enthalt Informationen uber den Server)Schema Art der Definition von Entries, Attributen, MatchingRules

entsprechen DatentypenScope Suchtiefe im DITSlapd openLDAP ServerSlurpd openLDAP ReplikationsagentSuffix Wurzel des NCURL Uniform Resource LocatorsWAN Wide Area Network

1 Einleitung

1.1 Aufgabenstellung

Das Problem bei einigen verteilten Verzeichnissen, wie zum Beispiel bei OpenLDAP ist, dasses nur einen Masterserver gibt, auf dem Anderungsoperationen durchgefuhrt werden konnen.Auf die Replikaserver kann nur lesend zugegriffen werden. Diese Konstellation wird dann zumProblem, wenn der Masterserver aus irgendeinem Grund nicht erreichbar ist. Dann waren Schreib-operationen so lange nicht erlaubt, bis der Masterserver wieder in Betrieb ist oder ein andererServer dessen Aufgabe ubernimmt. Um die Administration dieser Dienste zu erleichtern, warees wunschenswert, den gesamten Serverpool als Einheit zu betrachten und den Servern selbstdie Verteilung der Daten zu uberlassen. Sie sollten also autonom die Anderungen verbreiten undbei Ausfallen selbststandig ihre Struktur optimal anpassen oder wiederherstellen. Im Rahmender Diplomarbeit sollen verschiedene Mechanismen auf deren Eignung untersucht werden. Dabeispielen Zuverlassigkeit, Leistung und Resourcenverbrauch im Zusammenspiel mit verschiedenenNutzungsszenarien eine zentrale Rolle. Weiterhin soll bei der Wahl des Mechanismus’ auf dieArt, den Umfang und die Haufigkeit der Anderungen Rucksicht genommen werden. Der furdiese Anspruche optimale Mechanismus soll als Modul fur den OpenLDAP Server sowie ggf. eineKlientenerweiterung implementiert werden und unter die GPL gestellt werden.

6

2 Grundlagen

2.1 LDAP - Lightweight Directory Access Protocol

2.1.1 Einfuhrung

LDAP ist eine vereinfachte Form des X.500 Directory Access Protocol. Es wird bisher grossten-teils benutzt, um z.B. ein Personenverzeichnis einer Einrichtung zu verwalten und dabei dieinnere Struktur der Organisation abzubilden. Wie der Name schon sagt, handelt es sich um einVerzeichnis-Zugriffs-Protokoll. Ein Verzeichnis kann als eine Art Datenbank verstanden werden,die aber so optimiert ist, dass Leseoperationen sehr viel weniger Rechenaufwand benotigen alsSchreiboperationen. Wie in einem Telefonbuch sind die enthaltenen Daten indexiert, sodassman bei der Suche nach einem bestimmten Eintrag durch Angabe des Indexes alle mit demIndex ubereinstimmenden Eintrage zuruckbekommt. Der Index in einem Telefonbuch ist zumBeispiel der Nachname, die Stadt, der Stadtteil u.s.w.. Auch ein Inhaltsverzeichnis einesBuches ist ein Beispiel fur einen Verzeichnisindex, genauso wie die Verzeichnisstruktur in einemComputerfilesystem. Abstrakt gesagt haben Verzeichnisse die Aufgabe, gesammeltes Wissenschnell zuganglich zu machen.Ein Entry (Verzeichniseintrag) besteht aus einem Distinguished Name (DN) und einer Anzahlvon Attributen mit zugehorigen Werten. Einen Distinguished Name kann man sich als Pfadan-gabe vorstellen. Um beim Beispiel Computerfilesystem zu bleiben, entspricht der DistinguishedName dem absoluten Pfad zu einer Datei, z.B. /home/user1/public-html/index.html. Wennman aber die Filesystemstruktur in LDAP ubertragen will, ist es wichtig zu wissen, dass inLDAP der most-specific-value (hier index.html) als erstes dargestellt wird. (cn=index.html,cn=public-html, cn=user1, cn=home) ware zum Beispiel ein DN fur o.g. Filesystempfad. Jedeseinzelne der 4 Elemente des DN ist ein Relative Distinguished Name (RDN). Das bedeutet,dass dieses Element einen Verzweigungsast im Verzeichnisbaum darstellt. Fur das Beispielkann das Verzeichnis /home/user1/ die Unteverzeichnisse public-html, PUBLIC, PRIVATE,mathe u.s.w. haben. Diese Unterverzeichnisse stellen im Verzeichnisbaum RDN’s ausgehend von/home/user1/ dar.Attribute sind Eigenschaften eines Eintrags. Das Verzeichnis mit dem DN (cn=public-html,cn=user1, cn=home) kann mit den Eigenschaften cn=public-html, owner=user1, group=bin,inode=1886846983 u.s.w. definiert werden. In einem Telefonbuch ware der DN von einer Personz.B. cn=Alexander, cn=Merzky, cn=Chemnitz, cn=Deutschland. Die Attribute sind etwaStrasse, Hausnummer, Telefonnummer.Im Unterschied zum Telefonbuch kann man aber in elektronischen Verzeichnissen nicht nurnach RDN’s suchen, sondern nach allen vorhandenen Attributen. Also ist bei der Abbildung desTelefonbuchs in X.500/LDAP auch die Suche nach einer bestimmten Telefonnummer moglichund nicht nur nach den Indizes Nach- und Vorname. Relationale Datenbanken durchforsten stan-dardmassig bei einer Suchanfrage ihren gesamten Datenbestand, um einen zum Suchkriteriumpassenden Eintrag zu finden, wahrend Verzeichnisse nur den Teilbaum durchsuchen, der bei derSuche angegeben wurde (searchbase). Dafur sind Einfugeoperationen in Datenbanken wesentlicheinfacher, weil kein Pfad gesucht werden muss, in dem ein neuer Eintrag zu tatigen ist. DerVorteil von LDAP gegenuber anderen Verzeichnisdiensten wie dem Netware Directory Service(NDS) oder MS Active Directory ist, dass es ein offener Standard ist und somit kostenlos, aufallen Plattformen verfugbar und frei anderbar ist.Der Begriff LDAP bezieht sich sowohl auf ein Protokoll zum Austausch von Verzeichnisin-halten als auch auf das Format, in dem die Daten intern organisiert sind. [IMPLDAP][BINLDAP]

7

2.1.2 Das LDAP-Protokoll

Das LDAP-Protokoll ist direkt auf dem TCP-Layer aufgesetzt und beruht auf dem Client-Server-Prinzip. Demnach stellt ein Klient eine Anfrage an den Server, der diese dann entsprechendbearbeitet und dem Klienten das Ergebnis zuruckliefert. Anfragen und Antworten werden dazuin LDAPMessages eingebettet. Eine LDAPMessage besteht aus:

• MessageID - eine eindeutige fortlaufende Nummer, die den Bezug zwischen Anfrage undAntwort herstellt

• protocolOp - die Art der Anfrage bzw. Antwort

• controls - erweiterte Informationen

Der Klient kann folgende Anfragen (protocolOps) stellen:

• BindRequest - Klient will eine Verbindung zum Server aufbauen,dabei muss er sich ihm gegenuber authentifizierenDafur stehen 2 Mechanismen zur Auswahl: Simple, SASL

• UnbindRequest - Klient will seine Verbindung zum Server trennen

• SearchRequest - Klient stellt eine Suchanfrage nach bestimmten EintragenDiese werden durch folgende Suchattribute definiert:BaseObject: die Wurzel des Teilbaums, in dem die Suche stattfinden soll (searchbase)Scope: Soll nur das BaseObject, die gesamte nachste Ebene oder der ganze Teilbaum durch-sucht werdenFilter: Wonach soll gesucht werden, Angabe von Attribut-Wert Paaren ggf. mit WildcardsAttributes: Welche Attribute sollen zuruckgegeben werden

• ModifyRequest - Klient will Eintrage im Verzeichnuis andern

• AddRequest - Klient will dem Verzeichnis einen neuen Eintrag hinzufugen

• DelRequest - Klient will einen Eintrag aus dem Verzeichnis loschenBei diesen 3 Requestarten muss der DN des zu andernden Eintrags angegeben werden,sowie gegebenenfalls Attribut-Werte-Paare

• ModifyDNRequest - Klient will den DN eines Eintrags im Verzeichnis anderndas heisst, er will ihn im Verzeichnisbaum verschiebenDazu muss der alte und der neue DN angegeben werden, sowie ein Flag,das das Loschen des alten Eintrags veranlasst

• CompareRequest - Klient will einen Attributwert eines Eintrags mit einem gelieferten Wertvergleichen

• AbandonRequest - Klient will eine Operation abbrechen, die der Server in seinem Auftraggerade ausfuhrtDie Operation ist durch die Angabe der MessageID eindeutig referenziert

• ExtendedRequest - Erweiterung des LDAP-Protokolls ab Version 3, um nicht-standardisierteAnfragen und Antworten implementieren zu konnen, der Inhalt ist frei definierbar

Der Server kann folgende Antworten (protocolOps) liefern:

• BindResponse - Antwort auf einen BindRequest, ’success’ im Erfolgsfall

• SearchResultEntry - Server liefert eine Menge von Eintragen mit Attributen, die den Such-kriterien entsprechen

8

• SearchResultReference - Die gewunschten Daten sind auf einem anderen Server zu erfragen,eine LDAP-URL wird zuruck geliefert

• SearchResultDone - Nach der Auslieferung der Suchergebnisse wird im Erfolgsfall ein ’suc-cess’ gesendet, woraufhin die Verbindung beendet wird

• ModifyResponse - Antwort auf einen ModifyRequest, ’success’ im Erfolgsfall

• AddResponse - Antwort auf einen AddRequest, ’success’ im Erfolgsfall

• DeleteResponse - Antwort auf einen DeleteRequest, ’success’ im Erfolgsfall

• ModifyDNResponse - Antwort auf einen ModifyDNRequest, ’success’ im Erfolgsfall

• CompareResponse - Antwort auf einen CompareRequest, ’success’ im Erfolgsfall

• ExtendedResponse - Antwort auf einen ExtendedRequest, der Inhalt ist frei definierbar

Um die Funktionsweise zu verdeutlichen, folgt jetzt ein reprasentativer Protokollablauf einesSearchRequestsDabei wird der Klient zur Vereinfachung C und der Server S genannt 1

• C sendet an S einen BindRequest, mit dem er sich gegenuber ihm authentifiziertAuthType: simpleMessageID=1

• S antwortet mit einem BindResult mit einem LDAPResultResultCode:successMessageID=1

• C sendet an S einen SearchRequestBaseDN: o=meinefirma.orgScope: SubtreeFilter: (cn=Merzky)Attributes: “*“MessageID=2

• S findet ein entsprechendes Ergebnis und sendet ein SearchResultEntryDN: cn=Alexander, cn=Merzky, ou=admin, o=meinefirma.orgAttribute: objectClass , Value: organisationalPersonAttribute: cn, Value: AlexanderAttribute: sn, Value: ManagerAttribute: telephoneNumber, Value: 1234MessageID=2

• danach sendet S ein SearchResultDoneResultCode: SuccessMessageID=2

• C sendet einen UnbindRequest MessageID=3

[RFC2251] Die Konfiguration des Servers wird im allgemeinen durch das File/etc/openldap/slapd.conf vorgenommen, wahrend der Klient sein erforderliches Wissenentweder aus ldap.conf bezieht oder als Programmparameter ubergeben bekommt.

1C=Klient, S=Server

9

2.1.3 Das LDAP-Datenmodell

Die Grundidee ist das Vorhandensein eines globalen Directory Information Tree (DIT), der, wieder Name schon sagt, als baumformiges Verzeichnis strukturiert ist.Jeder Server, der Verzeichniseintrage in diesem weltweiten DIT bereitstellen will, braucht eineneindeutigen Einstiegspunkt, den sogenannten Suffix (Firmen-DN), also einen Pfad im globalenVerzeichnisbaum, der zur eigenen Organisation fuhrt. Damit die Eindeutigkeit gewahrleistet ist,muss ein solcher Suffix bei einer weltweiten Organisation registriert werden. Er stellt die Wurzeldes lokalen, vom Server bereitgestellten, Naming Contexts dar. Ein LDAP Server kann aber aucheigenstandig betrieben werden, muss in dem Falle also nicht in den globalen DIT eingehangtwerden. Jeder Knoten und jedes Blatt im DIT stellt ein Objekt dar. Es besteht aus einem DN,der eindeutig seine Position im Baum beschreibt, sowie einer Menge von Atrribut-Werte-Paaren.Ein Attribut, das in jedem Objekt enthalten sein muss, ist die ObjectClass. Objekte werdenim LDAP-Datenmodell uber Schemata (entsprechen Datentypen) definiert, die die benotigten(MUST-) und moglichen (MAY-) Attribute festlegt. Eine ObjectClass definiert genau ein solchesSchema. Beispielsweise benotigt die ObjectClass ”person“ die Attribute ”sn“(Surname) und ”cn“(common Name) und ermoglicht die Belegung der Attribute ”userPassword“ , ”telephoneNum-ber“, ”seeAlso“ und ”description“.Ein Attributeschema legt unter anderem seinen Namen, eine Beschreibung und eine Syntax fest.Syntaxes werden ebenfalls uber Schemata definiert, genauso wie MatchingRules, welche beimVergleich mehrerer Attributwerte gleichen Typs angewandt werden. Jedes Schema besitzt eineeindeutige ObjectID (OID). Sie ist eine eindeutige ID in der sogenannten Management Informa-tion Base (MIB). Neben den Standard-LDAP-Schemata fur Organisationsstrukturen und DIT-Management konnen auch eigene Schemata definiert werden, deren OIDs ebenfalls an zentralerStelle zu registrieren sind.Um eine einheitliche Schnittstelle zur Datenmanipulation zu bieten, wird der Import (Eintragvon Daten) uber sogenannten LDIF-Files (LDAP Data Interchange Format) vorgenommen. Die-ses Datenformat ist genau definiert und spiegelt die Struktur des entstehenden Eintrags wieder.Die LDAP-Kliententools wie etwa ldapadd wandeln diese Daten in LDAP-Protokollwerte umund kontaktieren damit den Server, der sie zur Speicherung in sein internes Format umwandelt.Die Art der internen Datenspeicherung im Server kann durch die Wahl eines Backends bestimmtwerden. OpenLDAP bietet zu diesem Zweck eine Vielzahl von Schnittstellen an, beispielsweise zurUnterbringung der Daten in einer BerkeleyDB (back-bdb) oder in einer SQL-Datenbank (back-sql). Die Wahl des Backends wird ebenfalls im Konfigurationsfile vorgenommen und beeinflusstmassgeblich die Such- und Anderungsperformance.Ein Server verwaltet allerdings nicht nur nutzerzugangliche Daten, sondern auch Eintrage, dieausschliesslich zur Ausfuhrung von Operationen notig sind, sogenannte DSAOperation-Entries.Auch auf bestimmte Attribute von Nutzereintragen kann nicht ohne weiteres zugegriffen werden,da auch sie von openLDAP nur zur Verwaltung genutzt werden, beispielsweise der EntryCSN(Change Sequence Number), der den Zeitpunkt der letzten Anderung dieses Eintrags angibt.

2.1.4 Einsatzszenarien

Wie bereits erwahnt, werden Verzeichnisse grosstenteils zur Bereitstellung von Mitarbeiter-informationen genutzt. Es konnen gesamte Firmenstrukturen abgebildet werden, indem dieeinzelnen Abteilungen je einen Teilbaum belegen. Wenn beispielsweise eine Firma den Suffix

”o=meinefirma, c=de“ besitzt, konnen unter dem DN ”ou=management, o=meinefirma, c=de“die Managementabteilung und unter ”ou=programming, o=meinefirma, c=de“ die Programmie-rer im Naming Context untergebracht werden.Es ist bei grossen Unternehmen auch moglich, in den einzelnen Abteilungen eigenstandige LDAP-

10

Server zu betreiben, welche zusammen die gesamte Firma reprasentieren. Dabei werden die Anfra-gen an ”fremde“ LDAP-Server entsprechend weitergeleitet. Weiterhin vorstellbar ist der Betriebmehrerer DSAs, die das selbe DIT-Fragment bereitstellen. Dieses Szenario kann verwendet wer-den, um die Ausfallsicherheit zu erhohen oder die Antwortzeiten zu verkurzen. Allerdings fallendamit Probleme mit der Synchronisation der Server an, die in dieser Diplomarbeit behandeltwerden sollen.Verzeichnisse konnen aber nicht nur zur reinen Informationsbeschaffung dienen, sondern werdenauch zur Authentifizierung bei weiteren Diensten (z.B. IMAP, Linux Login) genutzt.

11

2.2 Replikation

2.2.1 Einfuhrung

Unter Replikation versteht man die mehrfache Speicherung von Daten, aber auch das paralleleAusfuhren mehrerer gleicher Prozesse und das Vervielfaltigen von Nachrichten, um Dienste zudezentralisieren, und damit die Ausfallsicherheit und Fehlertoleranz zu erhohen sowie im Falleder Datenreplikation die Netzlast und die Antwortzeiten zu verringern.In dieser Arbeit soll es hauptsachlich um Datenreplikation gehen. Dafur bietet es sich an, einenVerbund von Servern zu installieren, die den selben Datenbestand redundant speichern und je-weils vorrangig von Klienten in ihrer unmittelbaren Umgebung kontaktiert werden. Vorrangigdeswegen, weil die Klienten im Sinne der Ausfallsicherheit bei Nichterreichbarkeit des ”lokalen“Servers und bei Weiterleitungen auf einen anderen zuruckgreifen sollen.Solange die redundant gespeicherten Inhalte nicht verandert werden, mussen die Server nichtmiteinander kommunizieren. Es reicht, bei einem Ausfall oder einer Inbetriebnahme, den Da-tenbestand von einem laufenden Server oder einer ”Masterkopie“ manuell oder automatisch zukopieren.Anders sieht es aus, wenn Klienten die Moglichkeit haben, die Daten zu manipulieren. Dazuzahlen zum Beispiel das Andern, Loschen, Hinzufugen oder auch die Umstrukturierung von Da-tensatzen. Da jeder Klient im Normalfall jeweils nur mit einem Server verbunden ist, hatte diesernach Ausfuhrung der vom Klienten gewunschten Anderungen nicht mehr den einheitlichen Da-teninhalt der restlichen Server. Das heisst, der Datenbestand im Serververbund ware inkonsistent.Wenn dann ein zweiter Klient seinen (einen anderen) Server nach den Informationen fragen wurde,die im ersten Server geandert wurden, so konnte dieser nur seinen ”veralteten“ Wissenstand lie-fern, was naturlich nicht gewunscht war.Um dieses Problem zu beheben, muss ein Mechanismus vorhanden sein, der einen einheitlichenund konsistenten Inhalt aller Server garantiert.Es ware denkbar, dass jeder Klient, der eine Anderung vornimmt, selbige an jeden Server imVerbund schickt, was aber die Kenntnis und die Erreichbarkeit aller Server voraussetzt. Ausser-dem sollte die Vervielfaltigung der Daten eher Aufgabe des Servers sein, um die Klientenrechnerzu entlasten und die Struktur der Server fur den Klienten transparent zu gestalten. Eine weitereIdee ist das Vorhandensein eines Agenten, an den jeder Klient seine Updates schickt und derseinerseits jeden Server damit beliefert.Die gangigste Losung ist, die Server untereinander abzugleichen, oder fachlich ausgedruckt, sie zusynchronisieren. Dabei nimmt der zustandige Server den Anderungswunsch entgegen und sorgtdafur, dass er an die restlichen Verbundsteilnehmer weitergeleitet wird.Bei der Replikation kann es vorkommen, dass einige der Server durch Software- und Hardwa-refehler, Uberlastungssituationen, menschliche Fehler oder durch Stromausfalle vorubergehendausfallen oder zumindest nicht erreichbar sind. Um eine hohe Verfugbarkeit des Serververbundeszu gewahrleisten, sollten derartige Fehler erkannt, toleriert oder isoliert/maskiert und im Idealfallsogar repariert und die Server neu gestartet werden. Zu diesen Mechanismen gehort auch, dassdie Servicebereiche von ausgefallenen Systemen von anderen Servern ubernommen werden, ohnedass der Klient etwas davon mitbekommt (Transparenz). Bei der Erkennung des Fehlverhaltensist zwischen netzwerkbedingter Nichterreichbarkeit und echten Hardwarefehlern zu unterscheiden.Nach der Wiederinbetriebnahme, die sowohl automatisch als auch manuell vorgenommen werdenkann, mussen die ausgefallenen Systeme wieder mit den betriebsbereiten Servern synchronisiertwerden. [REPTEC]Ein Performancevorteil durch Replikation kann aber nur erreicht werden, wenn die Anzahl derLeseoperationen die der Schreiboperationen ubersteigt. Der Grund liegt im grossen Schreibauf-wand, der um ein vielfaches hoher ist als bei einem einzelnen System, da mit jeder Writeoperationein komplexer Updatemechanismus ausgelost wird. Der Aufwand der Verteilung kann zwar

12

auf Kosten der Konsistenz reduziert werden, indem weniger Server mit den Updates versorgtwerden, dadurch leidet aber wiederum die Leseperformance, weil nicht alle Server auf demaktuellen Stand sind. Die nicht versorgten Server mussen dann die Anfragen weiterleiten oderliefern eben eine veraltete Version der Daten. Die Performance von Leseoperationen steigt durchdie gegebenenfalls geringere Entfernung zwischen Klient und Server, sowie durch das paralleleVerarbeiten von mehreren Readrequests an verschiedenen Servern. Die Ausfallsicherheit wirdjedoch immer durch Replikation erhoht.

Fur die folgenden Erklarungen ist eine kurze Einfuhrung in die Terminologie erforderlich:

• Replikation: Der Prozess, Datenbestande in mehreren Orten zu duplizieren und diese peri-odisch zu synchronisieren

• Synchronisation: Der Prozess, zu einem fruheren Zeitpunkt bereits konsistente Daten-bestande erneut abzugleichen

• Masterserver (Provider) : Server, der definitiv den Datenbestand halt, mit dem sich alleanderen synchronisieren mussen; auf ihn kann direkt geschrieben werden; authoritativeDatenquelle

• Replikaserver (Consumer, Slave, Replikaserver) : Server, der sich mit dem Masterserversynchronisieren muss; auf ihn sollte von Klientenseite aus nur lesend zugegriffen werdenkonnen

• Full Reload (initial content load): Die gesamte zu replizierende Menge wird im Ganzenubertragen

• Inkrementelles Update: Es werden nur Daten ubertragen, die sich seit der letzten Synchro-nisation verandert haben

Es gibt mehrere mogliche Konstellationen der Aufgabenverteilung, die in den folgenden Ab-schnitten naher beleuchtet werden:

• Jeder Server nimmt die Anderungen zuerst lokal vor und verteilt sie dann als authoritativeDatenquellean die anderen (Multi-Master-Replikation)

• Es gibt nur einen authoritativen Server, der Anderungen verbreiten darf. Daher leitet jederder anderen ”Replikaserver“ die Updaterequests an ihn weiter und empfangt dann ein Up-date von ihm, mit dem er letztlich seinen Datenbestand auffrischt.(Single-Master-Replikation)

• Jeder Klient ist so konfiguriert, dass er Anderungswunsche immer an ein und den selbenServer schickt, der dann auch ihren lokalen Server updatet (Single-Master-Replikation)

• Es gibt zwei oder mehr Masterserver, von denen aber immer nur einer Updaterequestsverarbeiten darf. Die restlichen Failover-Server synchronisieren sich mitb dem aktuellenMaster solange er aktiv ist. Wenn dieser durch irgendeinen Grund nicht mehr erreichbarist, ubernimmt einer der anderen seine Rolle. Auf die ubrigen Replikaserver kann nur lesendzugegriffen werden.

2.2.2 Multi-Master-Replikation

Diese Konstellation scheint auf den ersten Blick die vorteilhafteste zu sein, weil die Updatesden kurzesten Weg zurucklegen mussen (vom Klient zu seinem Server und von da aus zu allen

13

anderen Servern) und beim Ausfall eines Servers zumindest die nicht mit ihm verbundenenKlienten weiterhin updaten und lesen konnen.Nun stelle man sich aber folgendes Szenario vor: 2

Abbildung 1: gleichzeitige Updates

C1 will an O1 eine Anderung U1 vornehmen, schickt die entsprechende Anfrage also an S1.C2 mochte ebenfalls zur gleichen Zeit O1 andern und schickt seinen Request (U2) an S3.Da sowohl S1 als auch S3 das lokale Update entgegengenommen haben, bevor das der anderenPartei sie erreicht hat, kann keiner der beiden Server entscheiden, welche Version nun dieentgultige sein soll.Mathematisch ausgedruckt: 3

S1: t[U1] < t[U2] S3: t[U2] < t[U1]S1: tDiff1 = t[U2] - t[U1] > 0 S3: tDiff3 = t[U1] - t[U2] > 0

Ohne zusatzliche Massnahmen sind U1 und U2 in einem solchen Fall nicht eindeutig seriali-sierbar. Nun konnte man sagen, dass dieser Fall relativ unwahrscheinlich ist. Dabei muss aber inBetracht gezogen werden, dass tDiff durch Netzwerklatenzen, Verarbeitungszeiten sowie eventuelleUpdateintervalle (die Synchronisation wird z.B. nur alle 5 min durchgefuhrt) erhoht wird.

2C=Klient, S=Server, O=Objekt, U=Update3tDiff = Zeitdifferenz zwischen lokalem und Replikaupdate

14

Fur dieses Problem sind verschiedene Losungsvarianten moglich:

• Der Klient schickt einen Zeitstempel beim Updatewunsch mit. Somit wissen die Serverdann, welches Update zuerst in Auftrag gegeben wurde. Diese Losung setzt den Einsatzeines Zeitsynchronisationsprotokolls voraus. [MMREPROP]

• Die gleiche Idee kann auch angewandt werden, wenn der Server beim Eingang eines Upda-terequests einen Zeitstempel hinzufugt, bevor er es verbreitet.

Um uberhaupt eine Multi-Master-Umgebung in Betrieb nehmen zu konnen, mussen alle Serverlaut [LDAPMMRP] Anderungen aufzeichnen (loggen) und an die anderen ubertragen konnensowie einen Konflikterkennungs- und losungsmechanismus beinhalten. Ausserdem mussen imLDAP-Umfeld einzelne Objekte ausser ihrem DN eine wirklich eindeutige ID besitzen. Dennwenn der DN bei einem Update verandert wird, kann mit ihm kein eindeutiges Objekt mehrreferenziert werden. Um die Anzahl der Anderungen pro Objekt aufzeichnen zu konnen, mussauch eine Versionsnummer gespeichert werden, genau wie fur jedes einzelne Attribut in jedemObjekt. All diese Zusatzinformationen mussen ebenfalls im Verzeichnis untergebracht werden.

2.2.3 Single-Master-Replikation

Hierbei gibt es einen Server, der die Masterkopie des zu replizierenden Verzeichnisteils be-reitstellt. Nur er darf Schreibanforderungen der Klienten ausfuhren und an alle Replikaserverweiterleiten. Die Replikaserver werden auf Klientenseite entweder nur zum lesen genutzt (rechtesBild), oder sie leitet die an sie gerichteten Updaterequests an den Masterserver weiter, weilsie nicht authorisiert sind, die Requests zu verarbeiten (linkes Bild). In beiden Fallen werdendanach die Replikaserver vom Master aus aktualisiert. 4

1. C2 schickt einen Updaterequest an R1 1. C2 schickt seinen Updaterequest direkt an M

2. R1 forwardet den Request zu M 2. M updatet sich, verteilt die Updates an R1, R2

3. M updatet sich und verteilt Updates an R1,R2 3. R1 und R2 updaten sich

4. R1 und R2 updaten sich

Abbildung 2: Single-Master-Replikation

Das Multi-Master-Problem mit gleichzeitigen Anderungsanforderungen ist hier quasi ausgeschlos-sen, da der Server netzwerk- und prozessorbedingt alle ankommenden Queries sequentiell abar-beitet. Eine Ausnahme bilden hier nur multi-homed Multiprozessorsysteme mit entsprechender

4C=Klient, M=Masterserver, R=Replikaserver, U=Update

15

Serversoftware. Der Umstand, dass sich Pakete durch unterschiedliche Netzwerklatenzen ”uberho-len“ konnen, sollte hier trotzdem nicht ausser Acht gelassen werden. Auch hier ware es hilfreich,wenn der Klient den Request mit einem Zeitstempel versehen wurde, um die Anfragereihenfolgeruckverfolgbar zu machen .Das grosste Problem besteht aber darin, dass ein Ausfall des Masterservers alle Schreiboperatio-nen unausfuhrbar machen wurde. Aber auch hierfur gibt es mehrere Losungsansatze:

• Der Administrator kann einen bisher als Replikaserver genutzten Host zum Masterserverumfunktionieren

• Wenn die Replikaserver mitbekommen, dass ihr Master nicht mehr erreichbar ist, konnensie selbststandig einen neuen ”wahlen“.

2.2.4 Die Failover-Konstellation

Der letzte Punkt wird in abgewandelter Form beim Failover-Prinzip angewandt. Es gibt einenMasterserver, und mehrere Replikaserver, von denen einige als Masterkandidaten deklariert sind.Fallt nun der eigentliche Master aus, ubernimmt sofort der erste Kandidat seine Rolle. Diesersollte zu diesem Zeitpunkt auch die Bedingung an einen Masterserver erfullen, namlich eine aut-horitative Datenquelle zu sein, weil er ja bis dahin mit der bisherigen authoritativen Datenquellesynchronisiert wurde.Im Idealfall ware jeder Replikaserver ein Failoverserver, sodass nur beim Ausfall aller Server keineSchreiboperationen (wie auch Leseoperationen) mehr moglich sein wurden. 5 Das Problem bei

Abbildung 3: Failover-Prinzip

dieser Methode ist der Neustart eines in der Failover-Hieranrchie hoher liegenden Servers. Nimmtdieser sofort wieder die Masterrolle ein, gehen die zwischenzeitlich vorgenommenen Anderungenverloren, wenn er seine Daten nicht vorher mit denen des bisherigen Masters abgleicht.

2.2.5 Weitere Aspekte

Die Zusammenarbeit mehrerer Nutzer wird allgemein als Kollaboration bezeichnet. Diese Sicht-weise kann auch auf die Replikation projiziert werden. Da jeder Nutzer (Klient) lesend undschreibend mit dem System kommunizieren kann, konnen sich die verschiedenen Nutzer so un-tereinander verstandigen. Somit kann eine Replikationsumgebung auch als verteilter Informati-onskanal angesehen werden. Die Unterscheidung der zeitlichen Gebundenheit der Nutzer lassensich 2 gegensatzliche Szenarien beschreiben:Die synchrone Kollaboration wird vor allem bei interaktiven Echtzeitsystemen eingesetzt, indenen Nutzer gemeinsam (verteilt) zur selben Zeit arbeiten, um ein gemeinsames Ziel zu erreichen

5C=Klient, M=Masterserver, R=Replikaserver, F=Failoverserver

16

Die asynchrone Kollaboration verlangt kein gleichzeitiges Arbeiten aller Mitglieder, sondernbietet die Moglichkeit, zeitlich unabhangig Informationen zu liefern und zu benutzen, oder andersausgedruckt, zu teilenDass die Nutzer des Systems asynchron uber Verzeichnisse kommunizieren, durfte jedem klar sein.Hier stellt sich vielmehr die Frage, in welcher Weise die Server untereinander kommunizieren. Siekonnen entweder jede Anderung sofort (so schnell wie moglich), zu festgelegten Zeiten oder nurauf Anfrage verbreiten.

2.2.6 Nachteile

Wie bereits teilweise erwahnt, hat die Replikation von Daten nicht nur Vorteile. Durch diemogliche parallele Verarbeitung von Writerequests konnen Inkonsistenzen auftreten, die unterUmstanden schwer oder nicht eindeutig zu beheben sind. Der Vervielfaltigungsvorgang selbstbenotigt Systemressourcen (Rechnerlast, Netzwerklast) und kann die Write-Performance des zureplizierenden Dienstes sehr stark herabsetzen. Der Vorteil der Dezentralisierung kann hier zumNachteil werden, wenn auftretende Fehler nicht mehr eindeutig lokalisierbar sind. Auch ist einerhohter Aufwand zu betreiben, um Sicherheitsrichtlinien einhalten zu konnen, weil durch dieKommunikationsschnittstelle zu den Replikaservern auch nicht authorisierte Quellen Datenande-rungen veranlassen konnen. Bei der Auflosung von Inkonsistenzen kann es systembedingt zuDeadlocks kommen, besonders in Multi-Master-Umgebungen, bei denen Updates verschiedenerServer uber einen Zeitstempel zeitlich geordnet werden und mehrere Updates gleiche Zeitstempelhaben oder die Server verschiedene Systemzeiten haben.

17

3 Anforderungen - Top-Down Entwurf

In diesem Abschnitt werden konkrete Anforderungen an den zu erstellenden LDAP-Replikationsmechanismus erarbeitet. Dabei werden sowohl allgemeine als auch verzeichnis- undLDAP-spezifische Betrachtungen vorgenommen.Die Ergebnisse werden im nachsten Abschnitt mit bereits vorhandenen Losungen abgeglichen.

3.1 Anforderungen

3.1.1 Allgemeine Anforderungen

Allgemeine Anforderungen an Software sollten hier grundsatzliche Beachtung finden. Zuerst waredie Korrektheit zu nennen. Im Sinne des Softwareentwurfs bedeutet dies die Korrektheit desEntwurfs, aber auch die Konformitat von Entwurf und Implementation. Ein weiterer Punkt ist dieZuverlassigkeit. Es sollte garantiert werden konnen, dass der Replikationsmechanismus unter al-len Bedingungen, selbst bei Ausnahmesituationen, korrekt arbeitet, oder zumindest eigenstandigzu einer korrekten Funktionsweise zuruckfindet. Laut [REPTEC] bedeutet Zuverlassigkeit dielangstmogliche Laufzeit einer Komponente im Replikationsverbund, die durch Fehlertoleranz undRecovery erreicht wird. Dabei soll jeder Request zu irgendeinem Zeitpunkt beantwortet werden.Sie wird durch den Wert MTTF (Mean Time to Failure) gemessen, der die mittlere Zeit zwischen2 Fehlern angibt. Im Gegensatz dazu gibt die Verfugbarkeit an, ob ein System zu einen be-stimmten Zeitpunkt Anfragen entgegennehmen kann (momentane Erreichbarkeit). Sie wird zeitu-nabhangig durch die Wahrscheinlichkeit A=MTTF/(MTTF+MTTR) angegeben, wobei MTTRdie Mean Time to Repair angibt. Letzterer Punkt wird auch als Robustheit bezeichnet.Mit dem Einsatz von Netz- und Systemresourcen sollte die Software effizient umgehen, undsollte auch bei grossen Datenmengen eine ausreichende Performance bieten Die Nutzung derResourcen sollte ebenso wie die Policies konfigurierbar sein. Die Installation und Nutzung desReplikationsmechanismus’ sollte nutzerfreundlich gestaltet werden, das heisst ohne Spezialwis-sen oder ubermassige Administratorinteraktion bedienbar sein und sich nach gangigen Standardsrichten. Der Replikationszustand (Fortschritt, laufende Aktionen, Fehlerlogs...) sollten jederzeiteinsehbar oder prufbar sein, um dem Administrator ein rechtzeitiges Eingreifen zur Vermeidungmoglicher Katastrophen zu ermoglichen, aber auch um Resourcenknappheiten oder Fehlkonfi-gurationen zu erkennen. Die Software sollte leicht wartbar und erweiterbar sein, das heisstzum Beispiel, einen modularen, ubersichtlichen Quelltext mit Schnittstellen fur zusatzliche Pa-kete anbieten. Die Einteilung in Quelltextmodule dient auch der Reparierbarkeit. Der PunktWiederverwendbarkeit hangt in diesem Fall stark mit der Portierbarkeit und der Inter-operabilitat zusammen. So sollte versucht werden, den Mechanismus vielen Implementationenvon LDAP zuganglich zu machen oder zumindest mit minimalen Anderungen eine Anpassung zuermoglichen. Damit die Software mit anderen LDAP-Servern zusammenarbeiten kann, muss sieihnen naturlich in Form entsprechender Schnittstellen zuganglich gemacht werden. [ST1SCRIPT]

3.1.2 Anforderungen an den Replikationsmechanismus

Der Mechanismus soll fur den openLDAP Server V3 implementiert werden.Um die Vorteile der Replikation voll ausnutzen zu konnen, sollten Lese- oder Suchzugriffe aufjedem teilnehmenden Server erlaubt sein, wahrend die relativ seltenen Schreibzugriffenur von einem oder einigen wenigen Servern auszufuhren sind. Wunschenswert ware esjedoch, dass jeder Server Schreiboperationen von Klienten annimmt und diese an die entspre-chend authorisierten Server weiterleitet, sodass fur die Nutzer eine grosstmogliche Transparenzentsteht.Naturlich mussen die Server untereinander synchronisiert werden. Hier treten allerdings

18

die ersten naher zu spezifizierenden Anforderungen auf. Da der Updatevorgang selbst eine ge-wisse Zeit in Anspruch nimmt und von Updatepolicies beeinflusst wird (Synchronisationsinter-valle, Reihenfolge der Kontaktaufnahme...), muss eine Aussage gemacht werden, wie langedie Server untereinander inkonsistent sein durfen (temporare Inkonsistenzen), oder an-ders ausgedruckt, welche Form der Kollaboration (synchron/asynchron) zu verwenden ist.Diese Festlegungen sollten vom Nutzer konfigurierbar sein. Die Replikation selbst sollte zu-verlassig arbeiten, genauer gesagt muss garantiert sein, dass jeder Server letztlich mit einemMaster synchronisiert wird, sodass keine dauerhaften Inkonsistenzen oder Datenunterschie-de auftreten konnen. Ausserdem muss gesichert sein, dass jeder Replikaserver kein Update mehr-mals verarbeitet, was potentiell bei mehr als einem Master moglich ware. Der Replikations-/Synchronisationsprozess sollte von verschiedenen Punkten aus angestossen werdenkonnen. Die Replikaserver sollten jederzeit den Wunsch aussern konnen, auf den aktuellen Standgebracht zu werden wahrend es dem Master auch moglich sein sollte, nach ausgefuhrten Ande-rungen die Replikas zu informieren. Es sollten sowohl inkrementelle Updates zu Synchro-nisation wie auch ein kompletter Datentransfer zur Initialisierung oder Fehlerbehebungmoglich sein.Laut [LDAPREPREQ] sollte ein Master mehrere Replika gleichzeitig mit (den selben) Daten ver-sorgen konnen, um Bandbreite zu sparen. Falls ein Server neu startet, zum Beispiel nach einemAbsturz, solte er automatisch nach den korrekten Daten fragen und sie geliefert bekommen. Essollten alle gangigen LDAP-Schemata unterstutzt werden. Auch die Skalierbarkeit spielthier eine grosse Rolle: die Replikation sollte sowohl in LAN- wie auch in WAN- oder Internet-Umgebungen noch ausreichende Performance bieten konnen. Ein automatische Skalierung istjedoch nicht zwingend notig, es reicht die Konfigurierbarkeit. [LDAPREPREQ]Im Rahmen dieser Diplomarbeit soll ein Replikationsmechanismus entwickelt werden, bei demSchreiboperationen auch bei Ausfallen moglichst vieler Server (Master- oder Re-plikaserver) noch ausfuhrbar sind. Die Server sollen untereinander die Verteilung derDaten regeln, bei Ausfallen ihre Struktur so anpassen, dass die volle Funktionsfahig-keit (sofern moglich) erhalten bleibt. Die Administratorinteraktionen im laufenden Bertiebsollten minimal sein. Der Replikationsvorgang inklusive aller auftretenden Fehler und Einstellun-gen sollte fur den Endnutzer transparent (unsichtbar) sein. Die Replikation von Teilbaumen(DIT-Fragmenten) soll unterstutzt werden.

3.2 Fazit

Um die oben genannten Anforderungen erfullen zu konnen, eignen sich das Multi-Master-Prinzipsowie die Failover Konstellation. Das Single-Master-System, das beim Ausfall des Mastersjegliche Schreiboperationen unmoglich macht, ist hier nur mit den genannten Erweiterungenbrauchbar.

19

4 Replikationsmodelle - Bottom-Up Entwurf

In diesem Abschnitt werden bereits vorhandene und genutzte Replikations- und Synchronisati-onsmechanismen vorgestellt und auf ihre Anforderungskonformitat gepruft.

4.1 Vorhandene LDAP-Replikationsmethoden

4.1.1 LDAP-slurpd

Die erste LDAP-Replikationsmethode, die im grosseren Stil angewandt wurde, nutzt den Einsatzdes slurpd, der sozusagen als Verteiler von Updates dient und auf dem selben Server ausgefuhrtwie wie der Master slapd. Er uberwacht ein Replikationslogfile, dass vom Master-slapd mit LDIF-Updateinformationen gefullt wird, wenn er selbst Anderungen ausfuhrt. Das File beinhaltet alleReplikaserver, die zu kontaktieren sind, und fur jede Anderung einen Zeitstempel, den DN desmodifizierten Eintrags und eine Menge von Anderungen im LDIF-Format. Falls vom slurpd eineAnderung festgestellt wird, kontaktiert er alle registrierten slapd -Slaves und versorgt sie mit denUpdates. Dabei lauft ein Updatevorgang folgendermassen ab:

• C2 sendet einen Updaterequest an S1

• dieser liefert ein Referral (Uberweisung) an M

• C2 sendet Updaterequest nun an M

• M fuhrt das Update aus, schreibt es in den ReplicationLog und liefert C2 eine Erfolgsmel-dung

• slurpd registriert die Anderung im Log und sendet die Anderungen via LDAP an S1 undS2

• S1 und S2 fuhren die Anderungen aus und senden eine Erfolgsmeldung an slurpd

Abbildung 4: slurpd-Prinzip

[SLAPDADMIN] Der Einsatzbereich des slurpd liegt hauptsachlich in Umgebungen, in denenAnderungen vorwiegend an zentraler Stelle vorgenommen werden, wahrend die Menge der Lese-anfragen nur durch eine Verteilung der Last uber mehrere Repliakserver zu bewaltigen ist. Durchdas angewandte Singel-Master-Prinzip kann jedoch nicht sichergestellt werden, dass Schreibzu-griffe jederzeit moglich sind. Mit der Definition von Verzeichnisdiensten, dass auf Directoriesrelativ selten schreibend zugefgriffen wird, kann dieser Nachteil in Szenarien, bei denen die Ak-tualitat der Daten nicht zwingend notwendig ist, akzeptiert werden.

20

In Umgebungen, die aufgrund von Sicherheitsrichtlinien oder anderweitigen Restriktionen dieReplikation von Teilbaumen benotigen, ist der Einsatz slurpd -Mechanismus nicht geeignet, davon ihm keine Teilbaumreplikation angeboten wird.Aufgrund des langjahrigen Einsatzes ist der slurpd -Replikationsmechanismus zuverlassig genug,um auch in kritischen Umgebungen eingesetzt werden zu konnen, vor allem wenn grossen Wertauf Konsistenz zwischen allen Servern gelegt wird.Durch die genannten Einschrankungen hinsichtlich Fehlertoleranz und Teilbaumreplikation istdieser Mechanismus nicht mit den Anforderungen dieser Arbeit vereinbar.

4.1.2 ixSync

Die Firma ]init[ bietet eine kommerzielle Losung zur Synchronisation verschiedener Verzeich-nisdienste unterschiedlicher Hersteller an. Sie basiert auf dem Multi-Master Prinzip. Um dieverschiedenartigen DAP - (Directory Access Protocol-) Server unterstutzen zu konnen, sind hierObjektklassen und Attributtypen frei konfigurierbar und abbildbar, wodurch unterschiedlicheObjektklassen miteinander synchronisiert werden konnen.Besonders unterstutzt werden hier PKI-Umgebungen (Public Key Infrastrukturen) mit der Re-plikation von Zerifikaten fur Microsoft Exchange und Active Directory. Als Protokoll, auf demdie Synchronisation aufsetzt, wird hier LDAP verwendet, um neue Verzeichnisdienste durch De-finieren von Basis-Templates einfach einbinden zu konnen, ohne am Server selbst Anderungenvornehmen zu mussen.Da es sich bei dieser Moglichkeit um eine kommerzielle Losung handelt und aufgrund dessen keinenaheren Angaben zur Funktionsweise gemacht wurden, kann hier nur die obige Beschreibung alsAnsatz fur die Einsatzszenarien angefuhrt werden. [IXSYNC]

4.1.3 LDAP Sync-Operation

Im letzten Jahr wurde durch eine Kooperation von openLDAP und IBM ein Internet-Draftherausgegeben, das einen weiteren LDAP-Synchronisationsmechanismus vorstellt. Er nutztnormale LDAP Requests und Responses, um eine Single-Master-Replikationsumgebung zuschaffen. Ursprunglich ist er dazu gedacht, dass ein Klient einen Teil des DITs lokal beherbergtund synchron halt. Laut Draft kann der Klient aber auch ein Slave-/Replikaserver sein, sodasssich der Mechanismus auch zur Server-Server-Synchronisation eignet.Die Grundlage bildet eine erweiterte LDAP-Search Anfrage, die die ublichen ArgumenteBaseObject, Scope, DerefAliases, sizeLimit, timeLimit, typesOnly, filter und attributes enthalt.Zusatzlich enthalt dieser Request einen LDAP-Control namens Sync Request Control, der dieNutzung dieses Mechanismus’ anzeigt. Auch der Server nutzt bei seinen Responses zusatzlicheControls namens Sync State Control und Sync Done Control, um Synchronisationszustand und-daten zu liefern, verhalt sich aber sonst wie bei der Beantwortung regularer Anfragen.Die Idee dabei ist, dass der Klient anfangs den kompletten Kontext verlangt und im Anschlussdaran aktiv oder passiv mit den Anderungen versorgt wird. Der Modus, in dem der Klient aktivagiert, das heisst regelmassig nach Anderungen fragt, nennt sich RefreshOnly Mode, weil jedeClient-Server-Verbindung nur zum Abgleich (Refresh) mit der aktuellen Server-Datenbasis dient.Der Passive Modus heisst RefreshAndPersist Mode. Hier trennt der Server die Verbindung nachdem initial content load nicht, sondern versorgt den Klienten uber diese Session automatischmit neuen Updates.Damit sich der Master nicht den Zustand jedes Slave merken muss, sendet er mit jedemUpdate ein Cookie an den Klienten, das den aktuellen Datenzustand reprasentiert und vomKlient im RefreshOnly Mode bei jedem Request mitgeschickt wird. Dieses Cookie besteht auseinem ContextCSN (Zeitstempel des letzten Updates am Master) und der RID (eindeutige

21

ID des Masters). Wird nun der Master von einem LDAP-Klient geupdatet, aktualisiert erseinen ContextCSN. Der Slave schickt beim nachsten sync-Request sein (veraltetes) Cookie mit,woraufhin der Master die Differenz erkennt und ihn mit mit den Updates versorgt, die zwischendiesen beiden Timestamps vorgenommen wurden. Um herauszufinden, welche Eintrage neuersind als der Cookiewert, nutzt der Master deren EntryCSN-Attribute und liefert die Eintrage,bei denen der EntryCSN grosser sind als der Cookie-Timestamp. Schliesslich schickt der Masternoch den aktuellen Cookiewert. Im RefreshAndPersist-Modus verwaltet der Master intern dieCookiewerte der Slaves, schickt aber mit jedem Update den aktuellen Wert mit, sodass der Slavenach einem Absturz und dem darauf folgenden Neustart das seiner Aktualitat entsprechendeCookie bei der nachsten Anfrage liefern kann.Im folgenden werden die zusatzlichen Controls noch einmal aufgelistet:

SyncRequestControlmode (RefreshOnly | RefreshAndPersist)cookie OPTIONALreloadHint

SyncStateControlstate (add | delete | present | modify)entryUUID (eindeutige ID eines Eintrags, DN wird bei Anderung uneindeutig)cookie OPTIONAL

SyncDoneControlcookie OPTIONALrefreshDeletes BOOLEAN

Fur die vollstandige Funktion ist noch eine LDAP IntermediateResponseMessage notig:

SyncInfoMessagenewcookie (cookie) |refreshDelete (cookie, refreshDone) |refreshPresent (cookie, refreshDone) |syncIDSet (cookie, refreshDeletes, syncUUIDs)

Letztlich ist noch ein LDAP ResultCode definiert:

e-syncRefreshRequired

Die Synchronisation im Modus RefreshOnly lauft folgenderweise ab: 6

Initial Content Poll:

1. C sendet einen normalen LDAP-SearchRequest(BaseObject, scope, derefAliases=neverDerefAliases, sizeLimit, timeLimit, typesOnly,filter, attributes) inklusive eines SRC (mode=refreshOnly, keinem cookieund reloadHint=FALSE)

2. S erkennt, dass kein Cookie mitgeliefert wurde und schliesst daraus, dass C einenkompletten Transfer des gewunschten Kontexts wunscht; S sendet mehrereLDAPResultEntry-Pakete (objectName, Attributes) inklusive eines SSC (state=add,

6C=Klient, S=Server, SRC=SyncRequestControl, SSC=SyncStateControl, SDC=SyncDoneControl,SIM=SyncInfoMessage

22

entryUUID=UUID des Objekts,kein cookie), bis der Klient das gesamte DIT-Fragment erhalten hat.

3. S schickt eine LDAPSearchResultDoneinklusive eines SDC (refreshDeletes=False, kein cookie)

4. Dann schickt er eine LDAPIntermediateResponseMessage [LDAPIRM] inklusive einer SIM(newcookie=aktueller Synchronisationszustand)

Content Update Poll:

1. C sendet den selben LDAP-SearchRequest wie oben inklusive eines SRC(mode=refreshOnly, cookie=letztes von S geliefertes cookie, reloadHint=FALSE)

2. S erkennt cookie, schliesst daraus den Synchronisationszustand des Klienten; wenn al-le Anderungen einzeln mehr Datenvolumen entsprechen als ein kompletter Reload, dannschickt er den LDAPResultCode e-syncRefreshRequired, was eine komplette Neuubertra-gung zur Folge hat; ansonsten schickt er mehrere LDAPResultEntry-Pakete (objectName,Attributes) inklusive eines SSC (state=add | delete | modify | present, entryUUID=UUIDdes Objekts, newcookie OPTIONAL), bis das Klient-DIT-Fragment mit dem entsprechen-den Server-DIT-Fragment ubereinstimmt. Dabei versucht er, durch eine geschickte Wahl derModifikationsart Bandbreite zu sparen: Bei add-Sync’s sind alle Attribute mit Werten be-legt. Bei delete-/ present - Sync’s sind Attribute ohne Werte, d.h. sie konnen mittels SIM’s(syncUUIDs=UUIDs aller geloschten/ presenten Objekte, refreshDeletes=TRUE/FALSE)zusammengefasst werden, um die Menge der zu ubertragenden Daten zu verringern.

3. S schickt eine LDAPSearchResultDone inklusive eines SDC(refreshDeletes=TRUE/FALSE, newcookie)

Die Synchronisation im Modus RefreshAndPersist lauft folgenderweise.ab:Der Initial Content Poll funktioniert wie oben beschrieben. Dieser wird aber nicht mittels LDAP-SearchResultDone beendet, sondern durch eine SIM, die den Eintritt in den Persist-Zustand an-zeigt. Somit ist der Server in der Lage, weitere Pakete (die Updates) an C zu schicken, ohnedass dieser mittels LDAPSearchRequest danach fragen muss. Der komplette Reload des Kon-texts kann durch C angestossen (reloadHint=TRUE) oder von S veranlasst werden (result=e-syncRefreshRequired)Sowohl der ContectCSN des Masters als auch die Cookies der Slaves werden im jeweils lokalenLDAP-Baum gespeichert. Zustandig dafur sind die Objektklassen SyncProviderSubentry undSyncConsumerSubentry, auf die von Nutzerseite aus nicht zugegriffen werden kann, da sie zuden DSAOperationEntries gehoren.Der erzielte Einsatzbereich des sich noch im Beta-Stadium befindlichen sync-Mechanismus’ liegtvorwiegend in Umgebungen, in denen Anderungen von verschiedenen Rechnern angestossen wer-den konnen. Ahnlich wie beim slurpd -Prinzip ist durch den Single-Master-Mechanismus dieVerfugbarkeit von Updates begrenzt. Der Umgang mit Ressourcen wie Bandbreite oder Pro-zessorleistung wurde jedoch durch die Optimierung der Datenubertragung und den Verzicht aufzusatzliche Module stark verbessert. Die Minimierung der ubertragenen Daten ist in Umgebun-gen, in denen haufig Umstrukturierungen des Verzeichnisses vorgenommen werden, von besonde-rem Vorteil. Auch die Unterstutzung der Teilbaumreplikation ist ein Fortschritt gegebuber demslurpd -Mmechanismus, der in bandbreitenbegrenzten Anbindungen oder in durch security policiesbeschrankten Umgebungen ausgenutzt werden kann. Aufgrund des derzeitigen Entwicklungssta-diums dieser Methode kann uber die Zuverlassigkeit keine verbindliche Aussage gemacht werden;in durchgefuhrten Test erwies sich LDAPsync als stabil.Da dieser Algorithmus aber auf dem Single-Master-Prinzip beruht, ist es in der Form nicht mit

23

den Anforderungen vereinbar. Eine Erweiterung im Sinne eines automatisch gewahlten Masters(je nach Verfugbarkeit) ware eine Losung dieses Problems.

24

4.2 Der UBIK-Algorithmus

4.2.1 OpenAFS - UBIK

UBIK beinhaltet einen ganz anderen Ansatz. Es beruht auf der Replikation der unterliegendenDatenbank. Der Serverpool besteht aus N Servern, von denen mehr als die Halfte erreichbar seinmuss (Q > N/2), um Lese- und Schreiboperationen ausfuhren zu konnen. Der Grund hierfurist, dass unter diesen Q Servern zu jedem Zeitpunkt mindestens ein Server dabei ist, der bereitszu einem fruheren Zeitpunkt Lese- und Schreiboperationen annehmen durfte und durch einenDatenabgleich jetzt die aktuelle Datenbasis bereitstellt.Die Menge der gerade erreichbaren Server, die durch die erfullte Bedingung schreibberechtigtsind, wird als Quorum (Q) bezeichnet. Wenn mehr als N/2 Server online sind, wahlen sie einenKoordinator, der als einziger Server Schreiboperationen ausfuhren darf. Die anderen sind nurzur Ausfuhrung von Leseoperationen berechtigt. Die Zeit, in der ein Server der Koordinator ist,wird als Epoche (Regierungszeit) bezeichnet. Sobald der Koordinator (Synchronization Site, SS)gewahlt wurde, vollzieht er eine Recovery- (Aktualisierungs-) Operation, um sicher zu stellen,dass er eine Up-To-Date Datenbasis besitzt. Falls zu einem Zeitpunkt weniger als Q Server er-reichbar sind, endet die aktuelle Epoche und die Datenbasis ist bis zur nachsten Epoche nichterreichbar. Nach einer Neuwahl bearbeitet der neue Koordinator die noch ausstehenden Requests.Die Aktualitat der Daten wird durch eine DB-Versionsnummer beschrieben (ServerID + Epoche+ Anzahl der Anderungen). Bei der Wahl sendet jeder Server regelmassige beacons (impliziteVOTEFORME-Anfragen mit seiner DB-Version) aus, die entweder mit VOTE NO oder VOTE YESbeantwortet werden. Falls der Server mindestens Q VOTE YES-Antworten bekommen hat, dekla-riert er sich als Synchronisation Site und sendet fortan beacons inclusive der restlichen Zeit biszur Neuwahl (Expire), seiner Datenbankversion und der aktuellen Epoche, um seine Erreichbar-keit anzuzeigen und Stimmen fur die Verlangerung seiner Regierungszeit zu sammeln.Leseoperationen konnen ausgefuhrt werden, wenn die letzte vom Koordinator empfangene beacon-Expiretime noch aussteht und wenn dessen mitgesendete DB-Version der eigenen entspricht.Schreiboperationen durfen nur vom Koordinator ausgefuhrt werden, wenn dessen Regierungszeitnoch nicht vorbei ist und werden durch einen Write-Request an jeden Slave weitergeleitet. Wennweniger als Q Slaves auf diesen Request antworten, bricht der Koordinator die Transaktion abund beendet seine Epoche. Ansonsten sendet er eine Prepare-Message an an alle erreichbarenServer. Diese nehmen den Updaterecord in ihren log auf und antworten dem Koordinator. Fallsder Koordinator von allen Servern eine Antwort erhalt, sendet er eine Unlock-Message, die alleServer zum Ausfuhren/Unlock des Updates auffordert. Falls der Koordinator von mindestens ei-nem Server keine Antwort erhalt, bricht er die Transaktion ab und beendet seine Epoche. DiesesVorgehen wird als 2-Phase-Commit Protokoll bezeichnet und dient der atomaren Datenverteilung(Alles oder Nichts-Prinzip).Bevor der Koordinator uberhaupt Schreiboperationen annehmen und Leseoperationen erlaubenkann, muss er nach seiner Wahl ein Recovery ausfuhren. Dazu gehort die Eroffnung einer neu-en Epoche, die Umfrage nach der neuesten DB-Version, mit der er sich darauffolgend abgleicht,die Deklaration seiner neuen Version als Null-Version und der Abgleich aller anderen Server mitdieser Version. Ein Recovery kann vom Koordinator auch zur Behebung von nicht auflosbarenProblemen durchgefuhrt werden. Dabei beenden alle anderen Server ihre ausstehenden Writes.Durch die nicht festgelegte Rollenverteilung kommunizieren die UBIK-Instanzen in einer P2P-ahnlichen Weise, was zwar grundsatzlich die benotigte Bandbreite erhoht, aber zu einem toleran-teren Umgang mit Serverausfallen fuhrt.Der gesamte Algorithmus ist dafur ausgelegt, eine geringe Anzahl von Writes (max. 1/sec) abereine mittlere bis hohe Anzahl von Read (10-100/sec) verarbeiten zu konnen. Dabei wird grosserWert auf starke Konsistenz gelegt.Wenn dieser Algorithmus im Backend eines LDAP-Servers angewandt wird, ergeben sich aller-

25

dings einige Probleme:Die zugrundeliegende Datenbank (hier Berkeley DB) bildet zwar eine mogliche Grundlage derLDAP-Baumstruktur, diese ist aber nicht direkt ansprechbar, sodass die Replikation von Tei-len des Naming Contexts nur unter grossem Aufwand und einer Erweiterung des Algorithmus’moglich ist. Dazu mussten entsprechende Filter und Attributlisten implementiert werden, die beijedem Replikationsvorgang zu beachten sind. [UBIKAFS]

4.2.2 UBIK-Implementierung der Carnegie Mellon University

Den gleichen Grundalgorithmus nutzt auch die Implementierung der CMUbik-Bibliothek, diejedoch fest an die BerkeleyDB gekoppelt ist. Eine BDB-ahnliche API erlaubt es, Datenbank-operationen so vorzunehmen, als gabe es nur eine lokale BerkeleyDB. Der UBIK-Mechanismusverteilt jedoch - transparent fur den Nutzer - die Daten an alle Server im Quorum. Die Aktualitatwird hier durch eine Quorum- und eine Datenbankversion festgehalten: Bei jeder Neuwahl erhohtsich die Quorumversion um 1, wahrend sich die Datenbankversion bei jedem Update erhoht,aber bei einer Neuwahl zuruckgesetzt wird.Ein Configfile namens ubik.conf beinhaltet unter anderem eine Liste von Hosts, die die Mengealler potentiellen Quorummitglieder festlegt, also den Serverpool darstellt. Diese Liste muss beijedem teilnehmenden Host gleich sein, weil das einzige Kriterium zur Wahl des Masters die Positi-on in dieser Liste ist (vordere Eintrage haben Prioritat). Die Hosts kommunizieren untereinanderuber das UBIK-Protokoll, das aus Kommandos fur den Wahlvorgang (VOTEFORME, VOTE YES,VOTE NO), zur Authentifiziereng (AUTH*), zur Ubermittlung der Version (ASKVERSION, MYVER,VERIS), zur Quorumdeklaration (QUORUM WRITE, QUORUM NULL) und zur Synchronisation selbst(GIMME(Give Database), W(rite), FORWARD(Write), SWITCHDBS) besteht.Bekommt ein Host mehr als n/2 VOTE YES Stimmen, weil er unter den i Servern die niedrigsteHostlistenposition hat, deklariert er ein QUORUM NULL und fragt mittels ASKVERSION alle Hostsnach ihren Versionen. Vom Host mit der grossten Kombination aus { Quorumversion, Database-version } bezieht er mitteln GIMME die aktuelle (komplette) Datenbank. Anschliessend deklarierter ein QUORUM WRITE, woraufhin alle anderen Hosts die an sie gerichteten Writes an die gewahlteSynchronization Site (SS) FORWARDen. Diese werden von SS in die Datenbank geschrieben undmit SWITCHDBS und W(riteoperationen) an die anderen Hosts verteilt.Ein die UBIK-API nutzendes Programm kann nur lesend und schreibend auf die Datenbankzugreifen, wenn sich die lokale UBIK-Instanz in einem Writequorum befindet. Der Hintergedankefur das Leseverbot ist, dass die lokale Instanz wegen eines Netzproblems ein existierendesQuorum nicht erreichen kann und deswegen veraltete Daten, die im Quorum aktueller seinkonnen, liefern wurde.Auch hier findet sich wieder das Problem, dass, selbst wenn openLDAP mit einem BDB-Backendarbeitet, eine Replikation von Teilbaumen nur unter grossem Aufwand implementierbar ist.

Beide UBIK-Implementierungen setzen auf die Repliaktion der unterliegenden Datenbank. Siearbeiten grundsatzlich mit dem selben Algorithmus, der jedoch nicht fur den Einsatz als LDAP-Replikationsmechanismus konzipiert wurde. Die Zuverlassigkeit der AFS-Variante hat sich auf-grund des weltweiten Einsatzes gezeigt, wahrend sich die CMUbik-Variante noch im Entwick-lungsstadium befindet. Durch die anfangliche Ubertragung des gesamten Datenbestandes beimMasterwechsel sind beide Varianten nicht besonders bandbreitenfreundlich, was bei grossen Da-tenmengen und langsamen Abbindungen zwangsweise zu starken Verzogerungen fuhrt. Somitist der Einsatz in WAN-Umgebungen bei haufigen Serverausfallen nicht zu empfehlen, was imAFS-Umfeld ohnehin nicht unbedingt vorgesehen ist. In LAN-Umgebungen, in denen ausreichendBandbreite zur Verfugung steht, kann der Algorithmus hingegen seine Vorteile ausnutzen, die inder gesicherten Konsistenz und der Toleranz gegenuber Serverausfallen liegen. Da es sich hierbei

26

um keine spezifische Verzeichnisreplikation handelt, sondern vielmehr um einen Mechanismus zurSynchronisation von Datenbanken, wurde der Grundsatz, dass Schreibzugriffe eher selten statt-finden, nicht in Betracht gezogen. Daher ist der Algorithmus sowohl fur die Entgegennahme vonhaufigen Anderungen als auch fur der Verabeitung von grossen Update-Datenmengen optimiert.

4.3 Andere Modelle

4.3.1 Bayou

Xerox PARC’s Bayou Projekt wurde entworfen, um die Zusammenarbeit zwischen Nutzern zuermoglichen, die nicht dauerhaft uber ein Netzwerk miteinander verbunden sind. Es beruht aufdem Multi-Master-Prinzip. Deswegen unterstutzt Bayou schwache Konsistenz, was bedeutet, dassnicht zu jedem Zeitpunkt alle Server erreichbar und somit synchronisiert sein mussen. Es mussnur gewahrleistet sein, dass in endlicher Zeit ein Abgleich zwischen allen Servern stattfindet (end-liche Konsistenz). Der Synchronisationsprozess selbst findet immer nur zwischen 2 Servern statt(Anti-Entropie-Protokoll). Bei mobilen Geraten (Laptops...) wird der Vorteil dieses Systems vollausgenutzt: Sie brauchen neben dem Klienten noch einen lokalen Bayou-Server, der sich beimVerbinden mit dem Netz mit den restlichen abgleicht. Bis dahin wird nur dieser lokale Serverzum Lesen und Schreiben benutzt. Um den Abgleich zu ermoglichen, ist die Einteilung von Wri-tes in mehrere Schritte notig. Der Dependency Check pruft, ob ein konfliktloses Ausfuhrender gewunschten Schreiboperation moglich ist. Der Update Set beinhaltet die eigentlichen aus-zufuhrenden Operationen. Der dritte Schritt ist die Merge Procedure. Sie stellt ein Templatebereit, das Regeln fur die Auflosung von moglichen Konflikten beinhaltet. Jede Applikation, diediese Prozedur aufruft, kann sie mit eigenen Daten instanziieren und somit Konflikte aus eigenenAnderungen entfernen. Der Server bekommt also nur Informationen, welche Daten er andern soll,welche Bedingungen dabei einzuhalten sind und wie Konflikte aufzulosen sind.Jede lokale Anderung wird in einem Write-Log zusammen mit einem Zeitstempel und dem Ser-vernamen hinterlegt. Nach der lokalen Ausfuhrung werden die gleichen Informationen zusatzlichin ein Undo-Log geschrieben. Wenn sich anschliessend zwei Server synchronisieren, und von derGegenseite Updates mit einem fruheren Zeitstempel empfangen werden, so mussen diese auchan der lokalen Datenbasis vorher ausgefuhrt werden. Dazu werden zuerst die lokalen Updatesruckgangig gemacht, die zeitlich nach den empfangenen Updates liegen. Dann werden beide Up-datesequenzen zeitlich geordnet und erneut ausgefuhrt. Jeder der beiden Server fuhrt also letztlichdie selbe Updatesequenz aus.Da Anderungen erst wirklich fest vorgenommen werden konnen, wenn alle Server synchronisiertsind (weil jeder Server Updates enthalten kann, die mit bereits ausgefuhrten Anderungen inKonflikt stehen), kann es bei manchen Anwendungen, die dauerhaft fixe Daten benotigen, zuProblemen kommen. Dazu bietet Bayou den Einsatz eines Primary Servers an, der diese tentati-ven (ausstehenden)Writes zu stabilen Writes machen kann. Nach dieser Aktion werden fremdeUpdates, die zeitlich vor der nun stabilen Anderung liegen, danach ausgefuhrt, sodass die stabilenAnderungen auf jeden Fall nicht ruckgangig gemacht werden.Die Implementation des Bayousystems besteht aus 2 Komponenten:

• Client Stub - Laufzeitbibliothek, die mit der eigentlichen Applikation verlinkt ist;besitzt Mechanismen zur Serverlokalisierung, Implementierung von Session Guarantees,unterstutzt Secure Sessions, Read und Write Operationen and verschiedene Utilities.

• Server - der Datenbasisserver, beinhaltet Mechanismen zur Konfliktfindung und -auflosung,Server-Server-Kommunication und Database Management.

Die Kommunikation zwischen Client und Server findet uber ein plattformunabhangiges RPC-Package statt.

27

Die unterliegende Datenbank ist nicht festgelegt, muss aber folgende Eigenschaften vorweisen:

• Speichereffizientes Write logging

• Effizientes Undo/Redo von Schreiboperationen

• Moglichkeit zur Unterscheidung zwischen Committed Data (verbindlich) und Tentative Da-ta (provisorisch)

• Support fur Server-Server Antientropie

[BAYOU][XEROXBAYOU]Der Einsatz dieser Implementierung ist vorwiegend in WAN-Umgebungen vorteilhaft, in denendial-up-Klienten sowohl eingene Anderungen publizieren als auch Informationen (Daten) ande-rer Endnutzer verarbeiten wollen. Der grosse Vorteil liegt hier in der Unterstutzung von nichtdauerhaft aktiven Rechnern, deren Datenbanken trotzdem letztlich synchronisiert werden. Durchden Einsatz einer Variante der Multi-Master-Konstellation ist die Abwesenheit einzelner Server(Rechner) unproblematisch, was allerdings auch die erwahnte potentielle Gefahr eines deadlocksmit sich bringt. Haufige Anderungen an verschiedenen Hosts verursachen beim Abgleich zwischenihnen durch die Nutzung des Anti-Entropie-Verfahrens eine hohe Rechen- und Bandbreitenlast,zumal eigene Anderungen ohne den Einsatz eines Primary Servers nie fest vorgenommen werdenkonnen, da sich jederzeit ein Host mit einem zuruckliegenden Update synchronisieren und damitdie eigenen Anderungen ruckgangig machen kann kann.

4.3.2 Oracle

Die Datenbank Oracle besitzt mehrere Replikationsmethoden. Die einfachste , Read-Only-Snapshot genannt, dupliziert die gewunschten Datenbanken / Tabellen auf einen anderen Serverund updatet diese Kopien in bestimmten Zeitabstanden. Falls der Master eine Zeit lang unerreich-bar ist, wird der Snapshot als broken deklariert und ein manueller Refresh-Start ist notig, um dieReplikation fortzusetzen. Alternativ kann auch in einem solchen Fall eine komplette Neuubert-ragung getriggert werden, was bei grossen Datenbanken aber zu starker Netzlast fuhren kann.Diese Methode arbeitet also nach dem Single-Master-Prinzip.Eine weitere Moglichkeit ist die sogenannte Advanced Replication und arbeitet im Multi-Master-Modus, was auch hier unweigerlich zu Konflikten fuhren kann. Jedoch werden diese hier durchentsprechende Mechanismen aufgelost oder durch manuelles Triggern der Synchronisation mitparallelem Verteilen der Transaktionen verhindert. [ORACLEREP]Oracle kann zwar als Backend fur openLDAP (back-sql) verwendet werden, die Einschrankungauf ein bestimmtes Backend wurde jedoch der Universalitat widersprechen. Desweiteren sind auchhier Teilbaume nicht ohne weiteres in die SQL-Datenbank abbildbar.

4.4 Replikationsmedium

Die Replikation kann auf verschiedenen Ebenen vorgenommen werden, die sich in ihrer Abstrak-tion der Daten unterscheiden. Das einfache Kopieren von Datenfiles ist wohl die einfachste Artdes Abgleichs, wenngleich sie wenig effizient im Umgang mit Ressourcen ist. Eine Stufe hoherware der Vergleich von Datenfiles mit anschliessendem Austausch der Unterschiede anzusiedeln(Stichwort diff ), was den Umgang mit der Bandbreite erheblich verbessert, aber dafur die Re-chenleistung stark fordert.Die Strukturierung der Daten in Datensatze ist ein entscheidendes Merkmal von Datenbanken.Damit wird es in der nachsten Stufe moglich, beim Vergleich der Daten ihre Semantik (Bedeutung,Zusammenhang) zu nutzen, durch die Referenzierung von Datensatzen mittels IDs Bandbreite

28

zu sparen aber auch die Daten durch den optimierten Suchalgorithmus schneller finden und ver-gleichen zu konnen. Die Replikation der Daten auf Datenbankebene wird zum Beispiel beimUBIK-Algorithmus der CMU angewandt, der ausschliesslich mit der BerkeleyDB von Sleepycatzusammenarbeitet.LDAP kann verschiedene Backend-Datenbanken nutzen. Dazu zahlen unter anderem BerkeleyDB,SQL oder gdbm. Wie im LDAP Datenmodell bereits beschrieben, werden LDAP-Daten als Entriesverwaltet, die ihrerseits in die Backend-Datenbank abgebildet werden, also eine weitere Abstrak-tion hin zu LDAP erfahren. Die Replikation auf dieser Ebene bringt weitere Vorteile mit sich, dahier die Semantik der Daten durch Objekt- und Attributklassen genau bekannt ist. Das hat unteranderem zur Folge, dass Teile des Gesamtdatenbestandes exakt durch Merkmale wie Basisknotenoder Attributlisten beschrieben werden konnen. Somit ist auch die Replikation von Teilbaumenoder ausgewahlten Attributen (Thema Datenschutz) moglich. Als Beispiel ware hier die Replika-tion mittels slurpd oder LDAP-sync zu nennen.Am geeignetsten fur unser Vorhaben ist also die Synchronisation auf LDAP-Ebene, zumal dieopenLDAP-Implementation ja weitestgehend backendunabhangig entworfen wurde und ein Ab-gleich auf einer der unteren Abstraktionsebenen diese Unabhangigkeit stark eingrenzen wurde.

4.5 Eignung der Moglichkeiten

In diesem Abschnitt sollen mehrere der aufgefuhrten Replikationsarten auf ihre Eignung fur dieServer-Server-Synchronisation von openLDAP untersucht werden.Da wir im letzten Abschnitt festgestellt haben, dass die Synchronisation uber das LDAP-Datenmodell die meisten Vorteile mit sich bringt und die Teilbaumreplikation nur durchdiese Abstraktion ermoglicht wird, bleiben damit nur die bereits vorhandenen LDAP-Replikationsmechanismen LDAPsync und slurpd sowie ixSync zur Auswahl.Da es sich bei letzterem um eine kommerzielle Losung handelt, fallt auch diese Moglichkeit furdiese Arbeit weg. Die beiden LDAP-Replikationsmechanismen arbeiten beide uber das Single-Master Prinzip, erfullen damit also allein nicht die geforderten Bedingungen.Bezuglich des Replikationsmodells stellt meiner Meinung nach UBIK das Optimum dar, da hierdie Vorteile sowohl des Single-Master-Modells (keine Konfliktentstehung bei gleichzeitigen Up-dates) als auch der Multi-Master-Modells (kein Single Point Of Failure) kombiniert werden. DerNachteil hier ist allerdings, dass die bisherigen Implementationen bei der Wahl des Datenmodellsrecht unflexibel sind und nicht ohne weiteres auf eine Verwendung mit dem openLDAP Serverportierbar sind.Zusammenfassend lasst sich sagen, dass eine Kombination des LDAP-Datenmodells und desUBIK-Replikationsmodells am besten geeignet ist, um die gewunschten Anforderungen zuerfullen.

29

5 Untersuchung der Mechanismen und Modellentwurf

5.1 Bewertung und Wahl der Mechanismen

5.1.1 LDAP-slurpd / LDAP-sync

Aus der Beschreibung des slurpd-Mechanismus ist zu erkennen, dass der dortige Master (M) nocheinen weiteren Prozess benotigt (den slurpd) um die Slaves (Si) mit Updates zu versorgen. FalltM, oder auch nur einer seiner beiden Komponenten, aus, ist der Replikationsvorgang solangeunterbrochen, bis wieder beide Prozesse von M laufen. Um hier uberhaupt einen Masterwechselveranlassen zu konnen, musste jeder Server in der Lage sein, einen eigenen slurpd zu starten,um mit dessen Hilfe alle anderen Server mit Updates versorgen zu konnen.Die Slaves allein sind ausserdem nicht in der Lage, einen Ausfall des Masters zu bemerken, dadie Kommunikation nur von M ausgeht (Slaves listens for changes): meldet sich ein Masternicht mehr, weil er unerreichbar oder abgesturzt ist, gehen die Slaves davon aus, dass es nurkeine neuen Updates gibt, die der Master liefern konnte. Es musste also zusatzlich noch einentsprechender Mechanismus erstellt werden, der Ausfalle erkennt.

Der Sync-Master hingegen benotigt keine zusatzlichen Module, um Slaves mit Updates zuversorgen, die ja ihrerseits eine Klientenrolle gegenuber M einnehmen. Eher noch liegt hier derMehraufwand, zumindest im RefreshOnly Mode, beim Slave, der in festgelegten Abstandeneinen sync-Request an den Master schickt (Slave polls for changes). Dadurch ist er ohne weiteresin der Lage, Masterabsturze zu registrieren, wenn auch unter Umstanden in nicht-akzeptabler(Request-Intervall-) Zeit.Im RefreshAndPersist Mode wird ahnlich wie beim slurpd der Slave aktiv mit Updates versorgt(Slave listens for changes), ohne dass M zusatzliche Prozesse benotigt. Im Gegensatz zumslurpd -Mechanismus wird ein Masterausfall von den Slaves erkannt, da in diesem Fall ihrepersistente Verbindung unterbrochen wird.Der sync-Mechanismus bietet die Moglichkeit, mehrere Server zu kaskadieren. Bei dieser Varianteubernimmt ein Server die Rolle des alleinigen Masters, wahrend einige von seinen Slaveswiederum fur andere Server die Masterrolle ubernehmen, sodass Anderungen langsam bis zumletzten Slave durchsickern. Aber auch hier darf nur der oberste Master Schreiboperationenvornehmen, da ansonsten unauflosbare Inkonsistenzen auftreten konnen. Wenn jeder kaskadierteMaster beliebige Anderungen vornehmen konnte, die der Obermaster nicht mitbekommt (weilER ja der Master ist), wurde er diese beim nachsten Update unweigerlich ruckgangig machen,da er seinen Datenbestand ja fur authoritativ halt. Aufgrund dieser Tatsachen ist auch derSync-Mechanismus allein nicht in der Lage, die geforderten Bedingungen zu erfullen.Es ist also festzuhalten, dass weder slurpd noch sync allein die geforderten Bedingungenerfullen. Da aber LDAP-sync sowohl Polling als auch Listening beherrscht, die Replikation vonTeilbaumen erlaubt und eine gleichmassigere Aufgabenverteilung zwischen Master und Slaveimplementiert (was einen Wechsel zwischen S und M vereinfacht) ziehe ich diesen Mechanismusvor.

Es bedarf also noch zusatzlich folgender Erweiterungen, um die gewunschte Funktionalitat zuerreichen:

• Die Slaves benotigen eine sichere Ausfallerkennung des Masters innerhalb einer festge-legten Zeit (unabhngig vom Replikationsintervall), um entsprechend reagieren zu konnen

• Wenn der Master ausfallt, muss ein anderer Server seine Rolle ubernehmen(Wahl eines neuen Masters)

Der gesuchte Mechanismus muss dabei folgende Bedingungen erfullen:

30

• Der neue Master muss die gleiche Aktualitat haben wie der vorherige Master

• Der neue Master muss, genau wie sein Vorganger, den Gesamtkontext aller Slaves enthalten,um alle mit entsprechenden Updates versorgen zu konnen; der Algorithmus muss also inder Lage sein, einen Server nur im Falle der Datenvollstandigkeit als Master zuzulassen

Der Abgleich der Datenbanken NACH der Wahl eines neuen Masters kann von LDAP-sync uber-nommen werden.

5.1.2 UBIK

Der einzige Algorithmus, der einen Grossteil dieser o.g. Erweiterungen implementiert, ist UBIK:Auch hier stehen wieder 2 Varianten zur Auswahl: UBIK-Implementierung von openAFS unddie CMUbik-Bibliothek. Die Spezifikation besagt, dass der Master nach seiner Wahl alle Slavesnach ihren Versionen fragt und sich die hochste liefern lasst, bevor er seine Koordinatorrolleantritt. Anschliessend nimmt er Schreibauftrage an und leitet diese an die Slaves weiter. Falltder Master aus oder kann der Master zu irgendeinem Zeitpunkt nicht mehr als die Halfte derServer erreichen, findet eine Neuwahl statt bzw. verliert der Master sein Schreibrecht.In userem Fall soll aber LDAP sync die Synchronisation ubernehmen, sodass der UBIK-Teil, derden Datenabgleich vornimmt, uberflussig wird. Wir benotigen nur den Voting-Mechanismus, derfur jede Serverkonstellation einen eindeutigen Master findet.In genau diesem Punkt unterscheiden sich die beiden Implementierungen gravierend. CMUbiknutzt die Hostliste, die bei jedem Server gleich sein muss, um jedem Server eine quorum-weiteeindeutige ID, namlich seine Position in der Hostliste, zuzuweisen. Der Server mit der niedrigstenID, der VOTEFORME-Anfragen aussendet, wird von anderen zum Master gewahlt, naturlichmehr als n/2 VOTE YES Antworten vorausgesetzt.Die openAFS-UBIK-Variante nutzt zusatzlich noch einige andere Kriterien, die zwar dieEffizienz erhohen, aber auch die Gefahr von VOTING-Deadlocks vergrossert. Dazu zahlt zumBeispiel die Bevorzugung von fruher gewahlten Servern, die zwar einen Datenabgleich vor derKoordinatorrollenubernahme verhindern kann, wenn der vorherige Master erneut gewahlt wird,aber in ungunstigen Fallen dazu fuhren kann, dass von mehreren Servern verschiedene Masterbevorzugt werden und dadurch keine Entscheidung zustande kommt.Aus diesem Grund habe ich mich dafur entschieden, die einfachere aber auch sicherere VarianteCMUbik zu verwenden.Im folgenden soll untersucht werden, inwieweit die CMUbik-Implementation unseren Anforde-rungen entspricht und wo Anderungen vorgenommen werden mussen.

Erfullte Forderungen:

• Ausfallerkennung wird durch das Ausbleiben von Lebenszeichen (beacons) erkannt

• Die Wahl eines neuen Masters wird durch den UBIK-voting Mechanismus implementiert

Teilweise erfullte Bedingungen:

• Die ursprungliche Variante von UBIK garantiert die Aktualitat des neuen Masters,da sich dieser nach abgeschlossenem Voting die neueste Datenbankversion beschafft.Da beim UBIK-Algorithmus mehr als die Halfte aller Server verfugbar sein mussen, ist zujedem Zeitpunkt garantiert, dass mindestens einer die neueste Version besitzt.Weil die Daten hier aber nicht auf der Datenbankebene (Schlussel-Wert-Paare), sondernaus LDAP-Sicht (verzeichnisorientierte Datenverwaltung) zu behandeln sind (StichwortTeilbaumreplikation), sollte sich das Attribut Aktualitat auf den Inhalt des Verzeichnis-ses beziehen.

31

Nicht erfullte Bedingungen:

• Die reine Datenreplikation, wie sie UBIK implementiert, benotigt kein Wissen uber derInhalt den Datenbank, weil hier die Datenbankfiles 1-zu-1 repliziert werden.Deswegen ist es UBIK auch nicht moglich, zu entscheiden, ob eine Kopie der Datenbankvollstandig ist oder nicht (ob ein Server den Gesamtkontext oder nur einen Teilbaum ver-waltet). Es fehlt also ein Mechanismus, der nur Server mit vollstandigem Kontext alspotentielle Master zulasst.

Da die Aktualitat der jeweiligen Daten mit dem bereits vorhandenen LDAP-ContextCSN ausrei-chend beschrieben wird und durch die Auswertung von slapd -Parametern auch uber die Master-tauglichkeit bezuglich der Datenvollstandigkeit eine Aussage gemacht werden kann, sind durchdie Kombination von UBIK und sync alle Anforderungen erfullbar.

5.2 Modellentwurf

Um LDAPsync und CMUbik kombinieren zu konnen, muss zuerst die Aufgabenverteilung zwi-schen beiden genau definiert werden.

5.2.1 Aufgabenverteilung

Allgemeine Aufgaben UBIK:

• Wahl eine Masters wenn mehr als n/2 Server im Quorum sind

• Erkennen von Serverausfallen und Auflosen des Quorums bei weniger als n/2 Servern

• Mitteilen der Serverrolle und des neuen Masters an LDAP

• Mitteilen, wenn kein Quorum zustande gekommen ist

Allgemeine Aufgaben LDAPsync:

• Starten von UBIK

• Wenn slapd zum Slave gewahlt wurde

– soll er sich fortan mit neuem Master synchronisieren– darf er keine Schreiboperationen mehr selbst annehmen, sondern muss sie an den

Master weiterleiten

• Wenn slapd zum Master gewahlt wurde

– darf er sich fortan mit keinem Server synchronisieren– muss er an ihn gerichtete Schreiboperationen verarbeiten

• Wenn kein WriteQuorum existiert

– darf er sich fortan mit keinem Server synchronisieren– Darf er weder Lese- noch Schreiboperationen annehmen

32

Abbildung 5: Grundmodell

5.2.2 Anpassung der Aktualitatskriterien

Wie zu erkennen ist, benotigen wir nur den Teil des UBIK-Algorithmus’, der den Wahlmecha-nismus implementiert. Dieser funktioniert in der CMUbik-Variante folgendermassen:

1. Wenn Host A startet, versucht er sich mit allen Hosts in der Hostliste zu verbinden

2. Es antworten die Hosts X={Host1..Hostn} aus der Hostliste, die zu diesem Zeitpunkt laufen

3. Die Hosts Xi nehmen die Verbindung von Host A an und bestimmen seine Hostlist-Position(ID)

4. Nun sind die Hosts Y = {X}+A miteinander verbunden

5. Wenn Host Yi unter allen die niedrigste ID hat, pruft dieser, ob mehr als n/2 Hosts mitihm verbunden sind

6. Ist dies der Fall, deklariert er ein Null-Quorum und fragt alle Server nach ihrer Quorum-und Datenbankversion sowie nach einer Stimme fur das NullQuorum

7. Bekommt er daraufhin mehr als |Y| / 2 Stimmen, bezieht er die komplette Datenbank vondem Host mit der hochsten Quorum- und zweitrangig hochsten Datenbankversion

8. Ist er damit fertig, ubernimmt er die Rolle der Synchronisation Site (Koordinatorrolle) imneuen Write-Quorum

9. Alle anderen Hosts synchronisieren ihre Daten ab jetzt inkrementell mit der SynchronisationSite

Bis zu Punkt 6 konnte diese Vorgehensweise ohne Anderungen ubernommen werden. Schritt7 scheint aber fur grosse Datenbanken (LDAP-Verzeichnisse) relativ ungeeignet, vor allembei Szenarien, die die Synchronisation uber WAN-Umgebungen verlangen. Auch der zweifacheWechsel zwischem Provider- und Consumerrolle, einmal vor dem Abgleich der neuen SyncSitemit der aktuellsten Datenbank und zum zweiten vor dem Einnehmen der SyncSite-Rolle,erscheint recht umstandlich und im Zusammenhang mit openLDAP wenig geeignet.Es ware sinnvoll, die Datenbankversion in der Datenbank selbst zu speichern, um nach einemeventuellen Absturz nur die Anderungen seit dem Absturz aktualisieren zu mussen. Sie sollte

33

unabhangig davon, ob der Server vor dem Absturz Master oder Slave war, seine Aktualitat derDaten wiederspiegeln.

OpenLDAP benutzt zu diesem Zweck ein Attribut namens ContextCSN, dass einen Zeitwertder Form

20050222194107entspricht YYYYMMDDhhmmss also 22.02.2005 19:41:07

speichert.Es ist in einem DSAOperation-Entry der Klasse SyncProviderSubentry untergebracht, derseinerseits ein direktes Kind des BaseDN ist und selbst den DN ”cn=ldapsync,< BaseDN >“hat. Dieser Entry existiert bei jedem Server der zu irgendeinem Zeitpunkt einmal Master in einersync-Konstellation war und ist der Maximalwert aller EntryCSN’s im Kontext (bereitgestelltenLDAP-Baum) des Servers. Ein EntryCSN ist ein Attribut, das in jedem Entry existiert und denTimestamp der Erstellung des Entry’s angibt.Der ContextCSN wird in der sync-Umgebung folgendermassen genutzt:

1. Jeder Server (Master und Slave) muss eine eindeutige sync-ID ”rid“ besitzen

2. Wenn sich ein Slave S das erste Mal mit dem Master M synchronisieren will, stellt er eineentsprechende Suchanfrage an ihn

3. M erkennt die erstmalige Anfrage am Fehlen eines Cookies bei der Anfrage

4. M versorgt S mit dem kompletten Kontext (grosse Datenmengen !!!) und liefert anschlies-send seinen ContextCSN in Form eines Cookies der Form

csn=<Master-ContextCSN>,rid=<eigene rid>,sid=<eigene sid>

5. S speichert dieses Cookie als Kind des BaseDN’Sunter dem DN ”cn=syncrepl<eigene rid>,<BaseDN>“ also zum Beispielunter ”cn=syncrepl2 , o=University Of Michigan , c=us“Diese ebenfalls operationalen Entries werden SyncConsumerSubentries genannt.

6. Wenn sich S erneut mit M synchronisieren will, zum Beispiel weil es per Aktualisierungsin-tervall wieder so weit ist oder S neu gestartet wird, sendet er nun bei jedem sync-Request anM dieses Cookie mit. Die Verwaltung der <rid>’s dient dem Master im RefreshAndPersist-Modus zur Unterscheidung der Versionen verschiedener Slaves; im RefreshOnly-Modus wirddie <rid> ohnehin bei jedem Request mitgeschickt.

7. M erkennt dieses Cookie, sucht nur diejenigen Entries aus seinem Kontext heraus, derenEntry-CSN’s grosser als der CookieCSN sind und versorgt S nur mit diesen Anderungen

8. Anschliessend sendet er ein neu generiertes Cookie mit dem aktuellen ContextCSN an S

9. S nimmt die Anderungen vor und uberschreibt den entsprechenden SyncConsumerSubentrymit dem empfangenen Cookie

10. 6.-9. wiederholen sich

Die Aktualitat der Datenbank kann bei M also durch seinen ContextCSN ausgedruckt werden,wahrend sie beim Slave im SyncConsumerSubentry gespeichert wird. Man beachte, dass beimSlave der SyncConsumerSubentry den Zeitpunkt der Aktualisierung am Master angibt und nichtden Zeitpunkt, zu dem S die Updates vornimmt. Ansonsten hatte der Slave eine ”neuere“ Version,was bei spateren Betrachtungen zu Problemen fuhren wurde.Wir suchen aber eine Version, die sowohl bei Master als auch bei Slaves bestimmt werden kann,also unabhangig von der aktuellen Serverrolle ist.

34

Wenn der Server zuletzt Master war, ergibt sich:7

V = ContextCSN .

Wenn der Server zuletzt Slave war, ergibt sich

V = CSN(SyncConsumerSubentry).

Da bei einem Masterausfall mittles UBIK ein neuer Server zum Master gewahlt werden kann undsomit jeder Server sowohl einen SyncProviderSubentry (PSE) als auch einen SyncConsumerSub-entry (CSE) haben kann, ergibt sich fur die Version folgende Gesamtformel:

V = MAX(PSE,CSE).

Da dieser Wert, umgewandelt in einen Timestamp (type time t), die echte Aktualitat angibt undnicht, wie die DBVersion beim ursprunglichen UBIK-Algorithmus, relativ zu anderen Servern ist,kann damit auch die Quorum-Version wegfallen. Allerdings setzt das die genaue Zeitsynchronisa-tion zwischen allen Servern voraus (was aber fur die Auswertung der UBIK Quorum-Timeout-Zeitsowieso Bedingung ist).

7V=Datenbankversion eines Servers

35

5.2.3 Anpassung des VOTING-Mechanismus’

Wie wir bereits gesehen haben, bringt der Voting Mechanismus von UBIK einige unvorteilhafteEffekte mit sich. Einen Nachteil, die Komplettubertragung der Daten vom Server mit der maxi-malen Version SmaxDB zum neuen Master MminID , haben wir mit der neuen Versionierung bereitsausgeschaltet, denn MminID musste sich nur noch die Updates beschaffen, deren EntryCSN’s zeit-lich zwischen seiner Version und der Version von SmaxDB liegen.Der Nachteil, dass MminID zuerst in den Slave-Modus wechseln muss, um seine Daten zu aktua-lisieren, um danach in den Master-Mode zu gelangen, wahrend SmaxDB zuerst im Mastermodeseine Daten liefert, um danach im Slavemode seine entgultige Rolle einzunehmen, lasst sich auchumgehen. Es ware doch sinnvoll, wenn nicht der Server mit der kleinsten Hostlist-ID zum Ma-ster wird, sondern derjenige, der beim Votingvorgang ohnehin die grosste Version hat. Falls, wasder Normalfall sein sollte, mehrere Server diese maximale Version haben, sollte dann die Hostli-stenposition als zweite Bedingung genutzt werden, um einen eindeutigen Master zu bestimmen.Daraus ergibt sich folgender Algorithmus:

int lowest_host_with_biggest_version(){

maxdb = -1;hlpos = -1;for all Hosts i in Hostlist {

if (dbver (Host i) > maxdb) {maxdb=dbver (Host i);hlpos = i;}

}return(hlpos);

}

Den Server, der durch diese Funktion zuruckgegeben wird, nennen wir SmaxDBminPos Damitdieser Algorithmus funktioniert, mussen einige Bedingungen eingehalten werden:

• Jeder Server muss vor dem Voting die DBVersion von jedem anderen Server wissen, der lauft(diese wird beim UBIK-Algorithmus als Host-Attribut dbver in der Hostliste gespeichert)Das gilt auch, wenn ein neuer Server in das Quorum eintritt oder das Quorum verlasst,denn die bereits / noch vorhandenen Server mussen in einer eventuell folgenden Neuwahlmit ihrer aktuellen Version berucksichtigt werden.

• Wenn ein Server nicht mehr erreichbar ist (von ihm seit einer bestimmten Zeit kein UBIK-Kommando mehr empfangen wurde), muss dessen dbver in der Hostliste jedes Serverszuruckgesetzt werden, damit er nicht mehr als Master kandidieren kann. (Da wahrendeines WriteQuorums jeder Slave Si nur mit dem Master M kommuniziert, werden in Si

die Datenbankversionen aller Slaves ausser der eigenen zuruckgesetzt. Nur M kommuniziertmit allen Si’s und kennt daher alle Slaveversionen, die ihrerseits auch M’s Version kennen.)

Damit dieser Algorithmus zum gewunschten Ziel fuhrt, mussen weiterhin folgende Votingregelneingehalten werden::

• Ein Server sollte nur VOTEFORME-Messages broadcasten, wenn seine eigene ID beilowest host with biggest version() zuruckgegeben wird (gilt nur im VOTING State,dazu gleich mehr)

• Ein Server darf nur mit VOTE YES auf diesen Request antworten, wennlowest host with biggest version() die ID des fragenden Hosts zuruckgibt (gilt eben-falls nur im VOTING State)

36

Es ergibt sich jetzt die Frage, woher jeder Server die Datenbankversionen der ande-ren laufenden Server bekommt. Beim ursprunglichen UBIK-Algorithmus wurde erst nach{QuorumVersion,DBVersion} gefragt, nachdem der Master bereits feststand, also der Voting-Vorgang abgeschlossen war. Hier muss die Datenbankversion eines jeden Servers vor jederNeuwahl jedem anderen Server bekannt sein.

Dabei sind 6 Falle zu unterscheiden:

1. Ein erster Server aus der Hostliste startet− > keine Versionen werden erfragt

2. Ein bereits laufender Server nimmt eine Verbindung entgegen, ist aber in keinem Write-quorum− > er fragt den verbindenden Server nach seiner Version (die Versionen der bereits ver-bundenen Server hat er schon erfragt)

3. Ein bereits laufender Server nimmt eine Verbindung entgegen und ist bereits in einemWritequorum− > er fragt alle Server nach ihren Versionen (da sie sich wahrend des Writequorumsgeandert haben konnten)

4. Ein Server versucht beim Start eine Verbindung zu allen Servern aus der Hostliste aufzu-bauen− > er bekommt wegen (2/3) ein CMD ASKVERSION von jedem Server, er antwortetdarauf und sendet seinerseits ebenfalls ein CMD ASKVERSION an jeden dieser Server

5. Ein Server, der Master in einem Writequorum ist, sturzt ab− > Die Slaves bemerken das am Ausbleiben der Quorumerneuerung und fragen daraufhinjeden Host in der Hostliste nach seiner Version

6. Ein Server, der Slave in einem Writequorum ist, sturzt ab − > Der Master erkennt dies aneinem Quorum TimeoutEs konnte wahrend des letzten Write Quorums ein Server N hinzugekommen sein, dessenHostlistenposition niedriger ist als die des derzeitigen Masters O ist und der seine Da-tenbankversion auf den aktuellen Stand gebracht hat, sodass er (N) jetzt Master werdenmusste. Da aber die anderen Server seine aktualisierte Version nicht kennen, weil, wie bereitsbeschrieben, die Slaves nur die DBVersion des Masters kennen, werden sie trotzdem denalten Master (O) wahlen, was zu keinem Problemen fuhrt. Ausserdem verhindert das einenunnotigen Masterwechsel. Damit kann N also erst zum Master werden, wenn O ausfallt.

Um auch unnotige Masterwechsel bei einem existierenden WriteQuorum beim Hinzukommen ei-nes neuen Slaves (3) zu verhindern, zum Beispiel wenn SmaxDBminPos Slave im bestehendenWrite Quorum ist, weil er erst als Slave die aktuelle Version erhalten hat, wahlen alle Slaves,die in einem Writequorum eine VOTEFORME-Message vom Master erhalten, aus o.g. Grundenimmer diesen Master, auch wenn sie selbst SmaxDBminPos sind oder der derzeitige Master nichtSmaxDBminPos ist. Nur der neue Slave erkennt wegen (4), dass der Master nicht SmaxDBminPos

ist und votet deswegen mit VOTE NO. Da er aber nach einer gewissen Zeit (SMALL SECONDS)SmaxDBminPos als disconnected annimmt und damit seine Version aus der lokalen Hostlisteloscht, weil er keine Kommandos von ihm empfangt (er ist ja weiterhin Slave), fragt er nun deneinzigen Server, der VOTEFORME’s sendet (den Master), nach seiner Version. Dieser ist fur denneuen Slave nun erster Masterkandidat und deshalb votet er mit VOTE YES.Einzige Ausnahme ist ein beitretender Server, der sowohl die aktuelle Version als auch eine niedri-gerer Hostlistenposition als der bisherige Master hat, also SmaxDBminPos ist. In diesem Fall wahltjeder Slave wegen (3) den neu beigetretenen Server zum Master und verneint VOTEFORME-Messages des alten Masters. Zwar konnten die Slaves auch weiterhin den alten Master wahlen

37

(weil sie wissen, dass ein Writequorum besteht), der neue Server wurde jedoch fortlaufendVOTEFORME-Messages aussenden und den bisherigen Server nicht akzeptieren, weil er nichtweiss, dass bereits ein WriteQuorum besteht (und damit auch nicht, dass er die VOTEFORME’sdes Masters mit VOTE YES erwidern sollte). In einem solchen Fall scheint es einfacher, denMasterwechsel zu tolerieren, also den neuen Server Master werden zu lassen.Dadurch wird also nur ein neuer Master gewahlt, wenn die Bedingung i > n/2 zwischenzeitlichnicht oder zum ersten Mal erfullt war, der Master selbst ausfallt oder ein aktueller Server hinzu-kommt, der eine hohere Prioritat (niedrigere Hostlistenposition) hat.Um zu unterscheiden, ob sich ein Server in einem Quorum (Write- / Nullquorum) befindet odernicht, definiert UBIK einen internen Zustand namens Ubikstate. Er kann 3 Werte annehmen:VOTING

• Es laufen weniger als oder genau n/2 Server, die zusammen noch kein Writequorum bildenkonnen

• Es laufen seit kurzem mehr als n/2 Server, die gerade einen Master wahlen

• Der Master ist abgesturzt, woraufhin ein neuer gewahlt werden muss

WRITE QUORUM

• Es laufen mehr als n/2 Server und der Master wurde gewahlt

NULL QUORUM

• Aus einem bestehenden WriteQuorum sturzt ein Server ab, durch das entstehende Quorum-timeout deklariert der Master ein Nullquorum; Sobald er wieder genugend Stiimmen erhal-ten hat, deklariert er erneut ein WriteQuorum

Abbildung 6: Zustande eines UBIK-Servers

Der WRITE QUORUM-Zustand wird zusatzlich noch einmal in OTHER WRITE QUORUM (Slave in einemWritequorum) und in SS WRITE QUORUM (Master / Synchronization Site in einem Writequorum)unterteilt. Auch der VOTING-State benotigt eine Unterteilung in einen permanenten (VOTING) undeinen temporaren (VOTING TEMP) Zustand. Letzterer wird von den Slaves bei der Wahlabgabe furein Null- oder Writequorum zwischenzeitlich eingenommen.

38

5.2.4 Zustandsmapping

Im letzten Abschnitt wurden die interne Zustande von UBIK beleuchtet. Um ihnen entsprechendeAktionen des slapd zuordnen zu konnen, wird eine Abbildung des UBIK-Zustands auf eineninternen slapd -Zustand benotigt, der nur 3 Werte unterscheiden soll:

• VOTING : kein WriteQuorum existent

• MASTER : Server hat die Masterrolle in einem WriteQuorum

• SLAVE : Server hat die Slaverolle in einem WriteQuorum

Bei Start sollten sich sowohl ubik als auch der slapd im VOTING-State befinden. Wenn ein Servervon UBIK zur SynchronizationSite gewahlt wurde, er also den UBIK-Zustand SS WRITE QUORUMbesitzt, sollte der slapd die Masterrolle auf sync-Ebene einnehmen, was durch seinen ZustandMASTER angezeigt wird. In diesem Zustand sendet er fortwahrend CMD QUORUM WRITE’s an die an-deren UBIK-Instanzen, die ihrerseits im Zustand OTHER WRITE QUORUM sind. Die entsprechendlokalen slapd -Instanzen (Slaves) sollten sich in diesem Fall mit dem Master synchronisieren undnehmen deswegen den Zustand SLAVE ein. Wenn sie vom Master ein CMD QUORUM NULL empfan-gen, sollten sie zuruck in den slapd -Zustand VOTING wechseln, da dies das erste Anzeichen furdie Auflosung des Quorums bedeuten kann. Der Zustand VOTING TEMP findet im slapd keinerleiBeachtung

Abbildung 7: Zustandsmapping zwische n UBIK und slapd

5.2.5 Das Leseverbot

Beim CMUbik-Algorithmus verbieten Hosts, die in keinem WriteQuorum sind, den Usern dasLesen, weil sie netzwerkbedingt von einem eventuell existierenden Quorum getrennt sein konnten,und deswegen veraltete Daten ausliefern wurden.Diese harte Beschrankung ist zwar sinnvoll, wenn es unbedingt erforderlich ist, aktuelle Daten zuerhalten, schrankt aber auch die Nutzbarkeit der LDAP-Server stark ein. Wenn kein Netzproblemvorliegt und wirklich kein Writequorum existiert, konnten die Server ohne Bedenken ihre Datenausliefern, da es keine aktuellere Version gibt, weil die Daten in keinem Quorum aktualisiertwerden konnten. Und selbst wenn sie netzwerkbedingt von einem Quorum getrennt sind, istdie Wahrscheinlichkeit gross, das ein Klient Daten verlangt, die nicht im getrennten Quorumverandert wurden, da LDAP fur Daten entwickelt wurde, die selten geandert werden.Deswegen sollte zumindest eine Moglichkeit geschaffen werden, das Verbot von Leseoperationenbei Servern, die nicht in einem Writequorum sind, manuell aufzuheben.

39

5.2.6 Berucksichtigung von Teilbaumreplikationen

Ein Problem ergibt sich dann, wenn einige Server einen anderen Kontext haben als andere Server.Dies soll hier kurz anhand folgender Abbildung erlautert werden:Nehmen wir folgendes Szenario an: 8

Abbildung 8: Teilbaumreplikation

• S2 liegt in der Hostliste vor S1

• S2 wurde als Slave mit Master S1 synchronisiert, weil S1 eine aktuellere Version hatte

• S1 fallt aus

• S2 bemerkt den Ausfall des Masters und geht in den VOTING-State

• S1 wird neu gestartet

• da beide die gleiche Datenbankversion haben, gewinnt S2 das Voting, weil seine hlpos kleinerist

• nun wird also S2 zum (alleinigen) Master

• Da S2 den Teilbaum B nicht kennt, kann er fur diesen Kontext keine Updates entgegen-nehmen und S1 daher auch nicht mit Updates fur B versorgen. Somit sind Updates furB solange ausgeschlossen, bis wieder ein Server zum Master gewahlt wird, bei dem B imKontext liegt.

Um dieses Problem zu umgehen, sollten also nur Server zum Master gewahlt werden, die dieVereinigungsmenge der Kontexte aller Server in ihrem eigenen Kontext haben, oder andersgesagt, die jeden Teilbaum in ihrem DIT haben, der von einem anderen Server im Quorumbereitsgestellt wird. Weiterhin muss ein potentieller Masterserver auch den gesamten DITreplizieren, also seine sync-searchbase SBi muss dem Suffix Sui des Servers entsprechen.Das gleiche gilt auch fur Server, die zwar den gesamten Kontext replizieren, dafur aber nurausgewahlte Attribute in ihren Entries speichern (Stichwort Datenschutz/Sicherheitsrichtlinien).

8S = Server

40

Entry-Updates, die von diesen Servern als Slave empfangen werden, besitzen zwar den Zeitstem-pel der letzten Anderung des gesamten Entries, aber nur die zu replizierenden Attribute sindauf dem aktuellen Stand. Somit wurden sie als Master die restlichen Attribute ”unter falschenNamen“ ausliefern, also mit einem nicht zutreffenden Zeitstempel. Wenn der fruhere Masterdiese restlichen Attribute geandert hat, liefert der neue in dem Falle definitiv falsche Daten aus.Bei der normalen LDAP-sync Umgebung ist das kein Problem, da es keine Masterwechsel gibt,aber hier ist das ein Grund, auch solche Server nicht als Master zuzulassen.Die erwahnte Vereinigungsmenge aller Teilbaume sollte bei jedem Replikationsszenario einfixer Wert sein und kann somit als konstant angenommen werden. Im obigen Beispiel ist dieVereinigungsmenge der (Teil-)baume mit dem DN ”o=org1,c=de“ (der allgemeinste Suffix), wasbedeutet, dass S2 kein Master werden kann.Der gewahlte allgemeinste Suffix, nennen wir ihn ”common suffix“ Sucom , kann zum Beispielper Configfile festgelegt werden. Nur wenn folgender Algorithmus einem Server Erfolg meldet,kann er sich als Master bewerben.

int canbemaster(my_id){

if ((SUi == SUcom) && (SUi == SBi) && all_attrs_replicated)return YES;

else return NO;}

Nun weiss zwar jeder Server Si selbst, ob er VOTEFORME-Anfragen stellen darf, wenn er jedochder niedrigste Host mit hochster Version im Quorum SmaxDBminPos ist und die anderen Servernicht wussten, dass er kein Master sein kann, wurden sie ihn trotzdem zum Master wahlen,weil ja Si ihr Favorit ist. Die anderen Server mussten also daruber informiert werden, dass Si

nicht als Master zur Wahl steht, weil er obige Bedingung nicht erfullt. Diese Information kannzusammen mit der Version ausgetauscht werden und sollte ebenfalls fur jeden Host in der Hostlistegespeichert werden. Dadurch wurde sich der Algorithmus zur Bestimmung des bestgeeignetstenServers zum Master erweitern:

int lowest_host_with_biggest_version_that_can_be_master(){

maxdb = -1;hlpos = -1;for all Hosts i in Hostlist {

if (dbver (Host i) > maxdb) {maxdb=dbver (Host i);if (canbemaster (Host i))

hlpos = i;}

}return(hlpos);

}

Den Server, der durch diese Funktion zuruckgeben wird, nennen wir SmaxDBpotMminPos odereinfach Mreal

Nun ergibt sich aber folgendes Problem: Der UBIK-Algorithmus baut darauf auf, dass alleServer identische Dateninhalte haben. Die Annahme, dass mehr als die Halfte der Servermengeausreicht, um mindestens einen aktuellen Server zu enthalten, der Master wird, trifft hier nicht

41

mehr zu, da genau dieser eine aktuelle Server moglicherweise kein Master werden kann, weil erobige Bedingung nicht erfullt und deswegen ein nicht aktueller Server Master wird.

Um die Moglichkeit von Teilbaumreplikationen dennoch nutzen zu konnen, muss die Bedingungi > n/2 in j > n/2 geandert werden.

i = notwendige server, um ein Quorum zu bilden

j = notwendige server, um ein Quorum zu bilden,

die alle potentielle Master sein mussen

n = Anzahl der Server in der Hostliste

K = Menge aller Server, die potentielle Master sind ki ∈ Kak =

∣∣K∣∣Es stehen also nur noch ak von n Servern als Master zur Auswahl. Man beachte, dass mit jedemServer, der nicht Master werden kann, die Wahrscheinlichkeit fur ein Writequorum rapide ab-nimmt. Die Wahrscheinlichkeit PW fur ein Writequorum aus mindesten m von n Servern, die jeeine Zuverlassigkeit p besitzen, berechnet sich folgendermassen:

PW =∑

der Wkt aller Falle, in denen i ≥ m Server laufen

∣∣∣ m >n

2

p = Zuverlassigkeit eines Servers, zum Beispiel 0, 9H(i) = Falle, in denen genau i Server laufen

P (i) = Produkt der Wahrscheinlichkeiten p aller i laufenden Server

Q(i) = Produkt der Wahrscheinlichkeiten q=1-p aller (n-i) nicht laufenden Server

PW =i≥m∑i

H(i) · P (i) ·Q(i)∣∣∣ m >

n

2

=n−m∑i=0

(n

i

)· p(n−i) · (1− p)i

∣∣∣ m >n

2

PW = 1− PW= Wahrscheinlichkeit fur das Nichtzustandekommen eines Writequorums

Wenn zum Beispiel nur 2 von 8 Servern einen Teilbaum replizierenmussen statt 5 von 8 Servern 5 von (8-2) als 5 von 6 Servern laufen.

P5/8 =8−5=3∑i=0

(8i

)· 0.9(8−i) · (0.1)i = 0, 430 + 0.383 + 0, 149 + 0, 033 = 99, 5%

P5/6 =6−5=1∑i=0

(6i

)· 0.9(6−i) · (0.1)i = 0, 531 + 0, 354 = 88, 5%

Damit ist die Wahrscheinlichkeit fur das Nichtzustandekommen eines Writequorums rund 23mal so hoch. Auch bei hoherer Serverzahl ist eine relativ grosse Wahrscheinlichkeitsabnahme zu

42

beobachten, zum Beispiel wenn 3 von 25 Servern Teilbaume replizieren:

P13/25 =12∑i=0

(25i

)· 0.9(25−i) · (0.1)i ≈ 100%

P13/22 =9∑i=0

(22i

)· 0.9(22−i) · (0.1)i = 99, 931%

Diese Zahlen wurden mit dem beigelegten Programm n of m berechnet, das auch im Rahmendieser Arbeit entstand.Es ergibt sich nun die Frage, ob Nicht-Master-Kandidaten trotzdem wahlberechtigt sind. Dazuwieder ein Szenario:

• In einer Hostliste sind 10 Server angegeben (n=10)

• Zum Zeitpunkt t0 laufen 5 Masterkandidaten (m=5) , sie konnen kein Quorum bilden, weildie Bedingung m > n/2 nicht erfullt ist

• Zum Zeitpunkt t1 startet ein Nicht-Master-Kandidat N und votet fur SmaxDBminPos

• SmaxDBminPos eroffnet aber trotzdem kein Writequorum, weil m > n/2 immer noch nichterfullt ist

Wie man sieht, ist die Stimme von N wertlos. Da aber beim vorliegenden UBIK-Algorithmus nurdiejenigen Hosts eine Benachrichtigung uber ein entstandenes Writequorum bekommen, die denMaster auch gewahlt haben, muss N trotzdem seine Stimme abgeben.Um also die Teilbaumreplikationen zu ermoglichen, muss

• ein common Suffix im Configfile aufgenommen werden und mit dem Datenbanksuffix undder searchbase verglichen werden, sowie die zu replizierenden Attribute untersucht werden,um zu entscheiden, ob M ein potentieller Master ist

• eine neue Bedingung geschaffen werden, damit ein Server sich zur Wahl stellen kann - furVOTEFORME(er muss neben der maximalen Version und der minimalen Hostlistenposition auch nochpotentieller Master sein)

• eine neue Bedingung fur die Wahl eines Masters eingehalten werden - fur VOTE YES(M muss neben der maximalen Version und der minimalen Hostlistenposition auch nochpotentieller Master sein) Das gilt nur, wenn sie sich im VOTING-State befindenn (siehevorheriger Abschnitt)

• eine neue Bedingung fur die Deklaration eines Writequorums erstellt werden - furQUORUM WRITE(es durfen nur VOTE YES-Stimmen von potentiellen Mastern gezahlt werden, um m zuberechnen mit m > n/2)

• jeder Server seine Master-Eigenschaft allen anderen mitteilen - fur MYVER

5.2.7 Klientenbenachrichtigung

All diese Massnahmen haben wenig Sinn, wenn kein Klient (Nutzer) auf diese Daten zugreift. DieGrundkonfiguration sieht in solch einer Umgebung normalerweise so aus:

• Klienten in einem LAN kontaktieren den lokalen LDAP-Server

• Klienten, die nicht dauerhaft vernetzt sind (beispielsweise ppp-Klienten) kontaktieren einenfest konfigurierten Server

43

Abbildung 9: Klientenszenario

Die Aktionen, die ein Klient beim Server veranlassen kann, lassen sich in 3, fur diese Arbeitrelevante Hauptgebiete aufteilen:

• Write (hinzufugen, andern, loschen, verschieben)

• Read (lesen, suchen, vergleichen)

• Authorization

Da es sich hierbei um eine Single-Master-Umgebung handelt, und der Master als einziger schreib-berechtigt ist, besteht die erste Aufgabe darin, die an die Slaves gerichteten Writes an den Masterumzuleiten. In Abb. 7 mussten also slapd A und slapd B Writes von ihren Klienten an slapd Cweiterleiten, welcher dann nach ihrer Ausfuhrung A und B per LDAP-sync updated.Im slapd -Konfigurationsfile slapd.conf gibt es zu diesen Zweck fur Replacation-Slaves einSchlusselwort namens updateref. Die dort angegebenen LDAP-URLs definieren die Server, andie die Updates weitergeleitet werden sollen und werden als Attribut des fur die Replikation de-finierten Backends gespeichert.In unserem Fall ist hier nur eine URL notig, und zwar die des Masters. Da dieser Master jenach Konstellation ein anderer Server sein kann, muss dieser Eintrag dynamisch geandert wer-den konnen. Diese URL der Form <protocol>://<host>[:<port>] konnte in Standardfallen(protocol=LDAP, port=389) aus den Eintragen der UBIK-Hostliste generiert werden, was aller-dings die Flexibilitat stark einschranken wurde. Auch das fixe Mapping zwischen Hostlisteneintragund LDAP-URL bringt den Nachteil mit sich, dass beispielsweise bei einer Anderung des Proto-kolls eines Servers dieses Mapping bei allen Servern geandert werden musste.Sinnvoller ware es, wenn der Master nach erfolgreicher Wahl allen Slaves seine LDAP-URL mit-teilt, die ihrerseits diese URL als Update-Referral im entsprechenden Backend (und als provider-URL) speichern. Da die UBIK-SyncSite (Master) ohnehin die Slaves daruber informiert, dasser der neue Master ist und fortlaufend seine Masterrolle verlangert (QUORUM WRITE), kanndieser Protokollschritt zur Ubermittlung der updateURL genutzt werden.

QUORUM_WRITE <quorum_until> <updateref>

44

Das zweite zu losende Problem entsteht, wenn ein Master, beispielweise slapd A, ausfallt unddie Klienten A1, A2, A3 und X1 so konfiguriert sind, dass sie ausschliesslich auf A zugreifen. Indiesem Fall konnten diese Klienten nicht mehr auf die LDAP-Daten zugreifen, weder lesend nochschreibend.Es ware denkbar, dass B und C in A1, A2, A3 und X1 als Alternativen fur A konfiguriert werden,wobei A bevorzugt zu benutzen ist. Dazu ist es notig, dass sich alle potentiellen Klienten bei allenServern in der Hostliste authentifizieren konnen. Haben die Klienten auf Server ASchreibrechte, mussen sie auch auf allen anderen Servern dazu authorisiert sein, damit die Trans-parenz gewahrleistet wird. Dazu muss der DN, mit dem sich der Klient authentifiziert, auf jedemServer vorhanden sein.Bei allen openLDAP-Kliententools (ldapsearch, ldapadd, ldapmodify ...) wird der zu kontaktieren-de Server entweder im File /etc/openldap/ldap.conf oder als Argument des Klienten festgelegtund kann somit nicht wahrend der Laufzeit verandert werden. Um dennoch einen dauerhaftenZugang zu den gewunschten Daten haben zu konnen, ware folgende Konstellation denkbar:

• Die Klienten fragen beim ersten Kontakt mit dem lokalen LDAP-Server nach der UBIK-Hostliste und speichern alle vorhandenen Server (auch die nicht erreichbaren) in einer Liste

• Fallt der lokale Server aus, versuchen die Klienten der Reihe nach alle Server aus der Listezu kontaktieren

Der Nachteil ist hier, dass die Flexibilitat stark eingeschrankt wird, da kein direkter Ruckschlussvom Servername auf die LDAP-URL gezogen werden kann und deswegen die Standardwerteprotocol=LDAP, port=389 angenommen werden mussen.Um diesen Nachteil zu umgehen, musste die URL jedes Servers bekannt sein. Aus o.g. Grunden(Unflexibilitat bei der Anderung von Port und Protokoll) sind diese aber nicht festgelegt undmussen somit bei laufenden Servern erfragt werden. Jeder Server musste dann beim Start seineURL jedem erreichbaren Quorumaspirant mitteilen, der diese in einer gesonderten Liste spei-chert. Nun musste der Klient entweder regelmassig diese Liste vom lokalen Server ubernehmenoder musste von ihm uber jede neu hinzugekommene URL informiert werden, um sie in seineeigene Liste zu ubernehmen. Wenn der Klient sich nach jeder Operation wieder vom Servertrennt, was bei allen openLDAP-Tools der Fall ist, musste er die Daten permanent speichernkonnen, beispielsweise in ldap.conf. Damit konnte er bei Unerreichbarkeit des lokalen Serverssofort die Alternativserver kontaktieren.

• Jeder Klient speichert alle bekannten Server-URL’s in ldap.conf

• Jeder Server fragt jeden beitretenden Quorumkandidat (Server) nach seiner URL und spei-chert sie in einer Liste

• Der Klient versucht beim Start zuerst den lokalen Server zu kontaktieren

• Ist er erreichbar, gleicht der Klient sein Configfile mit der Liste des Servers ab, indemneue Server aufgenommen werden und geanderte URLs aktualisiert werden (das kann beimehreren slapd ’s pro Server problematisch sein)und sendet seine Requests an ihn

• Ist der lokale Server nicht erreichbar, kontaktiert er der Reihe nach alle in ldap.conf vor-handenen Server, bis einer von ihnen antwortet. An diesen Server sendet er seine Requests.

Da es aber eine grosse Menge anderer LDAP-Klienten gibt, zum Beispiel gq, den javabasier-ten Ldapbrowser, die Erweiterung des NetscapeMessenger Telefonbuchs oder auch die imopenLDAP-Paket enthaltenen Kliententools, die verschiedenste LDAP-Bibliotheken nutzen, kannim Rahmen dieser Arbeit nicht darauf eingegangen werden. Ein weiterer Grund dafur ist, dass

45

eine sehr grosse Anzahl von Klienten nicht mit update-referrals umgehen kann (beispielsweise dieOpenLDAP-Kliententools) und deswegen derzeit unbrauchbar fur ubiksync sind. Eine einfacheVariante ist der manuelle Eintrag von mehreren Quorumservern (URL’s) in jedes ldap.conf-Klientenconfigfile.

46

6 Design und Implementierung

Im letzten Abschnitt wurden die genauen Anforderungen sowie die daraus entstehenden Problemeerfasst, und deren Losung teilweise als Algorithmen realisiert. In dieser Sektion soll es vor allemum die programmiertechnische Umsetzung gehen.

6.1 Grundlegende Anderungen

6.1.1 Anderungen der CMUbik-Bibliothek

Die CMUbik Bibliothek ist, wie bereits erwahnt, eine Bibliothek, die ein API ahnlich der vonBerkeleyDB anbietet. Da wir aber nur den Voting-Mechanismus benotigen, die API aber aussch-liesslich Datenbankoperationen anbietet, muss die Schittstelle zu UBIK grundlegend verandertwerden.Zu den Aufgaben von UBIK zahlte die Masterwahl, die Ausfallerkennung anderer Server,das Mitteilen der Serverrolle an den slapd und das Informieren uber ein aufgelostesQuorum. Desweiteren benotigt UBIK zur Erfullung seiner Aufgaben einige Daten des slapd, undzwar die Datenbankversion (ctxcsn), den Datenbanksuffix, die URL, die sync-Searchbase und dieInformation, ob der Server als Slave alle Attribute replizieren soll.Die grundlegende Funktionsweise sieht wie folgt aus:

1. Beschaffung o.g. Informationen (ContextCSN, Suffix, URL, Searchbase, allAttrs)

2. Anhand von Suffix, Searchbase und Common Suffix prufen, ob der lokale Server als Masterkandidieren kann

3. Kontaktieren aller UBIK-Instanzen in der Hostliste

4. Austausch von Datenbankversion und Mastertauglichkeit mit allen erreichbaren UBIK’s

5. Wahl eines Masters anhand der Datenbankversionen und Hostlistenposition

6. Beitritt in ein bestehendes Quorum / Eroffnen eines neuen WriteQuorums

7. Die LDAP-URL des Masters senden oder empfangen

8. Mitteilen des UBIK-Zustands (Ubikstate), also VOTING / NULLQUORUM / WRITE-QUORUM, gegebenenfalls inclusive Master-URL, an den lokalen LDAP-Server

Da in keinem dieser Schritte die Datenbankschnittstelle erforderlich ist, kann diese aus derBibliothek entfernt werden, sodass zu diesem Zeitpunkt keine API mehr vorhanden ist. Alleaufgefuhrten Schritte kennzeichnen die ausschliesslich aktive Rolle von UBIK. Einzig dasStarten des UBIK-Prozesses benotigt eine Funktion, die anderen Programmen zur Verfugunggestellt werden muss. Um die Semantik dieser Funktion gut zu beschreiben, wurde der nameubiksync joinquorum() gewahlt. Sie initialisiert den internen Zustand (Ubikstate) undstartet anschliessend 2 Threads, die Anfragen anderer UBIK-Instanzen entgegennehmen undverarbeiten.Da die Implementierung von Ubiksync den slapd -Quelltext moglichst wenig beeinflussen sollte,wird dessen Konfiguration im Configfile ubik.conf vergenommen. Dazu zahlt die Hostliste, derCommonSuffix und ein Flag, das festlegt, ob auch Reads erlaubt sind, wenn der Server nicht ineinem Writequorum ist. Letztere Einstellung wird direkt vom slapd gebraucht, um entsprechendeBackend-Restrictions zu setzen. Deswegen wird die Funktion ubiksync get always read flag()ebenfalls in die API aufgenommen.

47

6.1.2 Anderungen / Erweiterungen des slapd

Um folgende Erklarungen besser verstehen zu konnen, mussen erst einige Algorithmen und Fun-tionsweisen naher beleuchtet werden:

• LDAPsync verwaltet eine Runqueue, in der Tasks verwaltet werden, die einen sync-Slavedazu veranlassen, sich mit dem Master zu synchronisieren. Jeder Eintrag dieser FIFO-Liste besteht hauptsachlich aus dem Task (do syncrepl() und einem Zeitpunkt, zu demdiese Funktion ausgefuhrt werden soll. Diese Queue nennen wir hier syncrepltask-list.Im RefreshOnly Mode berechnet sich der Zeitpunkt aus der Summe des Timestamps derletzten Synchronisation und dem Sync-Intervall (interval in slapd.conf), wahrend dieserWert im RefreshAndPersist-Modus 0 ist, weil es nur einen Task gibt, der nie beendet wird.

• Diese Runqueue wird im slapd daemon task(), also im Hauptloop des slapd -Servers verar-beitet, sodass bei jedem Durchlauf gepruft wird, ob ”die Zeit wieder reif fur einen Upda-terequest ist“ (Das gilt naturlich nur im RefreshOnly-Mode). Ist das der Fall, wird dieserRequest ausgefuhrt, also der Master nach Updates gefragt. Das nachfolgende select()wartet auf eine Aktivitat an den listener-sockets, uber die die Clients (also auch Sla-ves) den Server kontaktieren. Liegt nach einem timeout keine Anfrage vor (erkennt selectan keinem Socket einen Statuswechsel), wird wieder zum Anfang des Loops gesprungen.

• Jeder sync-Slave verwaltet die Informationen, die zum Replizieren notig sind, in einem structnamens syncinfo. Er beinhaltet unter anderem die eigene rid, die LDAP-URL des Provi-ders (Masters), Authentifizierungsmerkmale, Replikationsattribute (Attributlisten, Filter,Scope), den Replikationstyp (RefreshOnly / RefreshAndPersist), Zeitintervalle fur die Re-plikation und das syncCookie fur die Abstimmung mit dem aktuellen Master. Auf diesensyncinfo-Struct wird im slapd ausschliesslich uber einen Verweis im Backend zugegriffen,wodurch ein Wechsel des Masters einfach durch ein Umsetzen des Zeigers auf einen anderensyncinfo-Struct mit anderer provider uri vorgenommen werden kann.

• Das Backend wird ebenfalls durch einen Struct definiert, in dem eben der Verweis auf denubiksync-Struct gespeichert wird. Unter anderem sind dort auch der Datenbanksuffix (derKontext) und backendspezifische Einschrankungen (restrict ops) hinterlegt. Uber dieseRestrictions konnen beispielsweise Lese- und Schreiboperationen datenbankweit verbotenwerden.

• Der bereits erwahnte ContextCSN, der die Aktualitat der Datenbank angibt, wird im sync-Umfeld ctxcsn genannt

Um mit UBIK Informationen austauschen zu konnen, muss auch der slapd erweitert werden. DieFunktionsweise sieht hier folgendermassen aus:

1. Starten von UBIK, nachdem auf alle erforderlichen Informationen zugegriffen werden kann

2. Einnehmen der Slaverolle (dazu spater mehr)

3. Liefern der von UBIK angeforderten Informationen (ContextCSN, Suffix, URL, Searchbase,allAttrs)

4. Warten, bis UBIK einen neuen Zustand mitteilt und entsprechende Aktionen ausfuhren

• MASTER im WriteQuorum: Synchronisation stoppen, Lese- und Schreiboperationenerlauben• SLAVE im WriteQuorum: Synchronisation mit neuem Master aufnehmen, Lese- und

Schreiboperationen erlauben, Schreiboperationen an Master weiterleiten• VOTING (kein WriteQuorum): Synchronisation stoppen, Lese- und Schreiboperatio-

nen verbieten

48

Da der slapd nach dem Start fast ausschliesslich passiv mit UBIK kommuniziert, fallt hierdie API etwas umfangreicher aus. Zunachst mussen Funktionen definiert werden, die UBIKalle geforderten Daten liefern konnen. Die Funktion ubiksync get sync ctxcsn() liefertden ContextCSN des slapd, ubiksync get slapd suffix() liefert den Datenbanksuffix ausslapd.conf, ubiksync get db allattrs() liefert die Information, ob als laut slapd.conf al-le Attribute repliziert werden sollen und ob der Server somit als Master geeignet ist undubiksync get slapd url() gibt im Falle der Wahl als Master die eigene URL zuruck, um mittelsUBIK den anderen Servern ihren neue SynchronizationSite mitzuteilen.Da ein laufender Standard-LDAP-Server nur auf Klientenanfragen reagiert und sonst keineSchnittstelle fur weitergehende Anfragen bereitstellt, lasst sich ein direktes Eincompilieren derubiksync-Schnittstelle nicht umgehen. Es muss also ein Headerfile entstehen, dessen Funktionenden slapd oder seine Komponenten direkt ansprechen. Weiterhin mussen verschiedene Informa-tionen, wie zum Beispiel die URL oder der Datenbanksuffix, beim Start eingelesen werden, da imlaufenden Betrieb ”von aussen“ nicht darauf zugegriffen werden kann.Die wichtigste Funktion fehlt bis jetzt aber noch: die Moglichkeit, die Rolle im sync-Prozess zuwechseln: ubiksync change sync state(). Da der Server im slapd daemon task()-Loop aufVerbindungen wartet und erst nach Ablauf des select-Timeouts den restlichen Code abarbei-tet, was je nach Konfiguration sehr lange dauern kann, ist hier ein einfacher Funktionsaufrufunpraktikabel. Ist der Timeout unendlich, wurde die Verarbeitung der veranderten Taskliste biszur nachsten select-Aktivierung warten mussen, also bis sich ein Klient oder ein Sync-Slave miteinem Request meldet. Wurde ubiksync selbst die syncrepl-tasklist verandern, konnte slapddiese Anderungen trotzdem erst nach einem Timeout-Ablauf ubernehmen, weil die Verarbeitungder syncrepl-Tasks vor dem select stattfindet.Der einzige Weg, einen sofortigen Moduswechsel zu veranlassen, ist also die Aktivierung des

Abbildung 10: Die Hauptschleife des LDAP-Servers

slapd durch das Senden von Daten an einen von select uberwachten Socket, sodass dieser un-verzuglich ”aufwacht“ . Zu diesem Zweck wird im init-Abschnitt des slapd daemon task’s einneuer Socket namens ubiksync sock geoffnet und an den UBIKSYNC PORT gebunden. Dieser wirdin den listen()-Status versetzt, wartet also auf Verbindungswunsche, und wird schliesslich in dieSocket-Menge aufgenommen, die select() beaufsichtigt. Nach dem select() wird gepruft, ob dieserSockets der Grund fur die Aktivierung war (FD ISSET(ubiksync sock,&readfds)) und falls diesder Fall ist, wird die neue Verbindung akzeptiert. Die empfangenen Daten (ubiksync request,dazu gleich mehr) werden ausgewertet und die entsprechdenden Aktionen sofort von der Funk-tion ubiksync change sync state() vorgenommen. Da nach der Verarbeitung sofort ein neuerLoop-Durchgang folgt, werden die Anderungen der syncrepl-Tasklist unverzuglich berucksichtigt.

49

6.2 Das Kommunikationsmodell

6.2.1 Kommunikation zwischen slapd und lokalem UBIK

Die im letzten Abschnitt gesammelten Interaktionsanforderungen an UBIK und den slapd werdenhier noch einmal zusammenfassend dargestellt. Die folgende Abbildung zeigt eine Erweiterungvon Abb. 5. Der Informationsaustausch findet durch Funktionsaufrufe und Socketoperationenstatt.

Abbildung 11: Kommunikation zwischen UBIK und slapd

Die Aufrufe put suffix(), put slapd uri() und put slave syncinfo() werden beim Startendes Servers ausgefuhrt, um die entsprechenden Daten in Ubiksync zu speichern und wahrend derLaufzeit darauf zugreifen zu konnen. Unter die Kategorie get config fallt zum Beispiel, dasssich der slapd mittels get always read flag() die Erlaubnis einholt, auch Leseoperationen imVoting- oder Nullquorum-State zu gestatten.Die Kommunikation uber den UBIKSYNC-Socket geschieht durch den Austausch vonubiksync request’s, die aus folgender Datenstruktur bestehen:

typedef struct _ubiksync_request {int request_id; /* 4 byte */int oldstate; /* 4 byte */int newstate; /* 4 byte */char newmaster[50]; /* 50 byte */

} ubiksync_request; /* 62 bytes */

Die request id kann den Wert UBIKSYNC RQ CHANGE SYNCSTATE annehmen, was,wie der Name schon andeutet, einen Zustandswechsel auslosen soll. Die Antwor-

50

ten auf diesen Request sind entweder UBIKSYNC RP CHANGE SYNCSTATE SUCCESS oderUBIKSYNC RP CHANGE SYNCSTATE NOSUCCESS. Die Variablen newstate und oldsate konnendie Werte UBIKSYNC STATE MASTER, UBIKSYNC STATE SLAVE oder UBIKSYNC STATE VOTINGannehmen und somit dem slapd mitteilen, welche Rolle er einnehmen soll. Der String newmasterteilt einem Slave (UBIKSYNC STATE SLAVE) die URL des neuen Masters mit.Um den Einsatz von ubiksync mit moglichst wenigen Einschrankungen zu ermoglichen, solltesowohl der Port, mit dem UBIK lokal mit dem slapd kommuniziert, als auch der, mit dem dieUBIK-Instanzen untereinander uber ein Netzwerk Informationen austauschen, konfigurierbarsein. Auch diese Einstellungen werden in ubik.conf vorgenommen (ubik port, ubiksync port)und mussen zum Teil an den slapd ubertragen werden, was durch die in das UBIK-Interfaceaufgenommene Funktion ubiksync get ubiksync port() erfolgt. Da UBIK vom slapd gestartetwird, kann es vorkommen, dass UBIK seine Konfiguration noch nicht eingelesen hat, wenn slapdden Port erfragt, und ubiksync get ubiksync port() somit den Wert Init-Wert 0 liefert. Umdises Problem zu umgehen, muss die Funktion selbst die entsprechende Zeile aus ubik.conf lesen.

6.2.2 Kommunikation zwischen den UBIK-Instanzen

Diese Kommunikation erfolgt ausschliesslich durch den Austausch von Kommandos des UBIK-Protokolls uber Sockets. Zur Vereinfachung werden hier nur 3 Instanzen U1,U2 und U3 verwendet.Folgende Kommandos, von denen einige durch Parameter erganzt werden, sind definiert:9

• CMD VOTEFORME wird von U1 versendet, wenn er SmaxDBminPos ist

• U2 und U3 antworten mit einem CMD VOTEYES, wenn sie mit diesem Mastereinverstanden sind, wenn sie also auch der Meinung sind, dass U1 SmaxDBminPosist.

• U2 und U3 antworten mit einem CMD VOTENO, wenn sie U1 nicht fur SmaxDBminPoshalten oder sie in den letzten BIG SECONDS einen anderen Server gevotethatten

• Um die Version von U1 zu erfragen, sendet U2 ein CMD ASKVERSION

• Dieser antwortet darauf mit einem CMD MYVER <icanbemaster> <version> .Diese Version ist der in einen Unix-Zeitstempel umgewandelte ContextCSNdes lokalen LDAP-Servers, also eine 8-Byte lange LongInt-Zahl, wahrend daserste Argument der Ruckgabewert der Funktion can i be master() ist.

• Um als gewahlter Master den Slaves die Bildung eines NullQuorumsmitzuteilen, dient das Kommando CMD QUORUM NULL <quorum until><master uri>Quorum until ist die Summe vom aktuellen Unix-Timestamp und SMALL SECONDSund hilft den empfangenden Slaves beim Erkennen eines Masterausfalls(Quorum-Timeouts), indem sie selbst standig prufen, ob ihre lokale Zeit,addiert mit SMALL SECONDS diesen Wert uberschritten hat. In diesem Fallwechseln sie in den Voting-State.Die master uri enthalt die LDAP-URL des gewahlten LDAP-Servers, die von denempfangenden Slaves an ihren slapd weitergeleitet wird, um ihm den neuenMaster und das Update-Referral zu liefern.

• Zur Mitteilung uber ein entstandener WriteQuorum wird das KommandoCMD QUORUM WRITEL <quorum until> <master uri> verschickt, das die gleichenParameter wie CMD QUORUM NULL besitzt.

9U = UBIK-Instanz

51

Die Kommandos werden in der Funktion parse(), die von connections select() aufgerufenwird, ausgewertet und anhand von empfangenen Versionen und Erreichbarkeiten anderer Instan-zen entsprechend beantwortet.Ein Problem, das in der CMUbik-Originalversion nicht beachtet wurde, ist das fast gleichzeitigeEintreffen von Kommandos ein und der selben Ubik-Instanz auf dem selben Socket. Das fuhrtein dieser Implementierung, in der dieser Fall ofter auftritt, dazu, dass select nur einmal aktiviertwurde und kurz darauf das zweite Kommando eintraf, bevor der gesamte Socketinhalt ausgelesenwurde. Nach der Auswertung des Kommandos wurden eventuelle Parameter aus den noch nichtverarbeiteten empfangenen Daten gesammelt und im Anschluss alle nicht gebrauchten Daten ver-worfen. Wenn nun zum Beispiel ein hier haufiger versendetes Kommando wie CMD ASKVERSIONkurz nach einem CMD MYVER eintrifft, was beim Start eines Servers immer der Fall ist, wird daszweite Kommando unter Umstanden einfach ignoriert, da es wie gerade erlautert, weggeworfenwird und es wurden Verklemmungen entstehen, da auf genau dieses zweite Kommando gewartetwerden wurde.Die Losung dieses Problems besteht darin, schon auf Protokollebene zu entscheiden, wieviele Da-ten gelesen werden mussen. Dazu wird nach der Aktivierung von select() jeweils nur ein Byte(das Kommando) gelesen. Anschliessend wird gepruft, wie gross die Datenmenge der Parameterdieses Kommandos sein sollte, genau diese Menge gelesen und von parse() verarbeitet. Eventu-ell nicht gelesene Daten aktivieren das select() beim nachsten Schleifendurchgang und werdenin gleicher Weise verarbeitet. Diese Vorgehensweise verhindert den Kommandoverlust komplett,fuhrt aber auch dazu, dass alle Parameter eine fixe Grosse haben mussen. In dieser Implemen-tierung betrifft dies vor allem die zu ubertragende slapd -URL, die hier unabhangig von ihrerStringlange immer als 50-Byte-String ubertragen wird.Eine graphische Darstellung dieses Protokolls erubrigt sich hier, jedoch wird spater noch einmalauf die genaue Ursache und Wirkung der einzelnen Kommandos eingegangen sowie ein Kommu-nikationsablauf anhand eines beispielhaften Szenarios erklart.

6.2.3 Das Prozessmodell und Interprozesskommunikation

Da Ubik vom laufenden LDAP-Server gestartet wird, mit ihm kommunizieren soll, selbst aber ei-genstandig und unabhangig von ihm arbeiten sollte, ist nur eine parallele Ausfuhrung beider Teilepraktikabel. Die beiden Moglchkeiten, die hierzu in Frage kommen, sind Prozesse und Threads.Die CMUbik-Implementation arbeitet intern mit Lightweight Processes (Threads), da der Auf-wand zum Taskwechsel hier bedeutend kleiner ist als bei Prozesswechseln und Threads das Teileneines gemeinsamen Datenbereichs ermoglichen. In diesem zusammen genutzen Speicher werdenunter anderem Semaphore (Mutexe) verwaltet, um atomare Datenbereichszugriffe zu ermoglichen.Der erste Thread, den UBIK verwendet, ist der ubik loop, der den ubik state auswertet und ent-sprechende Aktionen auslost, beispielsweise das Aussenden von VOTEFORME-Kommandos oderden Ubergang in den Voting-State beim Erkennen eines Quorum-Timeouts. Die vom ubik loopaufgerufene Funktion connections select() uberwacht weiterhin alle aktiven Verbindungen zuanderen UBIK-Instanzen, wertet von ihnen empfangene Kommandos aus und sendet gegebenen-falls entsprechende Antworten zuruck. Der zweite Thread, der consuming loop(), wurde in derCMUbik-Implementierung hauptsachlich zur Verarbeitung von empfangenen Kommandos zurDatenbankmanipulation (Twophase-Commit, Write-Forwards u.s.w.) verwendet. Da diese hiernicht benotigt werden, wurden die ubrigen Funktionen in den ersten Thread verlagert und dieserThread entfernt.OpenLDAP arbeitet mit einem Thread-Pool, dessen Grosse im Configfile mit dem Schlusselwortthreads bestimmt werden kann und ansonsten einen Standardwert von 32 hat. Sofern dieseMaximalzahl von laufenden Threads noch nicht erreicht ist, wird fur jede Klientenverbindungein Thread aus diesem Pool benutzt. Anderenfalls wird die Anfrage zuruckgestellt und in ei-

52

ne Warteliste (pending list) aufgenommen. Sobald ein Platz im Threadpool frei wird, nutztdie am langsten wartende Aufgabe diesen verfugbaren Slot. Zu beachten ist hier, dass Klien-ten, deren Verbindung nach einem Request nicht beendet wird, also zum Beispiel SyncSlaves imRefreshAndPersist-Mode, dauerhaft einen Thread aus diesem Pool besetzen. Wenn also beispiels-weise ein Master bei Standardkonfiguration 32 Slaves im RefreshAndPersist-Mode mit Updatesversorgt, konnen weder Updates am Master selbst noch an Slaves gerichtete Updates vorgenom-men werden, die an den Master geforwardet werden, weil jede Updateoperation eine gesonderteVerbindung zu M erfordert und der zu erstellende Thread nie aus der pending list ubernommenwird, weil der Pool bereits voll ist. Deswegen sollte bei der Konfiguration dieses Pools die Grosseder Hostliste beachtet werden, wenn der zu bevorzugende RefreshAndPersist-Mode verwendetwird.Da der Wechsel zwischen Threads bedeutend weniger Zeit in Anspruch nimmt als der Prozess-wechsel, wird UBIK vom slapd in der Funktion slapd daemon task() vor der Hauptschleife ausals Thread gestartet. Die Funktion ubik init() liest das Konfigurationsfile ubik.conf aus, er-stellt daraufhin eine interne Reprasentation der Hostliste, initialisiert den ubik state, erfragt mitgetdbversion() und ubiksync get slapd suffix() die fur folgende Aufgaben erforderlichenDaten des LDAP-Servers, offnet den Socket, uber den andere UBIK-Instanzen Kontakt aufneh-men konnen, versucht seinerseits alle Hosts aus der Hostliste zu erreichen und startet schliesslichden ubik loop() ebenfalls als Thread. Dieser arbeitet dann in oben beschriebener Weise underfullt damit alle Aufgaben, die von UBIK verlangt werden.Die folgende Abbildung stellt samtliche Prozesse (Threads), sowie deren Aufruf und die Kommu-nikation zwischen ihnen noch einmal graphisch dar.

Abbildung 12: Das Prozessmodell und InterProcessCommunication

Die Kommunikation zwischen den LDAP-Servern selbst, die uber das nomale LDAP-Protokoll

53

stattfindet, bleibt hier unverandert, lediglich von LDAP-Klienten initiierte Schreiboperationenwerden durch einen Tausch von Provider- und Consumerrolle derart beeinflusst, dass sie gege-benenfalls an den Master geforwardet werden mussen. Die Verbindung zu Klienten selbst bleibtebenfalls weitestgehend unverandert, ausser dass bei entsprechender Einstellung Leseoperationenverboten werden, wenn sich der Server in keinem WriteQuorum befindet.

6.3 Das Ablaufmodell anhand eines Szenarios

In diesem Abschnitt werden die genauen Ablaufe wahrend des Betriebs von Ubiksync und dieKoordination von UBIK und slapd vorgestellt. Um die neu entwickelte Funtionsweise von Ubik-sync naher zu beleuchten, wird eine beispielhafte Kommunikation zwischen mehreren Ldap-Ubik-Servern nachvollzogen.

6.3.1 Voraussetzungen

Es existieren 3 LDAP-Server, A, B und C, die in jeder Hostliste in der gleichen Reihenfolge(A,B,C) registriert sind. Auch der UBIK-Port ist in allen ubik.conf-Files gleich definiert. Alle 3Server waren bisher weder Master noch Slave in einer LDAPSync- oder ubiksync-Umgebung, sindin slapd.conf aber als Sync-Slave konfiguriert und haben im Verzeichnis bereits Eintrage wieden BaseDN, den RootDN, den UpdateDN und den BindDN gespeichert. Wenn nicht gesondertdarauf hingewiesen wird, handelt es sich um die RefreshOnly-Methode.

6.3.2 Der Serverstart

In unserem Szenario startet Server B zuerst.Als erstes wertet slapd die Kommandozeilenargumente aus, wobei fur diese Erklarung nur dieOption -h URLs wichtig sind. Der ermittelte Wert wird mittels ubiksync put slapd url() imslapd -Teil von ubiksync zwischengespeichert. Sobald slapd sein Konfigurationsfile slapd.confeinliest, erkennt er am Vorhandensein einer syncrepl-Direktive, dass er die Slaverolle einnehmensoll und erzeugt daraufhin eine syncrepl runqueue mit einem dummy-Master, der nur derVollstandigkeit halber vorhanden sein muss, in Wirklichkeit aber nicht existiert. Es wirdausserdem ein syncinfo-Struct erzeugt, der mit dem Backend verknupft und zur spaterenVerwendung in ubiksync hinterlegt wird, Auch der suffix und das db allattrs-Flag, das ausdem syncinfo-Struct extrahiert wird, wird in ubiksync gespeichert. Nachdem die vollstandigeInitialisierungen abgeschlossen ist, wird der slapd daemon task() als Thread gestartet.Die erste Aktion, die diese Funktion ausfuhrt, ist das Starten von UBIK mittelsubiksync start ubik(). Anschliessend wird der Socket zur Kommunikation mit UBIKgeoffnet, an den uber ubiksync get ubiksync port() ermittelten Port gebunden und in denlisten-Staus versetzt. Nach der Aufnahme dieses Sockets in die von select() uberwachte Mengestartet die Hauptschleife. Diese uberwacht hauptsachlich die Menge aller registrierten Sockets.In der Zwischenzeit sollte UBIK seine vollstandige Konfiguration eingelesen haben und dieDatenbankversion vom slapd mit getdbversion() erfragt haben. Desweiteren benutzt es dengespeicherten Suffix, das db allattrs-Flag, die im syncinfo-Struct hinterlegte Searchbase, diegespeicherte URL des slapd -Servers und die commonsuffix-Einstellung aus ubik.conf , umzu entscheiden, on der Server Masterkandidat ist. Nun wird die alwaysallowreads-Direktiveaus ubik.conf in ubiksync gespeichert, der UBIK- und UBIKSYNC PORT registriert und dieHostliste initialisiert. Schliesslich wird versucht, eine Verbindung zu jedem Hostlistenmitgliedherzustellen und der ubik loop() gestartet. Mit der Initialisierung des ubik-states mit VOTINGwird dem slapd ein ubiksync request zugeschickt, bei dem nur die Werte request id =UBIKSYNC RQ CHANGE SYNCSTATE und newstate = UBIKSYNC STAE VOTING belegt sind.

54

Aufgrund des aktivierten select’s wertet der slapd diesen Request aus und ruft infolge dessen dieFunktion ubiksync change sync state(UBIKSYNC STATE VOTING, 0, NULL) auf. Sie bekommtmit dem Aufruf von ubiksync get always read flag das always read flag, entfernt denVerweis vom Backend zum Syncinfo-Struct, leert die syncrepl runqueue, verbietet anhanddes Backend-Flags SLAP RESTRICT OP WRITES Schreiboperationen und, wenn entsprechendkonfiguriert, mittels SLAP RESTRICT OP READS das Lesen von diesem LDAP-Server.Infolge der geleerten syncrepl-Tasklist versucht der slapd nun nicht mehr, sich mit dem Dummy-server zu synchronisieren.

Abbildung 13: Koordination beim Start eines Servers

55

6.3.3 Die Masterwahl

Der zweite startende Server ist C, dessen Startprozedur der gerade beschriebenen entspricht.Der folgende Absatz behandelt ausschliesslich UBIK-Interaktionen. Nach dem Eintritt in denubik loop versucht C, sich mit allen anderen Servern aus der Hostliste zu verbinden, also mit Aund B.B akzeptiert die Verbindung, aktualisiert seine eigene in der Hostliste gespeicherte Datenbank-version und sendet durch den Aufruf der Funktion hostlist hostconnected() ein CMD ASKVERan C, der daraufhin die Funktionen getdbver() und canibemaster() seiner ubiksync-Instanzaufruft um mit den erhaltenen Werten ein CMD MYVER <icanbemaster> <dbver> zuruckzulie-fert. Da das CMD ASKVER das erste von B empfangene Kommando war, sendet C ebenfalls einCMD ASKVER, das B in gleicher Weise beantwortet. Im Anschluss an diesen Protokollabschnitthat jeder der beiden Server die eigene Version und die des anderen in der Hostliste gespeichert.Aufgrund dessen kann nun jeder Server auswerten, ob er selbst lowestwithbiggestversion()ist. Da beide Server den Ctxcsn = 0 geliefert haben, weil sie bisher weder Master noch Slave ineiner Sync-Umgebug waren, entscheidet zu diesem Zeitpunkt nur die Hostlistenposition. Alsosendet B ein CMD VOTEFORME an C, der diese Anfrage zuerst verneint (CMD VOTE NO). Dasliegt daran, dass sich C vor der Bekanntgabe von B’s Version selbst gewahlt hat und erst nachSMALL SECONDS einen anderen Server wahlen darf. B sendet weiterhin in bestimmten IntervallenVOTEFORME-Messages aus, sodass nach Ablauf der SMALL SECONDS eine CMD VOTE YES-Antwort von C empfangen wird. Da sich B auch selbst wahlt, also insgesamt 2 VOTE YES-Stimmen von unterschiedlichen Servern erhalten hat, womit die Bedingung i>n/2 erfullt ist,deklariert er lokal ein WRITE QUORUM. Anschliessend erfragt er mittels get slapd url()die URL des lokalen LDAP-Servers, bestimmt den Wert quorumuntil in bereits beschriebenerWeise und teilt C mit einem CMD QUORUM WRITE <until> <ownURL> diese Entscheidung mit.Nun ruft er die Funktion ubiksync state set master(master URL) auf, die ihrerseits einenubiksync request mit der Belegung request id = UBIKSYNC RQ CHANGE SYNCSTATE undnewstate = UBIKSYNC STATE MASTER an den ubiksync-Port schickt. Nachdem der select()-Portdes slapd daraufhin aktiviert und der Request ausgewertet wurde, wird in der Funktionubiksync change sync state(UBIKSYNC STATE MASTER, UBIKSYNC STATE VOTING,NULL) auf-gerufen, deren einzige Aufgabe zu diesem Zeitpunkt im Zurucksetzen aller Datenbankrestriktionenbesteht. Somit konnen ab diesem Zeitpunkt von B sowhl Lese- als auch Schreibanforderungenentgegengenommen werden.Wenn C das CMD QUORUM WRITE empfangt, deklariert er lokal ein WRITE QUORUMund sendet ebenfalls einen ubiksync request an den lokalen slapd mit der Belegung request id= UBIKSYNC RQ CHANGE SYNCSTATE, newstate = UBIKSYNC STATE SLAVE und newmaster= master uri, also der empfangenen URL des Masters. Auch hier wird die Funktionubiksync change sync state() aufgerufen, allerdings mit den Argumenten (newstate =UBIKSYNC STATE SLAVE,oldstate = UBIKSYNC STATE VOTING,newmaster = Master-URL).Die empfangene URL wird im durch ubiksync put slave syncinfo() zwischenge-speicherte Syncinfo-Struct als syncinfo->si provideruri und im Backend-Struct alsbackend->be update refs eingetragen, wodurch der neue Master von C festgelegt wird,mit dem er sich synchronisieren soll und an den Updates weiterzuleiten sind. Weitere Einstellun-gen in slapd.conf, die die Synchronisation beeinflussen, beispielsweise die Wahl der Methode,die Searchbase, Replikationsintervalle oder auch Authentifizierungsattribute, werden unverandertin den neu generierten Struct ubernommen. Anschliessend werden laufzeitspezifische Elementedes Syncinfo-Structs neu initialisiert, sodass er nun mit dem Backendinfo-Struct verlinkt werdenkann. Die durch den vorangehenden Votingzustand gesetzten Datenbankrestriktionen werdenaufgehoben, die Syncrepl-Taskliste wird initialisiert und mit dem generierten Syncinfo-Struct alsArgument gestartet, wodurch C sich ab nun mit B synchronisiert.

56

Abbildung 14: Koordination bei der Masterwahl

6.3.4 Klienteninteraktion

Da an den Master gerichtete Updates von Klientenseite genauso ablaufen, wie bei einem Standard-LDAP-Server, sollen hier nur Interaktionen mit dem Slave naher betrachtet werden. Bei dieserInteraktion spielen UBIK und Ubiksync keine Rolle; alle Aufgaben werden hier vom slapd durch-gefuhrt.Wichtig dabei ist, dass der LDAP-Klient, hier K genannt, mit Referrals umgehen, also die beieinem Updatevorgang vom Slave erhaltene Referral-URL verarbeiten kann. Auf der Seite vonOpenldap [OLDAPORG] ist zu lesen, dass die mitgelieferten Tools (ldapadd, ldapsearch, ldap-modify ...) diese Anforderung nicht erfullen. Ich selbst benutze den LDAPBrowser von JarekGawor. [LDAPBROWSER]Sobald sich K bei C authentifiziert hat, startet der LDAPBrowser eine Suche nach dem gesamten

57

Teilbaum, der als BaseDN konfiguriert werden kann.Soll nun beispielsweise ein neuer Eintrag erstellt werden, etwa mit dem Inhalt eines LDIF-Files,wird von K ein Addrequest mit dem gewunschten Inhalt generiert und an den slapd C gesendet.Dieser erkennt am Vorhandensein des SLAP DBFLAG SHADOW-Flags seine Slaverolle und sucht dar-aufhin in seinem BackendInfo-Struct nach einen Eintrag in der Liste be update refs, wo er B’sURL findet. Infolge dessen fuhrt er dieses Update nicht aus, sondern sendet eine Referral-Antwortmit der in der Liste vorhandenen URL zuruck an K. Kann K diese Referrals verabeiten, sendeter den gleichen Addrequest an die gelieferte URL, also an B.Dieser nimmt das Update entgegen und fuhrt es aufgrund des Nichtvorhandenseins des FlagsSLAP DBFLAG SHADOW aus. Im folgenden wird angenommen, dass B aufgrund der schon vorhan-denen Eintragungen einen ContextCSN-Eintrag hat, denn er wird beim Erstellen des allererstenEintrags erzeugt. Nach dem Update aktualisiert B also einen Context-CSN-Entry mit dem Zeit-stempel des gerade ausgefuhrten Updates.Beim nachten SyncRequest seitens C erkennt B am mitgelieferten Cookie, das in fruheren Re-quests erstellt wurde, dass der soeben getatigte Neueintrag einen neueren Zeitstempel tragt alsder ctxcsn-Wert der Cookies und sendet infolge dessen diesen Eintrag als Antwort zuruck. Caktualisiert seine Datenbank und ubernimmt den neuen ctxcsn-Wert in seinen SyncConsumer-Subentry, dessen Werte er als Cookie fur die folgenden Anfragen nutzt.Auch im RefreshAndPersist-Mode leitet C die Updates an B weiter, erhalt jedoch unverzuglicheine SyncStateControl-Message von B, die den geanderten Eintrag enthalt.Falls der SyncProviderSubentry noch nicht existiert hat, wird er von B zum Zeitpunkt des erstenausgefuhrten Updates mit entsprechendem ctxcsn-Wert erstellt. Das gleiche gilt fur C’s Sync-ConsumerSubentry, der mit dem ersten Empfangen eines sync-Reply ’s erzeugt wird.

Abbildung 15: Klienteninteraktion

6.3.5 Ein dritter Server tritt ein

In diesem Abschnitt wird nur die Interaktion zwischen den UBIK-Instanzen betrachtet, da dieKommunikation mit Ubiksync und dem slapd bereits beschrieben wurde und sich hier nichtanders darstellt. Als dritter Server startet in diesem Szenario Server A, der ebenfalls die selbe

58

Startprozedur wie B durchlauft. Er versucht sich daraufhin mit B und C zu verbinden, wodurcher von beiden Servern je ein CMD ASKVER erhalt. Er liefert seine durch das verpasste Updatenicht aktuelle Datenbankversion und fragt B und C ebenfalls nach ihrer Version. Nachdem er diebeiden Antworten erhalten hat, erkennt er durch den Aufruf von lowestwithbiggestversion(),dass er selbst nicht Master werden kann und wartet auf ein VOTEFORME vom lowest Host withbiggest Version B, der dieses Kommando regelmassig an alle Hosts aussendet, die nicht in seinemWriteQuorum sind.Wahrend C nun aus oben genannten Grunden diese Anfrage fur eine bestimmte Zeit mit VOTE NObeantwortet, synchronisiert sich C weiterhin mit B. Sobald A mit VOTE YES antwortet, deklariertB den Server A intern als Mitglied in seinem Quorum und sendet ab sofort CMD QUORUM WRITE’san A. A sendet beim Empfangen dieses Kommandos ebenfalls einen ubiksync request an den lo-kalen slapd, der daraufhin die oben beschriebenen Aktionen zur Initialisierung des Slavezustandsausfuhrt und sich fortan mit B synchronisiert.

Abbildung 16: Ein Out-Of-Date-Server tritt bei

Falls A die gleiche Datenbankversion wie B hatte, sieht der Vorgang etwas anders aus: Nach demAustausch der Versionen wissen alle 3 Server, dass A lowestwithbiggestversion ist. DochB sendet weiterhin VOTEFORME-Messages aus, die von A, C aber auch von B selbst mit einemVOTE NO beantwortet werden, bis B’s WriteQuorum durch ein Timeout (SMALL SECONDS)auslauft.Nach der Auflosung des Quorums und dem internen Ubergang in den VOTING-State sendetB ein QUORUM NULL an C, sodass dieser ebenfalls den ubiksync-VOTING-State einnimmt. Zudiesem Zeitpunkt fangt A an, selbst VOTEFORME-Messages auszusenden, die sofort mit VOTE YESbeantwortet werden, da alle Server innerhalb der letzten SMALL SECONDS keinen anderenServer gewahlt haben. Damit ist die Bedingung i>n/2 erfullt, A nimmt die Masterrolle in obenbeschriebener Weise ein, wahrend B und C durch das empfangene CMD QUORUM WRITE in denSlavestate wechseln.

59

Abbildung 17: Ein Up-To-Date-Server mit niedrigster Hostlistenposition tritt bei

6.3.6 Ein Serverausfall

Auch hier sind wieder verschiedene Falle zu unterscheiden, deren Auswirkungen im folgendenbeleuchtet werden.Das erste zu betrachtende Szenario ist der Ausfall eines Slaves, wobei anschliessend immer nochgenugend Server laufen, um das Quorum aufrecht zu erhalten. Es sei, um bei der letzten Kon-stellation zu bleiben, A der Master, sowie B und C seine Slaves. (Abb. 18)

Fallt nun B aus, erneuert A den quorum until-Wert des WriteQuorums nicht, weil die Funk-tion declare quorum() diesen Wert berechnet, indem die Summe aus oldestinquorum() undSMALL SECONDS gebildet wird. Die Funktion oldestinquorum() gibt den Zeitpunkt der let-zen Wahl des Servers zuruck, dessen Stimme am langsten zuruck liegt, also den Zeitpunkt derletzten Wahl seitens B. Wird nun SMALL SECONDS lang kein VOTE YES von B empfangen, lauftdas Quorum aus, weil eben der quorum until-Wert nicht erneuert wird.Daraufhin sendet A ein QUORUM NULL an B und C mit bereits beschriebenen Folgen, bleibt selbstaber im Zustand SS WRITE QUORUM und erhalt von C ein VOTE YES. Zusammen mit seiner eigenenStimme ist damit die Anzahl der benotigten Votes erreicht und A deklariert sofort ein neuesWriteQuorum, das ebenfalls von C akzeptiert wird.Beim zweiten Fall soll nach dem Ausfall des Slaves B die Bedingung i>n/2 nicht mehr erfulltsein. (Abb. 19)Fur diese Betrachtung muss ein weiterer Server in die Hostliste (ubik.conf) aufgenommenwerden, damit ein Writequorum nur mit mindestens 3 Servern (3>4/2) gebildet werden kann,nach dem Ausfall aber immer noch 2 Server miteinander kommunizieren.Auch hier sollen sich im Augangszustand B und C mit A synchronisieren. Falt nun Server B aus,wird dies von A durch ein Quorum-Timeout nach SMALL SECONDS bemerkt. Infolge dessensendet er ein CMD QUORUM NULL an C, der den OTHER NULL QUORUM-Zustand einnimmt, wahrendA selbst noch SyncSite im Writequorum ist. Ebenso antwortet C sofort mit einem VOTE YES,jedoch kann A aufgrund der zu wenigen Stimmen kein WriteQuorum bilden, wechselt daher inden ubiksync-VOTING-State und sendet fortan solange VOTEFORME-Kommandos aus, bis er wieder

60

Abbildung 18: Nach dem Ausfall eines Slaves sind noch mehr als n/2 Server aktiv

mehr als n/2 VOTE YES-Stimmen erhalt. Wahrenddessen bleibt B im OTHER NULL QUORUM-State,um beim Starten eines weiteren Servers sofort in das Writequorum von A aufgenommen zuwerden. Im ubiksync-Kontext besitzt er durch das Mapping den VOTING-State, synchronisiertsich also nicht mehr mit A.Der dritte Fall behandelt den Ausfall des Masters A (Abb. 20). Nachdem von B und CSMALL SECONDS lang kein QUORUM WRITE von A empfangen wurde, ist fur beide das Quorumausgelaufen und sie wechseln in den VOTING-State. Beide Server haben zu diesem Zeitpunktentweder nur die Version des anderen in der Hostliste, die er beim Start des Quorums hatte, oderdiese wurde dadurch zuruckgesetzt, weil beide nicht miteinander kommuniziert haben und sichgegenseitig als disconnected deklariert haben. Da es ausserdem sein kann, dass C sich bereitsmit A synchronisiert hatte, bevor A ausfiel, wahrend sich B noch nicht auf dem aktuellen Standgebracht hatte, ist vor der Neuwahl ein erneuter Versionsaustausch erforderlich.Dazu wird im ubik loop bei jedem Eintritt in den VOTING-State gepruft, ob der letzte StateOTHER WRITE QUORUM war, also der Server Slave in einem WriteQuorum war. Ist diesder Fall, wird von allen Servern ausser dem ehemaligen Master die Version mittels CMD ASKVERerfragt.Sind nach dem Masterausfall noch mehr als die Halfte der Server aktiv, findet anhand derausgetauschten Versionen eine Neuwahl statt, die wie bereits beschrieben ablauft. Laufen nachdem Masterausfall weniger als oder genau n/2 Server, sendet SmaxDBminPos fortlaufendVOTEFORME-Messages aus, die von den anderen Servern mit VOTE YES beantwortet werden, aberzu keinem WriteQuorum fuhren.

6.3.7 Teilbaumreplikation

Wie bereits zu sehen war, wird das Flag icanbemaster nur gesetzt, wenn LDAP-Searchbase,slapd -Suffix und Common Suffix ubereinstimmen, sowie alle Atrribute repliziert werden. Es wirdgenutzt, um zu entscheiden, ob selbst VOTEFORME-Messages ausgesendet werden durfen, und ob

61

Abbildung 19: Nach dem Ausfall eines Slaves sind weniger als n/2 Server aktiv

selbige Anfragen anderer Server mit VOTE YES zu beantworten sind.Wird nun der aktuelle Server A gestartet, nachdem B und C bereits ein WriteQuorum gebildethaben, ist aber zum Beispiel so konfiguriert, dass er nur einen Teilbaum des Common Suffix’repliziert, passiert folgendes:Nach seinem Start findet ein Versionsaustausch zwischen ihm und den beiden laufenden Servernstatt. Beim Empfangen von A’s Antwort CMD MYVER <icanbemaster> <dbver> tragen B und Csowohl seine Datenbankversion als dbver als auch seine Mastertauglichkeit als canbemaster-Flagin ihre lokale Hostliste ein. A selbst pruft mit der Funktion islowestwithbiggestversion(me),ob er VOTEFORME’s aussenden darf, was hier durch das nicht gesetzte Flag verneint wird. Empfangter VOTEFORME-Messages von B, wird ebenfalls diese Funktion genutzt, die in diesem Fall eine po-sitive Ruckmeldung liefert.Da Datenbankversion und Mastertauglichkeit beim Start jedes Servers ausgetauscht werden unddie Hostliste laut Anforderung bei jedem Server gleich sein muss (also auch ihre Reihenfolge),gibt die Funktion islowestwithbiggestversion(id) uberall die selbe Antwort, wodurch Ver-klemmungen bei der Masterwahl praktisch ausgeschlossen sind.

6.3.8 Der RefreshAndPersist-Modus

Die bisherigen Erklarungen beiziehen sich primar auf die Nutzung des RefreshOnly-Modes, indem die Klienten periodisch nach Updates fragen und nach der Antwort seitens des Masters dieVerbindung wieder trennen. Im RefreshAndPersist-Mode, in dem die Slaves die Verbindung dau-erhaft aufrecht erhalten, sodass der Master sie aktiv mit Updates versorgen kann, ist folgendeszu beobachten:Fallt in einem bestehenden WriteQuorum der Master aus, melden die Slaves, dass der Masternicht erreichbar ist, da ihre bestehende Verbindung gekappt wurde, trennen anschliessend mit-tels ldap unbind() die entsprechende Verbindung, beenden die Synchronisation und geben alleRessourcen wie etwa den Socket wieder frei. An diesem Verhalten muss fur die Nutzung vonUbiksync nichts verandert werden, ausser die Anpassung der Fehlermeldung.Beim Ausfall eines Slaves mit anschliessender Quorumauflosung aufgrund unzureichender Hostan-

62

Abbildung 20: Ausfall des Masters

zahl gelangt, wie zu sehen war, jeder Slave schliesslich in den VOTING-State und beendet damitohnehin seine syncrepl-Tasks und damit auch die Verbindung zum Master, sodass nach einerNeuwahl ein neuer dauerhafter (persistent) Syncrequest ohne Komplikationen gestartet werdenkann. Bei der Aufrechterhaltung des Quorumns nach einem Klientenausfall gelangen die Slaveszwischenzeitlich in den UBIK-NULL QUORUM-State. Durch das Mapping in den Ubiksync-StateVOTING wird auch hier die SyncRequest-Verbindung getrennt, bevor sie von neuem initialisiertund der Request mit gleichen Attributen gestartet wird. Damit ist auch hier kein Fehlverhaltenzu erwarten.Wenn ein neuer Server in ein bestehendes Writequorum eintreten will, selbst aber sowohl dieaktuelle Version als auch die niedrigste Hostlistenposition besitzt, kommt es auch hier auf jedenFall zum Masterwechsel. Durch den Versionsaustausch nach dem Start von A und dem anschlies-sendem Quorumtimeout aufgrund unzureichender Stimmen fur B nehmen die beiden bisherigenQuorumteilnehmer nach einer gewissen Zeit den VOTING-Zustand ein, setzen die entsprechen-den Datenbankrestriktionen und C leert zusatzlich seine syncrepl-Taskliste. Beide wahlen ansch-liessend A als neuen Master, initialisieren den syncinfo-Struct sowie die Syncrepl-Taskliste undstarten mittels do syncrepl() den Synchronisationsvorgang. Auch hier ist funktional kein Un-terschied zur Nutzung des RefreshOnly-Modes erkennbar.Erwahnenswert ist jedoch, dass der syncrepl-Task, also die dauerhafte Verbindung zum Master,beim Ubergang in den Voting-State auf jeden Fall getrennt werden muss, auch wenn der ehema-lige Master weiterhin lauft, damit seine Verbindungspunkte (Sockets) wieder freigegeben werdenkonnen.

6.3.9 Behandlung von ungunstigen Konstellationen

Sowohl im RefreshOnly- als auch im RefreshAndPersist-Modus kommt es zu einem Problem,wenn der aktuelle Server A ein bestehendes Writequorum eintritt und kurz darauf (innerhalbSMALL SECONDS) der bisherige Master B absturzt. Da A nach dem Versionsaustausch von allenServern als SmaxDBminPos erkannt wird, bekommt B keine VOTE YES-Stimmen mehr. NachdemB etwa durch einen Ausfall nicht mehr erreichbar ist, hat er auch keine Gelegenheit, nach dem

63

Quorumtimeout ein CMD QUORUM NULL zu deklarieren und damit C in den ubiksync-VOTING-State zu setzen. Da die (Re)initialisierung der Taskliste und des syncinfo-Structs nur beim Uber-gang vom Master- oder Slave- in den Votingstate vorgenommen wird, versucht sich C weiterhinmit B zu synchronisieren, obwohl er fur A stimmt und fortlaufend QUORUM WRITE-Kommandosvon ihm erhalt, die er ebenfalls mit VOTE YES beantwortet.Die einfachste, aber auch optimalste, Losung fur dieses Problem ist, dass jeder Server, der vomubik-VOTING- in den SS WRITE QUORUM-State wechselt, also erstmals die Masterrolle uber-nimmt, zuvor durch das Senden eines CMD QUORUM NULL ein NullQuorum deklariert. Die Slaves,die dieses Kommando vom neuen Master erhalten, sind nach der Verarbeitung des Requests aufjeden Fall im ubiksync-VOTING-State. Wenn sie vorher bereits diesen Zustand hatten, weil nochkein Writequorum zustande gekommen war, wird keine erneute Initialisierung veranlasst, da nurein Wchsel des Zusatnds diese Aktion auslost. Waren sie hingegen noch im fur diesen Fall re-levanten SLAVE-State, wird in den VOTING-Zustand gewechselt, wodurch die Synchronisationmit B beendet und die Verbindung zu ihm getrennt wird. Sofort nach diesem Kommando sendetder Master ein CMD QUORUM WRITE, was alle Slaves (wieder) in den SLAVE-State versetzt.Beim Beitritt von neuen Servern in das WriteQuorum, die nicht SmaxDBminPos sind, bleibt derMaster im Zustand SS WRITE QUORUM deklariert also kein zwischenzeitliches Nullquorum.Ist der neue Server SmaxDBminPos und fallt der bisherige Master nicht aus, findet eine zwei-fache NullQuorum-Deklaration statt. Die slapd -spezifischen Aktionen werden aber nur bei ei-nem Zustandswechsel durchgefuhrt, sodass der Code nur einmal ausgefuhrt wird. Im Falle desAusfalls eines Slaves deklariert der Master durch den Timeout nur ein NullQuorum fur alleSlaves, um anschliessend wieder das WriteQuorum auszurufen, behalt aber selbst den ZustandSS WRITE QUORUM, weswegen diese Sonderbehandlung auch hier keine Anwendung findet.

6.4 Grenzfalle

6.4.1 Klientenaktionen wahrend des Quorum-Timeouts

Im Falle eines Masterausfalls merken die Slaves erst nach dem Timout des Quorums, also demAusbleiben von CMD QUORUM WRITE’s fur SMALL SECONDS, dass das Quorumm nicht mehrexistiert und treten in den VOTING-State ein. In dieser Zeit konnen sie sowohl Read- als auchUpdaterequests von lokalen Klienten annehmen. Letztere werden mit einem Referral zum (nichtmehr laufenden) Master beantwortet, sodass der Klient selbst versucht, eine Verbindung zumMaster herzustellen. Dieser Versuch schlagt unweigerlich fehl, wodurch das gewunschte Updatenicht vorgenommen werden kann. Damit ist zwar die Transparenz nicht mehr hundertprozentiggewahrleistet, aber es konnen keine Datenverluste oder gar Inkonsistenzen entstehen.Leseanfragen konnenin dieser Zeit, zumindest im RefreshAndPersist-Modus, ohne Bedenkenbeantwortet werden, da die Slaves bis zum Masterausfall mit allen Anderungen versorgt wurdenund, wie gerade zu sehen war, von keinem Slave im Quorum mehr Updates entgegen genommenwerden konnen, sodass auf jeden Fall aktuelle Daten geliefert werden.

6.4.2 Updates und Ausfalle im RefreshOnly-Modus

Die Konsistenz im RefreshOnly-Modus hangt stark vom konfigurierten interval ab, das die Zeitzwischen zwei Sync-Requests festlegt. Ist dieses zu klein eingestellt, wird unnotig Bandbreiteverbraucht, bei zu grossen Werten konnen Datenverluste auftreten, was mit folgendem Fall ver-deutlicht werden soll:Alle 5 Server der Hostliste A,B,C,D,E (n=5) nehmen an einem Writequorum teil, in dem Adie Masterrolle tragt. Klient K schickt einen Updaterequest an C, der mit einem Referral an Aantwortet. Nachdem K den Master kontaktiert und das Update vorgenommen hat, sendet B als

64

erster Slave einen Syncrequest und bekommt daraufhin die neuen Daten geliefert. Sollte nun derFall eintreten, dass sowohl A als auch B absturzen, bevor die anderen Slaves einen SyncRequestverschickt haben (weil ihr Intervall zu groos ist), findet die anschliessende Neuwahl nur unter dennicht-aktuellen Servern C, D und E statt. Da keiner von ihnen mit dem neuen Update versorgtwurde, die Bedingung i¿n/2 aber erfullt ist, gehen die Anderungen im entstehenden WriteQuorumverloren.Aufgrund dieses Nachteils wird ausdrucklich der Einsatz des RefreshAndPersist-Modus emp-fohlen, da hier die Wahrscheinlichkeit fur einen solchen Fall bedeutend geringer ist. Auf eineMoglichkeit zum volligen Ausschalten dieser Gefahr wird in einem spateren Abschnitt eingegan-gen.

6.5 Einsatzszenarien

Aufgrund der Nutzung des auf Banbreite optimierten LDAPsync-Mechanismus eignet sich dieentstandene Losung sowohl fur LAN- als auch fur WAN-Umgebungen. Auch die Prozessorlei-stung eines Servers wird durch die Nutzung des standartisierten LDAP-Protokolls nicht sonder-lich beansprucht. Die von UBIK beanspruchte Bandbreite hangt hingegen stark von der Anzahlder Server ab, die in der Hostliste vorhanden sind, denn jeder zusatzliche Server verursachtdie Vervielfachung der zu ubertragenden Versionen beim Neueintritt eines Hostlistenmitglieds.Da der Ausfall eines beliebigen Servers im Falle eines danach immer noch existierenden Write-Quorums toleriert werden kann, ist der Einsatz in fehleranfalligen Umgebungen reinen LDAP-Synchronisationsmechanismen vorzuziehen. Die Anwendung sowohl im LAN- als auch im WAN-Umfeld setzt voraus, dass alle teilnehmenden Server der Hostliste sich gegenseitig kennen (DNS)und berechtigt sind, Updates von allen anderen Servern entgegenzunehmen. Aufgrund des derzei-tigen Entwicklungsstandes ist der Einsatz in kritischen Umgebungen jedoch nicht zu empfehlen.

7 Der Quelltext

In diesem Abschnitt werden Auszuge aus dem Quelltext naher betrachtet, die einer Erklarungbedurfen.

7.1 UBIK

Der Hauptteil der Arbeit bestand in der Anpassung des UBIK-Wahlalgorithmus’, der komplettumgearbeitet werden musste, um die Zusammenarbeit mit dem LDAP-Server zu ermoglichen.Nur die Nutzung von lokal verwalteten Information (Hostliste, Zustande, Verbindungen) konnteweiterhin genutzt werden, musste aber ebenfalls erweitert werden.

7.1.1 Der ubik loop

static void *ubik_loop(void *conn){

time_t voting_temp;ubik_conn_t *ubikconn = (ubik_conn_t *)conn;voting_temp = (time_t) 0;vt = 0;

An dieser Stelle beginnt die Hauptschleife, die fur jeden internen UBIK-Zustand entsprechendeAktionen auslost.

65

while (1) {time_t now;

Als erstes wird gepruft, ob der slapd ein Signal zum Beenden von UBIK geschickt hat.

if ((ubikconn->closing == UBIK_YES) || (ubiksync_shutdown)) {pthread_exit(NULL);exit(1);

}time_t now;

Jetzt werden eventuelle Kommandos anderer UBIK-Instanzen gelesen und mit der gleich naherbetrachteten Funktion parse() verarbeitet.

/* read from other ubik instances */connections_select(ubikconn->connections); /* parse CMD’s */

Nun folgt die Auswertung des internen UBIK-Zustands:

now = time(NULL);switch(ubikconn->state) {

case VOTING:{

Mit folgendem Funktionsaufruf wird ubiksync aufgefordert, den slapd in den VOTING-State zuversetzen.

ubiksync_state_set_voting();if (state!=1)

{if (state == 4)

Wenn ein Server direkt vom OTHER WRITE QUORUM in den VOTING-State gelangt, ohnezwischenzeitlich im OTHER NULL QUORUM zu sein, kann nur der Master (die Synchroniza-tionSite) ausgefallen sein. In diesem Fall mussen alle anderen Server nach ihrer Version gefragtwerden, um bei der nun folgenden Neuwahl den realen SmaxDBminPos finden zu konnen. DieseAufgabe ubernimmt die Funktion hostlist hostunconnected().

{/* coming from OTHER_WRITE -> master must be down */printf("##### Master unreachable -> VOTING state\n");hostlist_hostunconnected(ubikconn,ubikconn->syncsite);printf("##### asking all Servers for versions\n");}

Da es sein kann, dass noch andere Server ausser der ehemalige Master ausgefallen sind, solltenauch deren Versionen nicht mehr berucksichtigt werden.

66

/* if we got in VOTING state caused by an *//* unreachable host clear it’s state */hostlist_clearunconnected(ubikconn);}

Sicherheitshalber sollte an dieser Stelle noch einmal sichergestellt werden, dass die Versionenaller verbundenen Hosts empfangen wurden.

/* if we didnt receive a version of a connected host, *//* ask for it */hostlist_get_unreceived_versions(ubikconn);

Nun folgt die Prufung, ob der lokale slapd als Master kandidieren kann. Ein VOTEFORMEkann nur alle SMALL SECONDS / 4 Sekunden ausgesandt werden, um das Netz nicht mitUBIK.Kommandos zu uberfluten. Ist diese ”inaktive“Zeit erreicht, wird mit der gleich naherbetrachteten Funktion hostlist islowestwithbiggestversion() gepruft, ob der slapd unterallen Servern mit der hochsten Versionsnummer die niedrigste Hostlistenposition hat und auchalle anderen Attribute besitzt, die ein potentieller Master benotigt. Die Funktion canvotefor()pruft, ob eine Selbstwahl moglich ist und broadcastet in dem Falle ein VOTEFORME an alleanderen Server.

/* Check, if i can send VOTEFORME */if (now - ubikconn->last_beacon > SMALL_SECONDS/4){if(hostlist_islowestwithbiggestversion

(ubikconn->hostlist,ubikconn->whoami_id) == UBIK_YES)

{if (canvotefor(ubikconn, ubikconn->whoami_id) == 1)

{ubikconn->last_beacon = now;vote_for_me(ubikconn);}

}}

}state = 1;break;

In den VOTING TEMP-Zustand gelangt ein Server zwischenzeitlich, wenn er fur die Verlange-rung eines Quorums stimmen soll. Hier wird nur gepruft, ob eventuell ein QuorumTi-meout vorliegt. Dies ist dann der Fall, wenn BIG SECONDS lang keine Kommando zuQuorum-Verlangerung empfangen wurde. Wird andererseits ein solches Kommando empfan-gen, setzt die parse()-Funktion den Zustand wieder auf OTHER NULL QUORUM oderOTHER WRITE QUORUM.

67

case VOTING_TEMP:{

if (vt){/* being some time in this state -> when slave in *//* write-quorum, master could be down */if (voting_temp != 0)

if ((now - voting_temp) > BIG_SECONDS){ubikconn->state = VOTING;ubiksync_state_set_voting();voting_temp = (time_t) 0;vt = 0;}

}else voting_temp = (time_t) now;vt = 1;

}break;

Wird vom Master ein CMD QUORUM NULL empfangen, deklariert jeder Slave lokal mittelsmydeclare quorum() ein NullQuorum, sodass der lokale slapd vom ubik loop veranlasst wird,die Replikation einzustellen. Die Funktion ubiksync state set nullquorum() veranlasst diegleichen Aktionen wie ubiksync state set voting().

case OTHER_NULL_QUORUM:{

if (state!=3) {ubik_log2(" state","OTHER_NULL_QUORUM",NULL);state=3;ubiksync_state_set_nullquorum("");}

}break;

Slaves in einem WriteQuorum rufen die Funktion ubiksync state set master() auf, die beimersten Zustandswechsel die Replikation startet. Anschliessend wird der bereits betrachteteZustand VOTING TEMP eingenommen.

68

case OTHER_WRITE_QUORUM:{

char *timeout_string;vt=0;voting_temp = (time_t) 0; /* reset.... */ubiksync_state_set_master("ubikconn->state: not known");if (state!=4) state=4;timeout_string=(char*)malloc(sizeof(char[100]));if ( now > ubikconn->quorum_until) {

ubik_log2 (" ubik_loop : Timeout!",NULL,NULL);}

ubikconn->state = VOTING_TEMP;}break;

Der Master in einem WriteQuorum veranlasst mit dem ersten Aufruf vonubiksync state set master(ME) das Einnehmen der Providerrolle des slapd..

case SS_WRITE_QUORUM:{

ubiksync_state_set_master("ME");if (state!=8)

{ubik_log2(" state","SS_WRITE_QUORUM",NULL);state=8;}

/* See if quorum still exists */

Konnte das WriteQuorum durch einen nicht antwortenden Slave fur SMALL SECONDS nichtverlangert werden, deklariert der Master fur alle Slaves ein NullQuorum, das heisst er sendet einCMD QUORUM NULL an jeden von ihnen, und versetzt sich selbst in den VOTING-Zustand,in dem, wie oben zu sehen war, der lokale slapd die Providerrolle aufgibt.

if ( now > ubikconn->quorum_until) {ubik_log2("##### Quorum timed out",NULL,NULL);declare_quorum(ubikconn, UBIK_NULL_QUORUM);ubikconn->state = VOTING;

Ansonsten sendet UBIK aller SMALL SECONDS/4 ein CMD QUORUM WRITE.

69

} else if (now - ubikconn->last_beacon > SMALL_SECONDS/4) {/* renew Quorum every SMALL_SECONDS/4 seconds */ubikconn->last_beacon = now;declare_quorum(ubikconn, UBIK_WRITE_QUORUM);

}}break;

default:ubik_log2(" state","unknown",NULL);ubikconn->state = VOTING;break;

}}

}

7.1.2 Die Funktion parse()

Die Funktion parse() wird nur aufgerufen, wenn connections select() eine Aktivitat aneinem der Sockets zu anderen UBIK-Instanzen erkannt hat, also ein Kommando zum Lesenbereit liegt.

static int parse(connections_t *connections, hostlist_t *hostlist,connection_list_t *item, connection_callbacks_t *cbs)

{int othercmd = 0;

Folgende Abfrage ist ein Relikt aus der ursprunglichen UBIK-Variante, wird aber zu Testzweckenweiterhin verwendet.

if (item->inmiddle == 1) {cmd = item->cmd;printf("continuing %s from %s\n",cmdstring(cmd), item->name);

Mit der Funktion prot getc() wird das erste Byte, also das Kommando selbst, dieser bereitstehenden Daten gelesen.

} else {cmd = prot_getc(item->pin);if (cmd == -1) {

printf ("##### error in getting CMD from %s\n",item->name);return UBIK_NOCONN;

}item->cmd = cmd;item->reading_state = READING_START;printf("<---- received %s from %s (%d)\n",

cmdstring(cmd),item->name,item->id);}

70

Die Funktion hostlist hostsentcmd() pruft, ob der entsprechende Host bereits vorher mituns Kontakt hatte, also schon Kommandos von ihm empfangen wurden. Ist das nicht derFall, veranlasst sie das Senden eines CMD ASKVER an diesen Host. Diese Aktion dient demAustausch aller Versionen beim Start eines Servers.

/* heard from this site */hostlist_hostsentcmd(hostlist, item->id);hostlist_heardfrom(hostlist, item->id);

Nun folgt die Auswertung des Kommandos:

switch (cmd){

Wurde die Stimme eines anderen Hosts empfangen, wird mit der Funktion myvoted yes()untersucht, ob genugend Stimmen fur die Eroffnung eines WriteQuorums vorhanden sind. Sindwir bereits Master in einem WriteQuorum, pruft die Funktion, ob NOCH genugend aktuelleStimmen vorhanden sind.

case CMD_VOTE_YES:/* ubiksync_state_set_voting(); */cbs->voted_yes(item->id, cbs->voted_yes_rock);

break;case CMD_VOTE_NO:

/* xxx do anything with this? */break;

case CMD_ASKVERSION:

Wurden wir nach unserer Version gefragt, sendet die Funktion mywhats version() den aktuellenContextCSN des slapd sowie die eigene Mastertauglichkeit zuruck.

ubik_log2("telling my version",NULL,NULL);cbs->whats_version(item->id, cbs->whats_version_rock);

break;

Beim Empfangen eines VOTEFORME-Kommandos pruft die Funktion myvote request(), obder anfragende Host SmaxDBminPos ist, ob er also gewahlt werden darf. Die entsprechendeAntwort wird anschliessend zuruck gesendet.

case CMD_VOTEFORME:{

res = cbs->vote_request(item->id, cbs->vote_request_rock);connections_lock(connections, item->id);if (res==UBIK_YES) {

connections_send_cmd(connections, item->id, CMD_VOTE_YES);} else {

connections_send_cmd(connections, item->id, CMD_VOTE_NO);}connections_flush_unlock(connections, item->id);

}break;

71

Beim Empfangen von Deklarationen fur ein Null- oder WriteQuorum werden ahnliche Aktionenausgefuhrt, weswegen diese beiden Kommandos in einem Quelltextabschnitt verarbeitet werden.

case CMD_QUORUM_WRITE:{othercmd = 1;}/* fall thru */

case CMD_QUORUM_NULL:{

item->inmiddle = 1;/* get the timeout (servertime + SMALL) => tmp */

Der erste Parameter beider Kommandos ist der Wert quorum until, ein 4-Byte Intergerwert.

r = prot_exactly_read(item->pin, (char *)&tmp, 4);

Die restlichen zu diesem Kommando gehorenden Daten geben die URL des Masters an.

/* get the LDAP-URI of new master */r = prot_exactly_read(item->pin, (char *)url, 50);

Nun folgt die einzige Unterscheidung, die aber in ihrer Auswirkung weitreichende Folgen hat.

if (othercmd == 1){

Hier wird dem lokalen slapd mittels ubiksync state set master(url) mitgeteilt, dass er dieSlaverolle einnehmen soll und sich mit dem Master <url> synchronisieren soll.

ubiksync_state_set_master(url);type = UBIK_WRITE_QUORUM;}

else{

Beim Eintritt in ein NullQuorum beendet der slapd alle Synchronisations-Tasks.

ubiksync_state_set_nullquorum(url);type = UBIK_NULL_QUORUM;}

printf (" received Masters LDAP URL : %s"," (newstate: %s)\n",url,cmdstring(cmd));

until = ntohl(tmp);

Es folgt die Deklaration des lokalen Quorum-Typs (Ubik-Zustands).

res = cbs->quorum_declaration(item->id, until, type,cbs->quorum_declaration_rock);

72

Auch Quorum-Deklarations-Kommandos mussen mit einer Stimme fur den Master beantwortetwerden.

item->inmiddle = 0;res = cbs->vote_request(item->id, cbs->vote_request_rock);connections_lock(connections, item->id);if (res==UBIK_YES) {

connections_send_cmd(connections, item->id, CMD_VOTE_YES);} else {

connections_send_cmd(connections, item->id, CMD_VOTE_NO);}connections_flush_unlock(connections, item->id);

}break;

Empfangene Versionen werden im folgenden Abschnitt ausgewertet: Auch das KommandoCMD VERIS ist ein Relikt aus der ursprunglichen Version von UBIK und diente der Verbreitungder eigenen Version eines gewahlten Masters, Das Kommando CMD MYVER wird von derFunktion mywhats version() gesendet, wenn ein CMD ASKVERSION empfangen wurde.

case CMD_MYVER:othercmd = 1;/* other cmd */

case CMD_VERIS:{

Auch hier werden die Parameter in mehreren Etappen gelesen, und zwar zuerst das Flag, dasdie Mastertauglichkeit des sendenden Servers angibt und als zweites der in einen Zeitstempelumgewandelte ContextCSN-Wert.

73

item->inmiddle = 1;switch(item->reading_state)

{case READING_START:

r = prot_exactly_read(item->pin,(char *)&icanbemaster, 4);

item->num1 = ntohl(icanbemaster);if (item->num1 == 0)printf ("<---- %s Cant Be Master\n",item->name);

elseprintf ("<---- %s is Mastercandidate\n",item->name);

item->reading_state = READING_STEP2;/* fallthru */

case READING_STEP2:r = prot_exactly_read(item->pin, (char *)&dbver, 8);if (r == 0) {

return UBIK_OK;} else if (r != 8) { /*NEWLONG 4*/

return UBIK_NOCONN;}dbver = ntohl(dbver);item->inmiddle = 0;

Beide Werte werden der Funktion mygot version() ubergeben, die sie in die lokale Hostlisteeintragt und auf Konformitat pruft.

cbs->got_version(item->id, item->num1, dbver,cbs->got_version_rock);

}return UBIK_OK;break;

}}break;

default:return UBIK_FAIL;break;

}return UBIK_OK;

7.1.3 Fur die Wahl wichtige Funktionen

Die Funktion canvotefor() bestimmt, wie auf ein VOTEFORME-Kommando zu antworten ist.

static int canvotefor(ubik_conn_t *ubikconn, int whom){

time_t now = time(NULL);

Wir konnen mit VOTE YES stimmen, wenn wir beim letzten Request den selben Host gewahlt

74

haben.

/* can vote for the same person again */if (ubikconn->whom_lastvoted == whom) {

return UBIK_YES;}

Wenn der lokale slapd Slave in einem WriteQuorum ist, kann fur keinen anderen Host gestimmtwerden.

/* if someone other than <whom> wants a vote from us, *//* when we are in WRITE_Quorums, answer with NO */

because we want to avoid an unneccesary change of the master */if (ubikconn->state == OTHER_WRITE_QUORUM) {

return UBIK_NO;}/* special case. if only one host don’t have to wait */if (ubikconn->total_hosts == 1) {

return UBIK_YES;}

Wenn wir nicht Slave in einem WriteQuorum sind, kann erst nach BIG SECONDS fur einenanderen Master gestimmt werden, als fur denjenigen, den wir vorher gewahlt haben.

/* can’t vote if last voted within BIGif (now - ubikconn->time_lastvoted < BIG_SECONDS) {

return UBIK_NO;}/* otherwise different vote but BIG has elapsed */return UBIK_YES;

}

Die Funktion declare quorum(), die den Slaves die Kommandos CMD QUORUM WRITE oderCMD QUORUM NULL sendet, nutzt fur die Berechnung des quorum until-Werts die Funktionoldestinquorum(). Sie gibt den Zeitpunkt der Stimme des Hosts zuruck, dessen Vote amlangsten zuruckliegt, der aber noch nicht als disconnected angenommen wurde.

time_t hostlist_oldest_inquorum(hostlist_t *hostlist) /* xxx , type */{

time_t now = time(NULL);time_t oldest = now;for (lup=0;lup<hostlist->num;lup++)

if (now - hostlist->hosts[lup].received_vote <= SMALL_SECONDS)/* not disconnected */if (hostlist->hosts[lup].received_vote < oldest)

oldest = hostlist->hosts[lup].received_vote;return oldest;

Mywhats version() gibt eine Antwort auf einen CMD ASKVERSION-Request. Sie nutzt dazudie Funktionen ubik canibemaster() und getdbversion(), um die entsprechenden aktuellen

75

Werte zu bekommeni, und sendet diese zuruck.

int mywhats_version(int from, void *rock){

int _icanbemaster=ubik_canibemaster();ubik_conn_t *ubikconn = (ubik_conn_t *)rock;net_canibemaster=htonl(_icanbemaster);/* get version from ldap */getdbversion(qver, dbver);ubikconn->quorum_version = *qver;ubikconn->db_version = *dbver;/* send version to <from> */net_dbver = htonl(*dbver);connections_lock(ubikconn->connections, from);connections_send_cmd(ubikconn->connections,from, CMD_MYVER);connections_send_len(ubikconn->connections,from,

(char *) &net_canibemaster, 4);connections_send_len(ubikconn->connections,from,

(char *) &net_dbver, 8);connections_flush_unlock(ubikconn->connections, from);return UBIK_OK;

Myvote request() wird von parse() aufgerufen, wenn ein CMD VOTEFORME empfangenwurde.

int myvote_request(int from, void *rock){

ubik_conn_t *ubikconn = (ubik_conn_t *)rock;

Wenn vom anfragenden Host noch keine Version empfangen wurde, was eigentlich nicht vorkom-men sollte, wird danach gefragt und eine negative Antwort gegeben.

if (hostlist_gotversionfrom(ubikconn->hostlist, from) == UBIK_NO){hostlist_askversion(ubikconn,from);printf ("----> returning VOTE NO, because got no version ",

" from %d\n",from);return UBIK_NO;}

Sollte der anfragende Host SmaxDBminPos sein, wird mit canvotefor() gepruft, ob oben ge-nannte Bedingungen auch erfullt sind und dann entsprechend ein positiver Ruckmeldung geliefert.

76

if (hostlist_islowestwithbiggestversion(ubikconn->hostlist,from) == UBIK_YES)

{

if (canvotefor(ubikconn, from)==UBIK_YES){ubikconn->whom_lastvoted = from;ubikconn->time_lastvoted = time(NULL);/*printf ("----> returning VOTE_YES to %d\n",from);*/return UBIK_YES;}

else{printf ("----> returning VOTE NO, because cant vote",

" for %d\n",from);return UBIK_NO;}

}

Wenn <from> nicht SmaxDBminPos ist, darf nicht fur ihn gevotet werden.

else{printf ("----> returning VOTE NO, because %d is not lowest\n",from);return UBIK_NO;}

}

Beim Empfangen einer VOTE YES-Stimme wird die Funktion myvoted yes() aufgerufen.

int myvoted_yes(int from, void *rock){

ubik_conn_t *ubikconn = (ubik_conn_t *)rock;hostlist_gotvotefrom(ubikconn->hostlist, from);

/* we didn’t have enough votes to build a write quorum -> *//* check again... If we overstep the i>n/2 condition through *//* this vote, we can declare a WriteQuorum with this host as master */

Wenn wir uns im VOTING-Zustand befinden, ist an dieser Stelle zu prufen, ob wir mit derneuen Stimme jetzt genugend Votes haben, um ein WriteQuorum zu deklarieren.

if ((ubikconn->state == VOTING) || (ubikconn->state == VOTING_TEMP)){

/* we are waiting for enough votes, so we can be Master *//* in a Write Quorum */if ((hostlist_total_mastercandidate_votes(ubikconn->hostlist,

UBIK_NULL_QUORUM)*1.)/(ubikconn->total_hosts*1.) > 0.5){

Ist dies der Fall wird lokal der Zustand SS WRITE QUORUM eingenommen und mittels

77

declare quorum() ein CMD QUORUM WRITE an alle Hosts geschickt, die bereits fur uns ge-votet haben. Weiterhin wird der lokale slapd dazu veranlasst, den MASTER-State einzunehmen.

/* YES, we have now enough votes to get master of a WriteQuorum */int votes;votes=hostlist_total_mastercandidate_votes(ubikconn->hostlist,

UBIK_NULL_QUORUM);ubik_log2("##### Now we have enuff Votes from mastercandidates ",

" -> Declaring WriteQuorum",NULL,&votes);/* declare WriteQuorum internally */ubikconn->state = SS_WRITE_QUORUM;/* put <from> internally in a WriteQuorum state */hostlist_wquorum(ubikconn->hostlist,from);

Um ein direktes Wechseln der Slaves von einem WriteQuorum in ein anderes zu verhindern,deklariert jeder Server, der erstmals die Masterrolle ubernimmt, zuerst ein NullQuorum, umdie Slaves dazu zu veranlassen, ihre Synchronisation mit dem alten Master einzustellen. Gleichdanach wird ein eigenes WriteQuorum deklariert, wodurch sich die Slaves nun mit diesem Serversynchronisieren.

declare_quorum(ubikconn, UBIK_NULL_QUORUM);/* send a QUROM_WRITE to all hosts */declare_quorum(ubikconn, UBIK_WRITE_QUORUM);ubik_log2("##### Entering write quorum as sync site",NULL,NULL);/* tell this decision to local ubiksync */ubiksync_state_set_master("ME");

}}

Sind wir bereits Master in einem WriteQuorum, wird gepruft, ob mit der neuen Stimme dieBedingung i > n/2 erfullt ist. Ist dies nicht der Fall, wird allen Hosts ein CMD QUORUM NULLzugesandt und der lokale slapd in den NullQuorum- (VOTING-) zustand versetzt.

/* We are master in a WriteQuorum -> handle votes...*/else if (ubikconn->state == SS_WRITE_QUORUM) {

if ((hostlist_total_mastercandidate_votes(ubikconn->hostlist,UBIK_NULL_QUORUM)*1.)/(ubikconn->total_hosts*1.) <= 0.5)

{/* we no longer have enough votes, it seems that either *//* a voting Host is down, *//* or the others are voting for someone else */declare_quorum(ubikconn, UBIK_NULL_QUORUM);ubik_log2("##### We no longer have enough votes to be ",

"sync site",NULL,NULL);ubiksync_state_set_nullquorum("ME");}

Sollte die Bedingung erfullt sein, der neue Host aber noch nicht im WriteQuorum sein, wird eraufgenommen.

78

else if (hostlist_inquorum(ubikconn->hostlist, from,UBIK_WRITE_QUORUM)==UBIK_NO)

{/* We are SS in a WriteQuorum and got a Vote from a Host *//* not being in this WriteQuorum simply host him and put *//* him in WriteQuorum State */printf ("##### %s joins our WriteQuorum \n",

hostlist_id2name(ubikconn->hostlist,from));hostlist_wquorum(ubikconn->hostlist,from);declare_quorum(ubikconn, UBIK_WRITE_QUORUM);}

return UBIK_OK;}

Die Aufgabe der Funktion connections select() ist neben der Uberwachung der bestehendenSockets auch die Annahme neuer Verbindungswunsche anderer UBIK-Instanzen. Wird einesolche Verbindung akzeptiert, folgt ein Aufruf der Funktion hostlist hostconnected():

void hostlist_hostconnected(hostlist_t *hostlist,int id){int *_qver, lup;long int *_dbver;

Laut Spezifikation soll nun jeder Host, der eine Verbindung annimmt, den verbindenden Hostnach seiner Version fragen. Da dieser beim empfangen des CMD ASKVER ebenfalls durchhostlist hostsentcmd() die Version erfragt, wird die lokale Version hier sicherheitshalber indie Hostliste eingetragen.

getdbversion(_qver,_dbver);hostlist->hosts[hostlist->me_id].dbver = *_dbver;

Anschliessend wird jeder andere Host nach seiner Version gefragt, sodass nach einer gewissenZeit jeder Server die aktuelle Version der anderen kennen sollte.

for (lup=0;lup < hostlist->num;lup++){if (lup != hostlist->me_id)

{hostlist->hosts[lup].askedforversion = 0;hostlist_askversion(hostlist->ubikconn,lup);hostlist->hosts[lup].connected = 1;hostlist->hosts[lup].askedforversion = 1;}

}}

Entsprechend pruft die Funktion hostlist hostsentcmd(), ob vom fragenden Host bereits dieVersion empfangen wurde. Ist dies nicht der Fall, wird sie von ihm erfragt.

79

void hostlist_hostsentcmd(hostlist_t *hostlist,int id){/* each server, a new server connects to, sends automatically an *//* ASK_VERSION. this command should cause the connecting host also *//* to ask for all versions */if(hostlist->hosts[id].askedforversion == 0)

{hostlist_askversion(hostlist->ubikconn,id);hostlist->hosts[id].connected = 1;hostlist->hosts[id].askedforversion = 1;}

}

Nun kommen wir zu der bereits oft erwahnten Funktion host-list islowestwithbiggestversion(), die als einzige daruber entscheidet, welcher Serverzum Master kandidieren oder gewahlt werden kann. Diese Funktion wird sowohl bei der Frage,ob sich ein Server als Master bewerben kann (ob er VOTEFORME’s senden darf), als auch beider Beantwortung dieses Kommandos genutzt.

int hostlist_islowestwithbiggestversion(hostlist_t *hostlist, int from){

long int maxdbver=-1; long int from_dbver=-1;time_t now = time(NULL);

Als erstes werden die Server herausgefiltert, sich als Master ungeeignet sind, weil sie nur einenTeilbaum des CommonSuffix’ replizieren oder verwalten.

/* we only say yes, if <from> is a potential master */if (hostlist->hosts[from].canbemaster == 0) { return UBIK_NO;}

Anschliessend wird die maximalste Version aller Hostlisteneintrage und die Version von <from>bestimmt.

/* first get the biggest dbversion and the version of <from> */for (lup=0;lup < hostlist->num;lup++)

{if (hostlist->hosts[lup].dbver > maxdbver)

{maxdbver=hostlist->hosts[lup].dbver;}

if (hostlist->hosts[lup].id == from)from_dbver=hostlist->hosts[lup].dbver;

}

Hat <from> in der lokalen Hostliste nicht die maximale Version, ist er ebenfalls kein Master-kandidat.

if (from_dbver < maxdbver) return UBIK_NO;

Ist seine Datenbank hingegen auf dem aktuellen Stand, wird als letztes noch gepruft, ob ein

80

anderer erreichbarer Host mit der selben Version eine niedrigere Hostlistenposition hat und sichauch als Master eignet. Wird ein solcher Server gefunden, darf nicht fur <from> gevotet werden.

else /* <from> has one of he biggest versions */{/* if the first in list -> he is lowest with maxdbver */if (from == 0) return UBIK_YES;/* should only compare with hosts we’ve heard from in BIG *//* if we’ve heard from someone else lower in BIG say NO */for (lup = 0;lup < from; lup++)

{/* if someone lower than <from> also has the maxdbversion, *//* <from> is not lowestwithbiggestversion */if ((now - hostlist->hosts[lup].heard_from < BIG_SECONDS) &&

(hostlist->hosts[lup].dbver == maxdbver) &&(hostlist->hosts[lup].canbemaster == 1)){return UBIK_NO;}

}}

return UBIK_YES;}

Die bereits verwendete Funktion hostlist total mastercandidate votes() summiert dieStimmen aller Hosts, die uns innerhalb der letzten SMALL SECNODS gewahlt haben mit dereigenen Stimme.

81

int hostlist_total_mastercandidate_votes(hostlist_t *hostlist, int type){

int total_votes = 0;time_t now = time(NULL);

for (lup=0;lup<hostlist->num;lup++){

if (hostlist->hosts[lup].isme == 1){if (hostlist->hosts[lup].canbemaster == 1)

total_votes++;}

else if ((now - hostlist->hosts[lup].received_vote <= SMALL_SECONDS) &&(hostlist->hosts[lup].inquorum >= type))

{if (hostlist->hosts[lup].canbemaster == 1)

total_votes++;}

else {hostlist->hosts[lup].inquorum = UBIK_VOID;}

}

return total_votes;}

Schliesslich ist noch die Funktion hostlist oldest inquorum() zu betrachten, die fur Quorum-timeouts seitens des Masters verantwortlich ist. Sie sucht, wie zu sehen ist, die Zeit der letztenletzten Stimme, die aber noch weniger als SMALL SECONDS zuruckliegt. Nach dieser Zeitdeklariert der Master diesen Host als disconnected und sollte dann seine letzte Stimme nichtmehr in die Suche einbeziehen.

time_t hostlist_oldest_inquorum(hostlist_t *hostlist) /* xxx , type */{

time_t now = time(NULL);time_t oldest = now;for (lup=0;lup<hostlist->num;lup++){

if (now - hostlist->hosts[lup].received_vote <= SMALL_SECONDS) {

if (hostlist->hosts[lup].received_vote < oldest) {oldest = hostlist->hosts[lup].received_vote;

}}

}

return oldest;}

82

7.2 Modifizierter slapd-Quelltext

Der Originalquelltext von openLDAP sollte moglichst wenig verandert werden, sodass so weitwie moglich der ihn beeinflussende Code nach ubiksync verlagert wurde. An dieser Stelle sollnicht auf jede Kleinigkeit eingegangen, sondern nur die Ausschnitte dargeboten werden, an denenrelevante Aktionen ausgefuhrt werden. Fur Interessierte findet sich im Quelltextpaket eine Listemit allen Anderung am Originalquelltext.

7.2.1 Die Initialisierung

Der beim Start aufgerufenen Funktion slapd daemon init() wird die als Argument gelie-ferte URL ubergeben, die mittels ubiksync put slapd url() in ubiksync zwischengespei-chert wird. Anschliessend werden beim Parsen den Konfigurationsfiles slapd.conf mittelsubiksync put slapd suffix() und ubiksync put slave syncinfo() weitere fur ubiksyncwichtige Daten zwiischengespeichert, sowie durch die Auswertung des Schlusselworts ubiksyncdie eigentliche Nutzung von ubiksync getriggert.

7.2.2 Der slapd daemon task

Nach der Eroffnung und Initialisierung des ubiksync-Sockets und der Aufnahme in die vonselect() uberwachte Socketmenge wird die Hauptschleife gestartet. Wird dieser Socket akti-viert, liegt also eine Nachricht der lokalen UBIK-Instanz vor, wird folgender Quelltext ausgefuhrt:

if(use_ubiksync()){if ( FD_ISSET( ubiksync_sock, &readfds ) )

{int ubiksync_error=0;FD_CLR (ubiksync_sock,&readfds);

Der Verbindungswunsch der Gegenseite wird akzeptiert.

ubiksync_msgsock = accept(ubiksync_sock,0,0);if (ubiksync_msgsock < 0)

{Debug (LDAP_DEBUG_ANY,"error creating msg socket\n",0,0,0);ubiksync_error=1;}

if (ubiksync_msgsock >= dtblsize){Debug (LDAP_DEBUG_ANY,"descriptor beyond table size\n",0,0,0);ubiksync_error=1;}

if ((ubiksync_msgsock > 0) && (ubiksync_error == 0)){

Der von ubiksync gesendete Request wird in einem ubiksync request-Struct ubertragen unddie gelesenen Daten in einer lokalen Kopie dieses Structs gespeichert.

l=read(ubiksync_msgsock,rq,sizeof(ubiksync_request));

83

Je nach Belegung der Structvariablen werden nun unterschiedliche Parameter an die Funktionubiksync change sync state() ubergeben, die gleich naher betrachtet wird. Der Name, oderbesser gesagt die URL, des neuen Masters muss nur den Slaves ubergeben werden, da der Masterseine URL selbst kennt und sie im VOTING-State keine Rolle spielt.Auf die syncrepl-Taskliste wird vom slapd uber den Pointer syncrepl rq zugegriffen (die syn-crepl runquoeue). Um zu verhindern, dass ein anderer Programmteil wahrend der Verarbeitungdieser Funktion die Taskliste verandert oder ausfuhrt, wird durch einen sogenannten Mutex(Semaphor) der exklusive Zugriff beantragt, der nach der Ausfuhrung wieder freigegeben wird.Notig ist das, weil die Funktion bei jedem der 3 Belegungen selbst die Taskliste initialisiert oderleert.

switch (rq->request_id){case UBIKSYNC_RQ_CHANGE_SYNCSTATE:

printf ("##### slapd_daemon_task : ubiksync requestedme to change sync state\n\n");

switch (rq->newstate){case UBIKSYNC_STATE_MASTER:

ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );l=ubiksync_change_sync_state(rq->newstate,

rq->oldstate, (char*) NULL);ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );break;

case UBIKSYNC_STATE_SLAVE:ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );l=ubiksync_change_sync_state(rq->newstate,

rq->oldstate, rq->newmaster);ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );break;

case UBIKSYNC_STATE_VOTING:ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );l=ubiksync_change_sync_state(rq->newstate,

rq->oldstate, (char*) NULL);ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );break;

default:printf ("##### new state unknown :%d\n",rq->newstate);break;

}

Um eine Meldung uber den Erfolg an ubiksync liefern zu konnen, wird eine entsprechendeAntwort generiert und zuruckgesendet.

84

if (l==1){rq->request_id = UBIKSYNC_RP_CHANGE_SYNCSTATE_SUCCESS;}

else{rq->request_id = UBIKSYNC_RP_CHANGE_SYNCSTATE_NOSUCCESS;}l=write (ubiksync_msgsock,rq,sizeof(ubiksync_request));break;

}close (ubiksync_msgsock);}

} /* use_ubiksync() */

7.3 Ubiksync

An dieser Stelle ist zwischen 2 Teilen zu unterscheiden, dem Interface, das UBIK fur den slapdanbietet und die Schnittstelle, die UBIK vom slapd angeboten bekommt.Die Funktionen ubiksync get sync ctxcsn() und ubiksync change sync state() stellen dasInterface dar, das der slapd-Teil von ubiksync anbietet.

7.3.1 Ubiksync get sync ctxcsn()

Diese Funktion dient der Findung des maximalen Wert aus ContextCSN und allen ctxcsn-Werten, die in Slave-Cookies gespeichert sind.

char* ubiksync_get_sync_ctxcsn (){

Nach der Initialisierung aller benotigten Variablen wird der gespeicherte suffix dbsuffix genutzt,um den Verweis auf das entsprechende Backend zu erhalten. Dazu ist zu sagen, dass der slapdnur je einen Suffix pro Server haben kann. aber auf einem Rechner mehrere Server laufen konnen,von denen jeder ein seperates Backend nutzt. Zur Vereinfachung wurde hier angenommen. dassnur ein Server pro Host lauft, da UBIK ohnehin nur Hosts unterscheiden kann, nicht aberunterschiedliche Prozesse auf ein und demselben Host.

/* get the backend, because all ops on syncrepl are based on it */be = select_backend( &slap_be_select , 0, 0 );if (be == NULL) printf ("error: cant select backend...\n");

Im folgenden Quelltextabschnitt wird der gespeicherte Suffix normalisiert (standardisiert), umihn fur die folgenden Funktionsaufrufe nutzen zu konnen.

/* normalize the backend-suffix-dn to work with it */dnPrettyNormal( NULL, &slap_suffix, &prettysuffixdn,

&normalsuffixdn, NULL );/* now we try to find the maximum ctxcsn entry from all *//* slave entries and the master entry */

85

Nun wird nach einem ContextCSN innerhalb der gefundenen Backend-Datenbank gesucht.Dazu wird der normalisierte Suffix an den String cn=ldapsync angehangt, um den DN desSyncConsumerSubentry’s zu bilden.

/* build suffix for potential masters to search for their ctxcsn */build_new_dn( &ctxcsn_mdn, (struct berval *)&normalsuffixdn,

(struct berval *)&slap_ldapsync_cn_bv, NULL );

Dieser wird im folgenden gesucht. Hierzu kann keine normale LDAP-Suchanfrage genutztwerden, da dieser Eintrag normalerweise fur Nutzer nicht sichtbar ist.

/* get id from this entry */ctxcsn_id = be->bd_info->bi_tool_dn2id_get( be, &ctxcsn_mdn );if (ctxcsn_id >= 0)

{/* if that entry was found read it */be->bd_info->bi_tool_id2entry_get( be, ctxcsn_id, &ctxcsn_e );

Ist er gefunden worden, wird sein Attribut ContextCSN extrahiert und als zwischenzeitlicherMaximalwert gespeichert.

/* get the attribute with schema si_ad_contextCSN */attr = attr_find( ctxcsn_e->e_attrs,slap_schema.si_ad_contextCSN);/* copy only the date value to the maxtimestamp to *//* compare it later */strncpy(maxtimestamp,attr->a_vals[0].bv_val,

sizeof("19000101000000")-1);}

Es folgt die Suche nach dem SyncConsumerSubentry, dessen rid laut sync-Spezifikation denMaximalwert 999 einnehmen kann.

/* now search for all slave entries for syncreplCookie */for (i=0; i < 1000; i++) /* the rid can be max 999 */

{sprintf (tmpslavedn,"cn=syncrepl%d",i);BER_BVSTR(&slap_syncrepl_cn_bv,tmpslavedn);sprintf (ctxcsn_mdn.bv_val,"%s,%s",slap_syncrepl_cn_bv.bv_val,

normalsuffixdn.bv_val);ctxcsn_mdn.bv_len=strlen(tmpslavedn)-1 +

strlen(normalsuffixdn.bv_val)+2;

Ist auch hier der DN der Form cn=syncrepl<i>,<Suffix> zusammengesetzt, folgt die Suchenach einem entsprechenden Eintrag.

86

ctxcsn_id = be->bd_info->bi_tool_dn2id_get(be,&ctxcsn_mdn);if (ctxcsn_id >= 0)

{be->bd_info->bi_tool_id2entry_get( be,

ctxcsn_id, &ctxcsn_e );if (ctxcsn_e != NULL)

{

Wurde dieser gefunden, wird sein Attribut syncreplCookie benutzt, um den csn-Wert zuextrahieren, ihn mit dem bisherigen Maximalwert zu vergleichen und diesen gegebenenfalls durchden gefundenen Wert zu ersetzen.

attr = attr_find( ctxcsn_e->e_attrs,slap_schema.si_ad_syncreplCookie);

/* find the csn string in the cookie */tmp=strstr(attr->a_vals[0].bv_val,"csn=");tmp+=4;strncpy(tmptimestamp,tmp,sizeof("19000101000000")-1);if (strcmp(maxtimestamp,tmptimestamp) < 0)

maxtimestamp=strdup(tmptimestamp);}

}}

Wurde gar kein entsprechender Wert (von Provider und Consumer) gefunden, wird kein Wertzuruckgegeben, ansonsten liefert diese Funktion den berechneten Maximalwert

if (strcmp(maxtimestamp,tmptimestamp) == 0)/* didnt find any ctxcsn */

return (NULL);else

return (maxtimestamp);}

7.3.2 Ubiksync change syncstate()

Diese schon oft erwahnte Funktion wird direkt vom slapd daemon task() gerufen, wenn er einKommando am ubiksync-Socket erhalt.

int ubiksync_change_sync_state(int newstate, int oldstate,char *newmaster_uri)

{

Die erste Aktion nach der Initialisierung ist die Prufung, ob uberhaupt ein Zustandswechselnotwendig ist.

if (newstate == oldstate) return 0;/* no change of the state necessary */

87

Auch hier wird das entsprechende Backend in gleicher Weise gefunden.

bd = select_backend( &slap_suffix , 0, 0 );

switch (newstate){

Sollte der VOTING-Zustand als Parameter ubergebn worden sein, werden folgende Aktionenausgefuhrt:

case UBIKSYNC_STATE_VOTING:{

Sollte der Server vorher ein Slave gewesen sein, wird die Synchronisation mit dem Masterbeendet, die eventuell bestehende Verbindung getrennt und die Verweise vom Backend auf densyncinfo-Struct geloscht, da diese im VOTING-Zustand nicht mehr benotigt werden.

while ( !LDAP_STAILQ_EMPTY( &bd->be_syncinfo )) {si_entry = LDAP_STAILQ_FIRST( &bd->be_syncinfo );if ((si_entry->si_type == LDAP_SYNC_REFRESH_AND_PERSIST)

&& (si_entry->si_ld)){ldap_get_option( si_entry->si_ld, LDAP_OPT_DESC, &s );if (s > 0)

connection_client_stop( s );ldap_unbind( si_entry->si_ld );si_entry->si_ld = 0;printf ("stopped RefreshAndPersist-Task\n");}

LDAP_STAILQ_REMOVE_HEAD( &bd->be_syncinfo, si_next );}

Anschliessend werden alle noch anstehenden syncrepl-Tasks beendet.

rtask=ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat);if (rtask != NULL)

ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );

Zuletzt sind Restriktionen fur das Backend zu setzen: Die SHADOW-Werte kennzeichenen dieSlaverolle in einem Replikationsprozess, der jetzt nicht mehr stattfindet. Das Schreiben beiServern, die sich in keinem WriteQuorum befinden, soll laut Anforderungen verboten werden;die Leseerlaubnis wird durch die entsprechende Konfiguration festgelegt.

88

SLAP_DBFLAGS(bd) &= !SLAP_DBFLAG_SHADOW;SLAP_DBFLAGS(bd) &= !SLAP_DBFLAG_SYNC_SHADOW;/* dont allow writes on voting servers */bd->be_restrictops |= SLAP_RESTRICT_OP_WRITES;global_restrictops |= SLAP_RESTRICT_OP_WRITES;if (!always_allow_reads)

{/* dont allow reaeds on voting servers */bd->be_restrictops |= SLAP_RESTRICT_OP_READS;global_restrictops |= SLAP_RESTRICT_OP_READS;}

return(1);}

Wenn von UBIK die Masterrolle verlangt wurde, sollten ebenfalls die Backend-Verweise zumsyncinfo-Struct aufgelost und die anstehenden syncrepl-Tasks beendet und geloscht werden.

case UBIKSYNC_STATE_MASTER:{while ( !LDAP_STAILQ_EMPTY( &bd->be_syncinfo )) {

si_entry = LDAP_STAILQ_FIRST( &bd->be_syncinfo );LDAP_STAILQ_REMOVE_HEAD( &bd->be_syncinfo, si_next );}

rtask=ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat);if (rtask != NULL) /* this should always happen in Slave mode */

{ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );}

Da einem Master sowohl Lese- als auch Schreiboperationen uneingeschrankt erlaubt werden,sind die entsprechenden Restriktionen hier zuruck zu setzen.

/* unset SHADOW DB Flags */SLAP_DBFLAGS(bd) &= !SLAP_DBFLAG_SHADOW;SLAP_DBFLAGS(bd) &= !SLAP_DBFLAG_SYNC_SHADOW;bd->be_restrictops &= !SLAP_RESTRICT_OP_WRITES;global_restrictops &= !SLAP_RESTRICT_OP_WRITES;bd->be_restrictops &= !SLAP_RESTRICT_OP_READS;global_restrictops &= !SLAP_RESTRICT_OP_READS;return(1);break;}

Die Einnahme der SLAVE-Rolle bringt die meisten Aufgaben mit sich.

case UBIKSYNC_STATE_SLAVE:{

Die ubergebene URL des neuen Master wird zuerst als neuer Provider im syncinfo-Structeingetragen.

89

masteruri = strdup(newmaster_uri);ubiksync_slave_syncinfo->si_provideruri = strdup(masteruri);LDAP_STAILQ_INIT( &bd->be_syncinfo );ber_str2bv( ubiksync_slave_syncinfo->si_provideruri,

strlen( ubiksync_slave_syncinfo->si_provideruri ), 1,&ubiksync_slave_syncinfo->si_provideruri_bv[0] );

Nun folgt die Neuinitialisierung des lokal durch ubiksync put slave syncinfo() gespeichertenAbbilds der Originalkonfiguration des Slaves, also der Werte, die in slapd.conf angegeben wordensind. Einige dieser Daten mussen neu initialisiert werden, da ihre Existenz durch den Gebrauchvon Mehrfachzeigern nicht mehr garantiert oder die Belgung mit einem Ausgangswert erforderlichist. Dazu zahlen der Verweis zum Backend und der Socketdeskriptor fur die Kommunikation mitdem Master, Die Listen der zu replizierenden Attribute wurden beim Zwischenspeichern denStructs gesondert hinterlegt und werden nun zuruckgespielt.

ubiksync_slave_syncinfo->si_be = bd;/* NOW recharging attrs , exattrs ... */for (i=0;ubiksync_attrs[i] != NULL;i++)

{ubiksync_slave_syncinfo->si_attrs[i] = ubiksync_attrs[i];}

assert (ubiksync_exattrs != NULL);for (i=0;ubiksync_exattrs[i] != NULL;i++)

{ubiksync_slave_syncinfo->si_exattrs[i] = ubiksync_exattrs[i];}

ubiksync_slave_syncinfo->si_presentlist = NULL;LDAP_LIST_INIT( &ubiksync_slave_syncinfo->si_nonpresentlist);

Das eventuell vorhandene Cookie sollte ebenfalls geloscht und wahrend der spateren Replikationerneut aus der Datenbank gelesen werden.

slap_sync_cookie_free( &ubiksync_slave_syncinfo->si_syncCookie,0);

Im Folgenden wird dem Backend mitgeteilt, dass bei Writerequests die angegebene URL alsReferral an den Klienten zuruck zu liefern ist.

newreferral[0].bv_val = strdup(masteruri);newreferral[0].bv_len = strlen( newreferral[0].bv_val );if(value_add( &bd->be_update_refs, newreferral))

printf ("###### Error in adding new referral\n");

Nun wird der soeben generierte syncinfo-Struct mit dem Backend verlinkt und gepruft, ob sichdas Backend fur die Syncreplikation eignet.

90

LDAP_STAILQ_INSERT_TAIL( &bd->be_syncinfo,ubiksync_slave_syncinfo, si_next );

if ( !LDAP_STAILQ_EMPTY( &bd->be_syncinfo )){if ( !( &bd->be_search && &bd->be_add &&

&bd->be_modify && &bd->be_delete )){printf("database does not support operations

required for syncrepl", i);return (0);}

Auch im Falle der Einnahme des SLAVE-States sind sowohl Lese- als auch Schreiboperationenerlaubt. Letztere werden jedoch durch das Vorhandensein der SLAP DBFLAG SHADOW- undSLAP DBFLAG SYNC SHADOW-Flags im Zusammenhang mit dem Updatereferral durch ein Referralzum Master beantwortet.

SLAP_DBFLAGS(bd) |= SLAP_DBFLAG_SHADOW;SLAP_DBFLAGS(bd) |= SLAP_DBFLAG_SYNC_SHADOW;bd->be_restrictops &= !SLAP_RESTRICT_OP_WRITES;global_restrictops &= !SLAP_RESTRICT_OP_WRITES;bd->be_restrictops &= !SLAP_RESTRICT_OP_READS;global_restrictops &= !SLAP_RESTRICT_OP_READS;

Schliesslich wird die Taskliste neu initialisiert, um eventuell vorhandene Relikte aus fruherenZustanden restlos zu entfernen, und die Repliaktion mit aktuellen Werten fur Master, updaterefu.s.w. gestartet.

LDAP_STAILQ_INIT( &syncrepl_rq.task_list );LDAP_STAILQ_INIT( &syncrepl_rq.run_list );ldap_pvt_runqueue_insert( &syncrepl_rq,

ubiksync_slave_syncinfo->si_interval,do_syncrepl, (void *) ubiksync_slave_syncinfo );

}return(1);break;

}}return (0);

}

7.3.3 Ubiksync state set master()

Der UBIK-Teil von ubiksync stellt unter anderem die Funktion ubiksync state set master()zur Verfugung, die fur den Ubergang in den MASTER- oder SLAVE-Zustand sorgt. Ausser derWertebelegung besteht keine Unterschied zu den Funktionen ubiksync state set votig() undubiksync state set nullquorum(), weswegen hier nur erstere vorgestellt wird.

91

int ubiksync_state_set_master(char *_master_uri){

Die Argumente der Funktion werden zuerst in der lokalen Reprasentation des ubiksync-Zustandszuwischengespeichert.

int port = ubik_get_ubiksync_port();state->master_uri=strdup(_master_uri);state->master=UBIKSYNC_MASTERIS;state->state=UBIKSYNC_WRITEQUORUM;

Im folgenden ist zu sehen, dass nur nur bei einem Wechsel des ubiksync-Zustandes weitereAktionen durchgefuhrt werden, was auch fur die beiden anderen Funktionen gilt. Diese Aktionenbestehen im Eroffnen eines Sockets, dem Verbinden mit dem lokalen slapd, der auf demubiksync-Port auf Nachrichten von ubiksync wartet, und dem Belegen des ubiksync requests mitentsprechenden Werten.

if (actualstate!=UBIKSYNC_WRITEQUORUM){actualstate=UBIKSYNC_WRITEQUORUM;rq = (ubiksync_request *) malloc (sizeof(ubiksync_request));if (rq == NULL) perror ("malloc");bzero (&sa,sizeof(sa));sa.sin_family = AF_INET;hp=gethostbyname("localhost");if (hp == NULL) perror ("gethostbyname");bcopy(hp->h_addr,&sa.sin_addr,hp->h_length);sa.sin_port = htons(port);sock = socket(AF_INET,SOCK_STREAM,0);if (sock == -1) perror ("ubiksync_state_set_master : socket");if (connect(sock,(struct sockaddr*)&sa,sizeof(sa)) < 0)

perror ("ubiksync_state_set_master : connect");rq->request_id = UBIKSYNC_RQ_CHANGE_SYNCSTATE;

Anhand des Parameters master uri wird entschieden, ob die Master- oder die Slaverolle einge-nommen werden soll. Ist der Struct mit allen relevanten Daten belegt, wird dieser an den slapdgesendet, der in diesem Fall die bereits betrachtete Funktion ubiksync change sync state()mit gleichen Parametern aufruft.

if (strcmp(_master_uri,"ME")==0){rq->newstate = UBIKSYNC_STATE_MASTER;bzero(rq->newmaster,50);}

else {rq->newstate = UBIKSYNC_STATE_SLAVE;bcopy(_master_uri,rq->newmaster,50);}

write (sock,rq,sizeof(ubiksync_request));close(sock);

}

92

8 Installation, Konfiguration und Test

In diesem Abschnitt wird erklart, welche Schritte notig sind, um die im Rahmen dieser Arbeitentandene Software zu installieren und lauffahig zu machen.

8.1 Installation der Quellpakete

Da die sync-Erweiterung von OpenLDAP die Nutzung der Version 3 des LDAP-Protokolls voraus-setzt, wurde die zum Zeitpunkt der Erstellung neueste Version von openLDAP (2.2.17) verwendet.Wie bereits erwahnt, sind fur die Eignung als Master nur die Backends BerkeleyDB oder ldbmgeeignet. Da jeder Server potentiell Master werden sollte, ist die Nutzung eines dieser beidenBackends notig. Wird back-bdb gewahlt, ist zu beachten, dass auch hier eine aktuelle Versionbenotigt wird (BerkeleyDB 4.2). Letztlich ist fur die aktuelle openLDAP-Version noch das PaketSASL in der Version 2 notwendig, wobei hier das Paket cyrus-sasl-2.1.19 verwendet wurde.

8.1.1 BerkeleyDB 4

Beispielhaft wird hier die Installation des Pakets db-4.3.27.tar.gz vorgenommen. Nach demEntpacken sind unter Linux folgende Aktionen auszufuhren:

#> cd db-4.3.27/build_unix#> ../dist/configure [Optionen]

Ohne die Angabe von entsprechenden Optionen wird das Paket spater unter/usr/local/BerkeleyDB.4.3/ installiert. Sollte hier ein anderes Zielverzeichnis angegebenwerden, sind bei den weiteren Paketen die entsprechenden Optionen zu andern. Anschliessendsind die ublichen Schritte durchzufuhren.

#> make#> make install

Da bei der Konfiguration des Pakets openLDAP keine Angabe des BerkeleyDB-Verzeichnissesangegeben werden kann, mussen sowohl fur die Headerfiles als auch fur die Bibliothekenentsprechende symbolische Links erstellt werden.

#> ln -s /usr/local/BerkeleyDB.4.3/include/db.h /usr/inlude/db.h#> ln -s /usr/local/BerkeleyDB.4.3/include/db_cxx.h /usr/inlude/db_cxx.h

#> ln -s /usr/local/BerkeleyDB.4.3/lib/libdb.a /usr/lib/libdb-4.a#> ln -s /usr/local/BerkeleyDB.4.3/lib/libdb.a /usr/lib/libdb-4-3.a#> ln -s /usr/local/BerkeleyDB.4.3/lib/libdb.a /usr/lib/libdb-4.3.a#> ln -s /usr/local/BerkeleyDB.4.3/lib/libdb.so /usr/lib/libdb-4.so#> ln -s /usr/local/BerkeleyDB.4.3/lib/libdb.so /usr/lib/libdb-4-3.so#> ln -s /usr/local/BerkeleyDB.4.3/lib/libdb.so /usr/lib/libdb-4.3.so

93

8.1.2 SASL 2

Die Installation dieses Pakets gestaltet sich relativ simpel.

#> ./configure --with-bdb-libdir=/usr/local/BerkeleyDB.4.3/lib \\--with-bdb-incdir=/usr/local/BerkeleyDB.4.3/include

#> make#> make install

Aber auch hier mussen noch entsprechende Links gesetzt werden, damit OpenLDAP deientsprechenden Bibliotheken findet.

#> ln -s /usr/local/lib/sasl2 /usr/lib/sasl2#> ln -s /usr/local/lib/libsasl2.so.2.0.19 /usr/lib/libsasl2.so.2#> ln -s /usr/local/lib/libsasl2.so.2.0.19 /usr/lib/libsasl2.so

8.1.3 OpenLDAP mit ubiksync

Da der ubiksync-Zusatz direkt in das openLDAP-Paket einkompiliert wird, ist nur die Installa-tion dieses Pakets notig. Dazu sind wieder nur die Standartschritte auszufuhren

#> ./configure#> make depend#> make#> make install

Nun sollte eine lauffahige Version des ubiksync-fahigen slapd auf dem System vorhanden sein,die ohne weitere Angaben unter /usr/local/libexec installiert wurde.

8.2 Konfiguration

8.2.1 Voraussetzung fur den Betrieb von ubiksync

Zu erst ist zu beachten, dass alle teilnehmenden Hosts einander kennen, genauer gesagt, denHostnamen aller anderen Hosts auflosen konnen. Ist dies nicht der Fall, kommt es DNS-bedingtzu grossen Verzogerungen beim Start.Die zweite Bedingung ist die zeitliche Synchronisation aller teilnehmenden Hosts. Eine Moglich-keit hierzu ist der Einsatz des Network Time Protocol (NTP). Der mikrosekunden-genaue Ab-gleich ist nicht notig; die Systemzeiten sollten sich aber nicht mehr als eine Sekunde voneinanderunterscheiden.

8.2.2 Konfiguration des slapd

In dieser Sektion wird auf die Belegung der beiden Konfigurationsdateien ubik.conf undslapd.conf eingegangen, die zum Betrieb notig ist.Zuerst ein Auszug aus slapd.conf, das sich bei der Standartkonfiguration unter/usr/local/etc/openldap/ befindet. Die ersten Zeilen zeigen dem slapd, wo die Schemadefi-nitionen und die Unicode Zeichentabellen zu finden sind.

94

ucdata-path /usr/local/share/openldap/ucdatainclude /usr/local/etc/openldap/schema/core.schemainclude /usr/local/etc/openldap/schema/cosine.schemainclude /usr/local/etc/openldap/schema/inetorgperson.schemainclude /usr/local/etc/openldap/schema/openldap.schemainclude /usr/local/etc/openldap/schema/nis.schemapidfile slapd.1.pidargsfile slapd.1.args

Der folgende Ausschnitt definiert backendabhangige Einstellungen, also das zu nutzende Backend,den Suffix, den dieses Backend bedienen soll, das Verzeichnis, in dem die Datenbank abzulegenist, und den DN des sogenannten Rootusers, der alle Berechtigungen zur Initialisierung desVerzeichnisses hati, inklusive Passwort. Dieser DN wird beim Starten des Servers automatischerstellt, sodass der LDAP-Administrator unter Angabe dieser Zugangsdaten die volle Kontrolleerlangt.Wie bereits erwahnt, ist diese Version von ubiksync darauf ausgelegt, dass nur ein Server (miteinem Backend) pro Host laufen darf.Die letzte Zeile im folgenden Ausschnitt sollte unbedingt verandert werden, um unerlaubteSchreibvorgange zu verhindern. Eine genaue Anleitung dazu findet sich auf der Manpageslapd.access(5).

######################################################################## consumer database definitions#######################################################################

database bdbsuffix "o=University of Michigan,c=US"directory db.1.arootdn "cn=Manager,o=University of Michigan,c=US"rootpw secretaccess to * by * write

Die Grosse des bereits erwahnten Threadpool kann mit folgendem Schlusselwort eingestelltwerden. Zu beachten ist, dass jeder Server, der sich als Slave im RefreshAndPersist-Modus mitdiesem Server synchronisiert, einen Platz in diesem Pool dauerhaft belegt und bei vollstandigerBelegung der Threads aus bereits beschriebenen Grunden keine Updates mehr moglich sind.

threads 32

Der letzte Abschnitt in slapd.conf behandelt die Konfiguration der sync-Replikation. Wiebereits erwahnt, muss jeder teilnehmende Server eine eindeutige <rid> besitzen, die in derersten Zeile anzugeben ist, und als Slave gestartet werden.Letzteres geschieht durch das Schlusselwort syncrepl, durch das beim Start des Servers allenotigen Vorkehrungen fur die Replikation getroffen werden. Da aber nach dem Start noch keinServer zum Master gewahlt wurde, muss als provider ein Server angegeben werden, den esnicht gibt, da sich der slapd ohne diese Angabe mit einer Fehlermeldung wieder beendet. Umlange Wartezeiten durch DNS-Suchen zu verhindern, ist die sinnvollste Einstellung hier dereigene Hostname in Verbindung mit einem ungenutzten Port. In durchgefuhrten Tests wurdefestgestellt, das die Angabe eines nicht laufenden Servers zum Beenden des slapd fuhren kann,was wie folgt zu begrunden ist:

95

Ist der Master nicht erreichbar, wird durch die gleich betrachtete retry-Direktive festge-legt, wie oft und in welchen Abstanden ein erneuter Versuch zur Verbindungsaufnahmeunternommen werden soll. Dazu wird jedes Mal die syncrepl-Taskliste unter der Annahme,dass immer noch ein Task vorhanden ist, von neu zeitlich eingeordnet (rescheduled). Wurdewahrend dessen mit die Einnahme des Voting-States durch ubiksync diese Liste geleert, beendetsich der slapd aufgrund dieses unerwarteten Zustands beim Versuch, die Liste neu zu reschedulen.

syncrepl rid=2provider=ldap://staude.rootpool.de:12345

Folgende Zeile geben den DN des Users an, der dazu berechtigt sein soll, die vom Master emp-fangenen Updates in die Datenbank einzutragen, sowie dessen Authentifizierungs-Credentials.Dieser User sollte nicht der Rootuser sein.

updatedn="cn=Replica,o=University of Michigan,c=US"binddn="cn=Manager,o=University of Michigan,c=US"bindmethod=simplecredentials=secret

Die Einstellungen, die angeben, WAS zu replizieren ist, werden in den nachsten 5 Zeilen angege-ben. Zu beachten ist, dass die searchbase dem oben genannten suffix entspricht, um diesenServer als Master zulassen zu konnen. Desweiteren sind dazu unbedingt auch die Belegung deranderen Attribute zu ubernehmen, da sonst als Slave keine vollstandige Replikation stattfindetund sich dieser Server somit nicht als Master eignet.

searchbase="o=University of Michigan,c=US"filter="(objectClass=*)"attrs="*"schemachecking=offscope=sub

Letztlich wird noch der Replikationstyp angegeben, wobei die gezeigte Einstellung vorzuziehenist, und die Anzahl der Wiederholungsversuche zur Kontaktausnahme mit dem Master einge-stellt. Die Angabe des Intervalls ist nur im RefreshOnly-Modus notig und gibt den zeitlichenAbstand zwischen 2 Requests an (hier 5s). Dieser Wert sollte aus Konsistenzgrunden relativniedrig gehalten werden. Die letzte Zeile taucht in keiner Manpage auf und triggert den Gebrauchvon ubiksync.

type=refreshAndPersistretry=10,20interval 00:00:00:05ubiksync=on

8.2.3 Konfiguration von UBIK

Das Konfigurationsfile ubik.conf sollte in dem Verzeichnis untergebracht sein, von dem aus derslapd gestartet wird.Das Wert des peers-Attributs gibt die Liste aller teilnehmenden Hosts an. Diese Zeile muss beiallen Hosts gleich sein, sollte also am besten kopiert werden. Der Wert des whoami-Schlusselworts

96

ist der eigene Hostname und muss in der peers-Liste vorkommen. Der Eindeutigkeit halbersollten in beiden Zeilen nur vollstandige Hostnamen inklusive Domainnamen verwendet werden.

peers: ast.rootpool.de,rebe.rootpool.de,staude.rootpool.de,baum.rootpool.dewhoami: staude.rootpool.de

Die folgende Zeile gibt den Common Suffix an, der sowohl mit dem suffix als auch mit dersearchbase aus slapd.conf ubereinstimmen muss, um diesen Host als Master zulassen zu konnen.Weiterhin solte zu diesem Zweck der scope mit sub und der filter mit (objectClass=*)belegt sein, um die Replikation des gesamten Teilbaums zu garantieren.

csuffix: o=university of michigan,c=us

Dieses Flag dient als Schalter fur die Erlaubnis, dass auch Server, die sich in keinem Write-Quorum befinden, Daten liefern durfen. Der originale UBIK-Algorithmus verhindert dies, dadurch einen Netzfehler getrennte Hosts ein eventuell existierendes WriteQuorum nicht sehenwurden und gegebenenfalls falsche Daten ausliefern wurden. Um die Leseverfugbarkeit abernicht unnotig zu verringern, kann das Verbot mit Hilfe dieses Flags aufgehoben werden. Solltekein Netzproblem vorliegen, kann das Lesen ohne Bedenken erlaubt werden, da keine aktuellereDatenbankversion existieren kann.

alwaysallowreads: yes

Schliesslich konnen an dieser Stelle noch die beiden zu nutzenden Ports festgelegt werden, dieohne Angabe die Standartwerte 3000 und 3001 haben.

ubiksync_port: 12345ubik_port: 12346

Anschliessend sollte der Start des ubiksync-slapd ’s durch folgendes Kommando moglich sein:

#>/usr/local/libexec/slapd -d4 -h <eigene URL> -f ./slapd.conf

8.2.4 Initialisierung

Nun ergibt sich folgendes Problem: Da Server als Slave gestartet wird, nimmt er keine Eintragean, auch wenn sie vom Rootuser veranlasst werden. Um zumindest die Grundkonfigurationeintragen zu konnen, muss der Server ohne syncrepl-Direktive im Configfile gestartet werden,die dazu einfach auszuklammern ist :

97

# syncrepl rid=2# provider=ldap://dummy_server:12345# updatedn="cn=Replica,o=University of Michigan,c=US"# binddn="cn=Manager,o=University of Michigan,c=US"# bindmethod=simple# credentials=secret# searchbase="o=University of Michigan,c=US"# filter="(objectClass=*)"# attrs="*"# schemachecking=off# scope=sub# type=refreshAndPersist# retry=10,20# interval 00:00:00:05# ubiksync=on

Nachdem der Server anschliessend (als Master) gestartet wurde, sollte das Verzeichnis zuerst mitden notwendigsten Eintragen gefullt werden. Dazu zahlen der suffix, der updatedn sowie imFalle der simple authentication ein binddn. Nun sollte der Server fur den Einsatz mit ubiksyncgewappnet sein, sodass nach Beenden des slapd obige Konfigurationszeilen wieder aktiviertwerden konnen.

8.3 Test

In diesem Abschnitt wird bei unterschiedlichen Konstallationen gepruft, ob das Ergebnis denErwartungen entspricht. Zu diesem Zweck wurde ldapsync auf 5 Servern installiert, konfiguriertund initialisiert, sodass im Ausgangszustand alle Datenbanken die selbe Version haben. Es wirdder RefreshAndPersist-Modus verwendet. Die Hostliste in ubik.conf sieht folgendermassen aus:

peers: ast.rootpool.de,rebe.rootpool.deast-rot.rootpool.de,rebe-rot.rootpool.de,staude-rot.rootpool.de

8.3.1 Die Wahl

Nach dem Start der ersten beiden Server dieser Liste votet rebe fur ast. Dieser kann jedochkein WriteQuorum eroffnen, da die Stimmen von mindestens 3 Servern benotigt werden. Startetals dritter Server staude-rot, deklariert sich ast nach dem Versionsaustausch zum Master underoffnet das WriteQuorum.Der LDAP-Klient ldapbrowser verbindet sich nun mit staude-rot und nimmt einen Neueintragvor. Wie erwartet bekommt er ein Referral zuruck und sendet den Request anschliessend an denMaster ast. Dieser nimmt den Eintrag vor und sendet Updates an staude-rot und rebe. EineSuchanfrage an rebe zeigt die erwartete Ubernahme der Anderung.

8.3.2 Eintritt eines nicht-aktuellen Servers

Als vierter Server startet ast-rot. Der erkennt nach dem Austausch der Versionen, dass er fur aststimmen muss, da dieser unter allen Servern mit der hochsten Version die niedrigste Hostlistenpo-sition hat. Nach einer Weile stimmt ast-rot auf ast’s VOTEFORME-Anfragen mit VOTE YES

98

und wird daraufhin in das WriteQuorum aufgenommen. Nachdem die Konfiguration der Slaverol-le abgeschlossen ist und die Synchronisation gestartet wurde, empfangt ast-rot wie erwartet dasUpdate, welches im letzten Abschnitt vorgenommen wurde. Auch hier bestatigt eine Suchanfragean ast-rot mittels ldapbrowser die erwartete Anderungsubernahme.

8.3.3 Ausfall des Masters

Nun soll der sogenannte worst case in einer normalen Replikationsumgebung eintreten, und zwarder Ausfall des Masters ast. Um einen wirklichen Absturz zu simulieren, wurde dieser Servernicht einfach beendet, sondern mittels killall -9 slapd sofort gekillt.Wie zu vermuten war, bemerken die Slaves rebe, staude-rot und ast-rot diesen Ausfall durchden fehlenden Verbindungsendpunkt am sync-Socket zum Master. Nach einer Weile gelangen siealle durch den Timeout des Quorum zuruck in den VOTING-Zustand. Den Erwartungen entspre-chend findet ein kompletter Versionsaustausch zwischen allen 3 Servern statt. Durch das Loggingist zu erkennen, dass erstens jeder der 3 Server die selbe Version hat, und zweitens, dass diese 3Versionen auf allen 3 Servern korrekt angezeigt werden, also in jeder der 3 Hostlisten identischsind. Aufgrund dessen wird nun rebe eindeutig zum Master gewahlt.Um die Neuinitialisierung der Update-Weiterleitung zu testen, wurde mit Hilfe des LDAP-Browsers ein Update an staude-rot vorgenommen. Auch hier entsprach das Ergebnis den Er-wartungen: Die Anderung wurde an rebe weitergeleitet, der seinerseits staude-rot und ast-rotaktiv uber die vorgenommenen Updates informierte. Ein Blick in alle 3 Verzeichnisse bestatigteden aktualisierten, identischen Datenbestand.In einem zweiten Test wurde versucht, kurz nach dem Ausfall ast’s (innerhalbSMALL SECONDS) an rebe ein Update vorzunehmen. Da dieser bis zum Timeout weiterhin alsSlave agiert, liefert er die URL von ast als Referral zuruck. Der LDAP-Browser versucht nun,seinen Anderungswunsch an ast zu senden, bemerkt aber, dass dieser nicht mehr lauft und be-endet den Versuch mit der Meldung server unreachable. Auch wenn dies nicht das optimalsteVerhalten ist, wird dadurch zumindest die Konsistenz zwischen allen Servern gewahrleistet.

8.3.4 Ausfall eines Slaves

In diesem Abschnitt wird untersucht, ob die durch einen Ausfall entstehende Server-Minderheit zueiner Auflosung des Quorums fuhrt. Zu diesem Zweck wird staude-rot ebenfalls gekillt. Nachdemrebe durch einen Quorum-Timeout den Ausfall bemerkt hat, versetzt er ast-rot durch das Ver-senden eines CMD QUORUM NULL in den ubiksync-VOTING-Zustand, der eine sofortige Been-digung der Synchronisation zur Folge hat. Ast-rot antwortet mit einem VOTE YES. Da nun abernicht mehr genugend Stimmen vorhanden sind, um das WriteQuorum weiter zu fuhren, nimmtnun auch rebe den VOTING-Zustand ein und versendet weiterhin VOTEFORME-Nachrichtenan ast-rot. Dieser Teil der Vermutung ist also eingetreten.Nun sollte auch keinem Updatewunsch, weder an rebe noch an ast-rot, mehr Folge geleistetwerden. Um dies zu testen, wurde an beiden Servern versucht, ein Update vorzunehmen, was vonBeiden mit einer operation restricted Fehlermeldung abgelehnt wurde. Diese Anforderung istalso auch erfullt.

8.3.5 Teilbaumreplikation

Im folgenden wurde rebe-rot so konfiguriert, dass er als Slave nur den Teilbaum

searchbase="ou=people,o=University of Michigan,c=US"

99

replizieren soll, wodurch er nicht als Masterkandidat in Frage kommen sollte und auch seineStimme nicht fur die Wahl gezahlt werden darf. Wahrend des Versionsaustausches wird durchdas Logging an allen 3 laufenden Servern angezeigt, dass sich rebe-rot im Slave only-Modusbefindet, also nicht zur Wahl steht. Trotz der Stimme von rebe-rot eroffnet rebe wie erwartetkein WriteQuorum, da laut Spezifikation nur Stimmen von potentiellen Mastern gezahlt werdendurfen.Um wieder ein WriteQuorum bilden zu konnen, wird ast erneut gestartet, der ebenfalls rebe-rotals Slave only erkennt. Durch das verpasste Update hat ast eine altere Version und mussdadurch rebe als Master akzeptieren. Auch hier kommt den Anforderungen entsprechend einneues WriteQuorum mit dem Master rebe zustande.Anderungen im o.g. Teilbaum werden nun an alle Server verteilt, wahrend andere Teile des DITwie gewunscht nicht von rebe-rot repliziert werden.

8.3.6 Performance

Die Performance im Sinne der Verteilung der Updates ist durch den Einsatz desRefreshAndPersist-Modus sehr gut, da jede Anderung sofort an die Slaves verteilt wird. Auf-grund des Fehlens eines Kommandozeilentools zur Manipulation des lokalen LDAP-Servers, dasdie Verarbeitung von Referrals implementiert, konnte kein Update-Performancetest durchgefuhtwerden. Da der Master in einem solchen Fall vom Klienten durch regulare LDAP-Requests kontak-tiert wird, ist sein Verhalten nicht von einer LDAP-Umgebung ohne Replikationsmechanismus zuunterscheiden. Die Zeit des Masterwechsels kann durch die Manipulation von SMALL SECONSund BIG SECCONDS (zur Zeit nur im Quelltext) beeinflusste werden, sodass eine Anpassungan LAN- oder WAN-Umgebungen durchgefuhrt werden kann.

9 Fazit

9.1 Anforderungskonformitat

In diesem Abschnitt wird noch einmal zusammenfassend uberpruft, inwieweit die entstandeneErweiterung den gewunschten Anforderungen entspricht.

• Die Synchronisation zwischen allen Servern, genauer gesagt zwischen dem Master undseinen Slaves, wird durch den Einsatz des LDAP-sync Mechanismus’ gewahrleistet.

• Das Hauptziel dieser Arbeit, die automatische Strukturanpassung bei Ausfallen, wirddurch den Einsatz des fur diese Aufgabe optimierten UBIK-Algorithmus’ in Verbindung mitder lokalen Kommunikation zwischen UBIK und dem slapd und den damit verbundenenRollenwechseln realisiert.

• Ein Teil der automatischen Datenverteilung, der Abgleich aller Slaves mit dem Master,wird durch LDAP-Sync selbst vorgenommen. Der zweite Teil hingegen, das Verarbeiten vonReferrals und die Kontaktaufnahme mit dem Master, liegt in den Handen des Klienten.Versteht man unter Automatismus die Transparenz fur den Endnutzer, ist auch der zweiteTeil erfullt.

• Bei entsprechender Konfiguration (alwaysallowreads) sind Lesezugriffe uberall er-laubt, vorausgesetzt naturlich, der kontaktierte Server ist in Betrieb. Ist der lokale Server ineinem WriteQuorum, sind sowohl Lese- als auch Schreiboperationen gestattet, unabhangigvon seiner aktuellen Rolle.

• Da mehr als die Halfte der registrierten Server laufen mussen, um Schreiboperationen zuerlauben, ist das Ziel, auch nach Ausfallen beliebiger Server Updates verarbeiten

100

zu konnen, nur bedingt erfullt. Jedoch ist diese Anforderung eine deutliche Verbesserunggegenuber der reinen Single-Master-Konstellation, bei der ein Ausfall des Masters zur ge-nerellen Ablehnung von Updates fuhrt.

• Die Tranzparenz fur den Endnutzer wird durch die erwahnte automatische Verteilungder Daten gewahrleistet. Somit kann ein User nur feststellen, ob ein WriteQuorum existiertoder nicht, da nur im ersten Fall Schreiboperationen erlaubt sind. Der Nutzer weiss jedochnicht, ob sein lokaler Server gerade Master oder Slave ist.

• Die einzigen szenarioabhangigen Konfigurationen sind auf UBIK-Seite die Belegung derHostliste, und die Festlegung eines Common Suffixes. Die Konfiguration des slapd muss umeine syncrepl-Direktive in Verbindung mit der eindeutige Zuteilung von rid’s zwischen al-len teilnehmenden Servern erweitert werden, um den Einsatz von ubiksync zu ermoglichen.Damit fallt der Admiinisatrationsaufwand sehr gering aus und ist ohne Spezialwis-sen moglich. Mit der Wahl des gewunschten Modus und die Einstellung der Intervallzeitenim RefreshOnly-Modus sind ausserdem die wichtigsten Updatepolicies konfigurierbar.

• Die Unterstutzung der Replikation von Teilbaumen wird durch LDAPsync gesichert,fuhrt aber durch den Einsatz von UBIK zu einigen Einschrankungen hinsichtlich der Ma-stertauglichkeit solcher Server.

• Die Unterscheidung zwischen dem initial content load (vollstandige Datenubertragung)und incremental updates (Ubertragung von veranderten Daten) wird durch das Vor-handensein von SyncConsumerSubentry und SyncProviderSubentry sowie durch die Op-timierungen von LDAP-sync (refreshRequired) vorgenommen, sodass der unnotige Ver-brauch von Bandbreite praktisch ausgeschlossen ist.

• Der Automatische Abgleich beim Start eines Servers wird durch den Versionsaustauschgewahrleistet. Hat der neue Server eine niedrigere Versionsnummer, nimmt er im Falleeines entstehenden / bestehenden Writequorums die Slaverolle ein und gleicht sich mit demMaster ab.

• Die Unterstutzung aller gangigen LDAP-Schemata ist die Aufgabe von LDAP-sync.

• Durch den Einsatz dieses speziellen Single-Master-Prinzips sind dauerhafte Inkonsisten-zen zwischen den Replikaservern aufgrund der seriellen Verarbeitung praktisch ausge-schlossen. In einigen Sonderfallen, beispielsweise dem Absturz des Masters vor dem Verteilender Updates, konnen die vorgenommenen Anderungen verloren gehen, was sich allerdingsnicht negativ auf die Konsistenz auswirkti.

Auch die allgemeinen softwaretechnischen Anforderungen sollten nicht ausser Acht gelassen wer-den

• Mit entsprechenden Tests wurde die Zuverlassigkeit des Wahl- und Replikationsprozes-ses uberpruft. Das Ergebnis war die Einhaltung aller geforderten Bedingungen, selbst inGrenzfallen. Jedoch sollte nicht ausser Acht gelassen werden, dass es sich bei der entstan-denen Erweiterung um einen Prototyp handelt.

• Verfugbarkeit kann in diesem Umfeld verschiedene Bedeutungen haben. Einerseits hatubiksync keinen Einfluss darauf, ob ein einzelner Server lauft und damit Klienten in seinemUmfeld bedienen kann. Andererseits wird durch die Toleranz gegenuber Ausfallen versucht,sowohl Lese- als auch Schreiboperationen so lange wie moglich zumindest den Klienten zuerlauben, deren lokale Server sich in einem WriteQuorum befinden. Ist ein Server in keinemWriteQuorum, sind Updates nicht erlaubt, wahrend die Ausfuhrung von Leseoperationenmit entsprechender Einstellung jederzeit verfugbar sein kann.

101

• Durch das Ausschalten uberflussiger Rollenwechsel innerhalb des UBIK-Algorithmus’,den geringe Rechenaufwand wahrend eines solchen Statuswechels und die Optimierungenwahrend der Updateubertragung seitens LDAPsync ist der Umgang mit Bandbreite undRechenleistung sehr effizient.

• Die Skalierung der entstandenen Software im WAN-Umfeld konnte nur ansatzweise mitHilfe einer Modemanbindung getestet werden. Da sich die zu ubertragenden Datenmengendes UBIK-Protokolls relativ unabhangig von der Anzahl der Server im unteren Bereich be-wegt, kann davon ausgegangen werden, dass auch der Einsatz im grosseren Umfang ausrei-chend performant ist. Die Performance der Synchronisation selbst ist durch die erwahntenOptimierungen seitens LDAPsync optimal.

• Durch das Logging der gerade durchgefuhrten Aktionen und des aktuellen Zustands jedesServers kann der Administrator jederzeit prufen, wie der Zustand des Gesamtsystems ist.

• Die Erweiterbarkeit des UBIK-Protokolls ist durch die Trennung von Datenaustausch, Infor-mationsverarbeitung und Wahlvorgang mit relativ wenig Aufwand verbunden. Auch wurdeversucht, die Aufgabengebiete im Quelltext klar zu trennen, was die Wartbarkeit positivbeeinflusst.

• Die Anforderungen an Portierbarkeit und Interoperabilitat sind durch die innere Struk-tur des openLDAP-slapd kaum erfullbar, da sehr direkt auf seine internen Daten zugegriffenwerden muss.

9.2 Verbesserungs- / Optimierungsmoglichkeiten

Das entstandene Softwarepaket erullt, wie im letzten Abschnitt zu sehen war, einen Grossteil derAnforderungen. Einige Details konnten aus Zeitgrunden leider nicht optimal gelost werden. Durchdie Erweiterbarkeit ist jedoch die Moglichkeit der Weiterentwicklung dieses Projekts gegeben.Da es sich bei LDAPsync um ein relativ junges Projekt handelt, das hohe Anforderungen an dieAktualitat der verwendeten Softwarebibliotheken stellt, konnten einige der folgenden Problemein Zukunft der Vergangenheit angehoren. Dazu zahlt unter anderem, dass bisher nur wenige Kli-enten mit Update-Referrals umgehen konnen. Man sollte annehmen, das durch den vermehrtenEinsatz der sync-Replikation zukunftig auch die mitgelieferten openLDAP-Kliententools referral-tauglich werden,Am ubiksync-Projekt sind ebenfalls einige Verbesserungen vorstellbar:Die Moglichkeit, mehrere LDAP-Server pro Rechner laufen zu lassen, wurde in dieser Implemen-tierung nicht beachtet, da UBIK ausschliesslich auf die Kommunikation zwischen verschiedenenHosts ausgelegt war und somit nicht zwischen mehreren Instanzen pro Host uneterscheiden konn-te. Sollte unter n slapd ’s auf einem Rechner allerdings nur ein Server mit ubiksync arbeiten, ist dieAdressierung dieses Servers durch die Angabe der URL bei der Deklaration des WriteQuorumseindeutig, sodass an ihn gerichtete UBIK-Kommandos am richtigen Server ankommen wurden.Durch eine kleine Anderung im Quelltext ist diese Moglichkeit also auch anwendbar. Eine weitereMoglichkeit ist die Erweiterung des UBIK-Protokolls um eine konfigurierbare UBIK-Portnummer,wodurch mehrere ubiksync-Instanzen pro Rechner unabhangig voneinander arbeiten konnten.Ein weiteres Problem kann vorwiegend im RefreshOnly auftreten, wenn der Master ein Updateentgegengenommen hat und seinen Dienst quittiert, bevor er die Anderungen an die Slaves wei-tergeleitet hat. Bilden die Slaves nach einem Timeout ein neues WriteQuorum und verarbeitenweitere Updates, bevor der ehemalige Master wieder eintritt, geht die erste Anderung zwangs-weise verloren, obwohl dem Klienten ein erfolgreicher Eintrag gemeldet wurde. Dieses Problemlasst sich nur durch die Anwendung eines 2-Phase-Commit Protokolls losen: Der Master darf ersteine Erfolgsmeldung an den Klienten liefern, wenn sichergestellt ist, dass alle Slaves, oder bessergesagt, mehr als die Halfte aller Hosts, den Empfang des Updates bestatigt und es ausgefuhrt

102

haben. Erst dann sollte auch er das Updates lokal vornehmen.Wenn in diesem Fall weniger als n/2 Slaves antworten, ist die Transaktion abzubrechen, und eineFehlermeldung an den Klienten zu senden. Um diese Updates dennoch nicht ablehnen zu mussen,konnte der Master das Update lokal in einer todo-Liste speichern, wo es erst nach erfolgreicherVerbreitung wieder entfernt wird. Sollte er vor der Verbreitung absturzen oder nicht genugendKlienten den Empfang bestatigen, musste eine Moglichkeit gegeben sein, dieses Update zu einemspateren Zeitpunkt erneut zu verbreiten. Aufgrund der dadurch potentiell auftretenden Konflik-te (der veranderte Eintrag wurde in der Zwischenzeit erneut geupdatet) ist hier kein einfacherLosungsweg zu erwarten.Ein problematisches Szenario, das sowohl im RefreshOnly- als auch im RefreshAndPersist-Modusauftauchen kann, ist der Ausfall eines oder mehrerer Slaves, wobei anschliessend weniger als n/2Server im Quorum sind. Wird in der Zeit bis zum Timeout des Quorums ein Update vorgenom-men, wird es an eine Minderheit verbreitet. Sollten die restlichen Server durch die Trennung einesNetzwerksegments ein eigenes Quorum mit mehr als n/2 Servern bilden und Updates ausfuhren,wurden die zuerst ausgefuhrten Andeungen ebenfalls verloren gehen, da der Zeitstempel derspateren Updates neuer ist. Auch hier fuhrt der Einsatz des gerade erklarten 2-Phase-Commit-Protokolls zur Losung des Problems, da Updates nicht an eine Serverminderheit verbreitet werdenkonnen.Einem Teilbaum A - replizierenden Slave sollte die Entgegennahme von Updates verboten wer-den, die einen anderen Teilbaum B betreffen. Der Grund hierfur liegt darin, dass der mit demSlave kommunizierende Klient nicht wissen kann, wie der aktuelle Teilbaum B belegt ist, da ermit einer Suchanfrage nur diese veraltete Version zu Gesicht bekommt, die nicht mit Updatesversorgt wird. Fur diesen Teilbaum sollten sowohl Lese- als auch Schreiboperationen an eine au-thoritative Quelle weitergeleitet werden.Um die Bandbreitenanforderungen des UBIK-Protokolls nochmals zu verringern, konnte zum Bei-spiel die wiederholte Ubertragung der Master-URL verhindert werden, indem sie auf Slave-Seitebis zur Auflosung des WriteQuorums zwischengespeichert wird. Ebenso kann der Versionsaus-tausch einen betrachtlichen Umfang einnehmen, wenn auch die ubertragenen Datenmengen sehrgering sind. Hier kann unter Beachtung von Timeoutzeiten und der Dauer der Wahl eine Opti-mierung vorgenommen werden.In abschliessenden Tests wurde beobachtet, dass bei einer Replikation des gesamten NamingContextes von LDAPsync auch die SyncConsumerSubentries der verschiedenen Server repliziertwurden, was zu unerwarteten ContextCSN-Differenzen fuhrte. Daher wird die Unterbringung derzu replizierenden Daten in einem Teilbaum, beispielsweise ”cn=data, o= University Of Michigan,c=us“, empfohlen, um diesen unerwunschten Datenaustausch zu verhindern.

9.3 Abschliessende Worte / Ausblick

Zweck dieser Arbeit war der Nachweis uber die Machbarkeit der gewunschten Anforderungen aneinen LDAP-Replikationsmechanismus, der tolerant gegenuber Serverausfallen ist und trotzdemkonsistente Datenbestande garantiert. Die entstandene Software erfullt einen Grossteil der An-forderungen, sollte jedoch aufgrund des Prototypen-Status’ noch nicht in kritischen Umgebungeningesetzt werden. Wunschenswert fur die Zukunft dieses Projekts ware eine grossere Auswahl vonreferral-tauglichen Kliententools, ohne die der Einsatz nur bedingt moglich ist.Sollte sich die Konzeption dieser P2P-ahnlichen Single-Master-Umgebung bewahren, ware aucheine Aufnahme in das openLDAP-Projekt vorstellbar.

103

A Quellen

Literatur

[IPROT] Dave Roberts – Internet Protocols Handbook – Coriolis Group Books

[IMPLDAP] Mark Wilcox – Implementing LDAP – wrox-programmer to programmer

[BINLDAP] OpenLdap 2.0.12-Release – http://www.openldap.org

[RFC2251] RFC 2251 Lightweight Directory Access Protocol (v3) –http://www.ietf.org/rfc/rfc2251.txt

[MMREPROP] Proposals for Multi-Master Replication between LDAP Directories (1998) –http://www.stanford.edu/hodges/LDUP/ProposalPresentations-1-May-1998/telstra multi master/sld001.htm

[LDAPMMRP] LDAP Multi-Master Replication Protocol (1997) draft-ietf-asid-ldap-mult-mast-rep-02.txt

[LDAPREPREQ] draft-ietf-asid-replica-req-01.txt

[ST1SCRIPT] Softwaretechnologie 1 – Kroha P. - March 2001Vorlesungsskript der TU-Chemnitz

[SLAPDADMIN] The SLAPD and SLURPD Administrators GuideUniversity of Michigan –http://www.umich.edu/ dirsvcs/ldap/doc/guides/slapd/toc.html

[BAYOU] Designing and Implementing AsynchronousCollaborative Applications with Bayou http://www2.parc.com/csl/projects/bayou/pubs/uist-97/Bayou.pdf

[XEROXBAYOU] http://www2.parc.com/csl/projects/bayou/

[UBIKAFS] http://www.mirrors.wiretapped.net/security/cryptography/filesystems/arla/prog-afs/shadow/doc/ubik.mss

[REPTEC] Preplication Techniques in Distributed Systems–Helal, Heddaya, Bhargava–Kluwer Academic Publishers 1996

[LDAPBROWSER] LDAP Browser / EditorVersion 2.8.1http://www.iit.edu/ gawojar/ldap

[OLDAPORG] www.openldap.org

[IXSYNC] www.init.de

[ORACLEREP] Oracle Replication Solutionswww.dbasupport.com/oracle/ora9i/ors.shtm

104

B Abbildungen

Abbildungsverzeichnis

1 gleichzeitige Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 Single-Master-Replikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Failover-Prinzip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 slurpd-Prinzip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Grundmodell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 Zustande eines UBIK-Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 Zustandsmapping zwische n UBIK und slapd . . . . . . . . . . . . . . . . . . . . . 398 Teilbaumreplikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409 Klientenszenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4410 Die Hauptschleife des LDAP-Servers . . . . . . . . . . . . . . . . . . . . . . . . . . 4911 Kommunikation zwischen UBIK und slapd . . . . . . . . . . . . . . . . . . . . . . . 5012 Das Prozessmodell und InterProcessCommunication . . . . . . . . . . . . . . . . . 5313 Koordination beim Start eines Servers . . . . . . . . . . . . . . . . . . . . . . . . . 5514 Koordination bei der Masterwahl . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5715 Klienteninteraktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5816 Ein Out-Of-Date-Server tritt bei . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5917 Ein Up-To-Date-Server mit niedrigster Hostlistenposition tritt bei . . . . . . . . . 6018 Nach dem Ausfall eines Slaves sind noch mehr als n/2 Server aktiv . . . . . . . . . 6119 Nach dem Ausfall eines Slaves sind weniger als n/2 Server aktiv . . . . . . . . . . 6220 Ausfall des Masters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

105

C Selbststandigkeitserklarung

Erklarung

Hiermit versichere ich, dass ich die vorliegende Diplomarbeit selbststandig verfasst und keineanderen Quellen und Hilfsmittel als die angegebenen benutzt habe. Alle Stellen im Text, dieanderen Werken im Wortlaut oder sinngemass entnommen sind, wurden als Entlehnung kenntlichgemacht.Chemnitz, den 10.4.2005

Unterschrift

106