Einführung Client-Server Sollen verschiedene Prozesse untereinander eine Verbindung aufbauen, um Daten auszutauschen, gibt es dabei ein grundsätzliches Problem: Die Synchronisation. Woher soll der eine Prozess vom anderen Wissen, daß dieser bereit ist, die gewünschte Verbindung herzustellen? Um dieses Problem zu umgehen, werden Programme nach dem Client-Server-Prinzip entworfen. Ein Server ist dabei ein Prozess, der (meist in einer Endlosschleife) auf eine Verbindung wartet. Server-Programme werden auch als daemon bezeichnet. Oft erkennt man diese schon an dem Namen mit angehängtem „d“ z.B. ftpd, Nameserver named. Ein Programm, das eine Verbindung zu einem Server aufbaut, wird Client genannt. Der Client übernimmt den aktiven Teil des Verbindungsaufbaus und bestimmt dessen Zeitpunkt. Kurz angesprochen: TCP/IP Stack OSI Layer Stocket-Kommunikation Allgemeines an Client-Server Nebenläufe und Iterative Ein nebenlöufer erzeugt für jeden Server einen Kundprozess, um di eeingehenden Anfragen zu bearbeiten. Vorteil: mehrere Clients können zur gleichen Zeit die Dienste des Servers in Anspruch nehmen. Genutzt wird diese Art von Server vor allem bei Diensten die eine lange, oder unbestimmte bearbeitungszeit Zeit benötigen – z.B. HTTP Iterative Server --- VON DANIEL ÜBERTRAGEN – HIER FEHLT ETWAS --- Verfügbar- und Hochverfügbarkeitssysteme Das Ziel von HA besteht in einer Sicherstellung der Geschäftsabläufe durch ein weitgehend reibungsloses Funktionieren der IT Architektur. Je besser ein Unternehmen auf einen gravierenden Systemausfall vorbereitet ist, desto geringer ist die Gefahr schwerwiegender Folgen, wenn es zu einem Ausfall kommt. Die Themen HA und Disaster Recovery Strategien gehören daher nicht nur in die Verantwortung der ITAbteilung, sondern zur Agenda der Geschäftsleitung. Studie (2001): Von 4900 befragten Unternehmen antworteten 74%, dass sie erhebliche Ausfälle hatten. Die zunehmende Vernetzung der Märkte, im Zuge der Globalisierung, erfordert ein höheres Maß an Verfügbarkeit (z.B. Onlinedienste mit 24 Stunden Verfügbarkeit, ungebrochener Datenwachstum). Studie: 50-80% mehr Daten pro Jahr im Rechenzentrum. Studie (2001): 2 von 5 Unternehmen melden Konkurs an, aufgrund weil die IT Systeme einer Katastrophe unterlegen sind. Die Kosten durch einen Ausfall können enorm sein. z.B. 1 Stunde Downtime bei Fluggesellschaften: 108 000 USD Kreditgesellschafte: 3,16 Mio USD Wertpapierhandel: 8 Mio USD Wettbewerbsfaktor Wichtig sind Folgekosten (Administration, Image) Gründe für Ausfälle Hardware Fehler menschliches Versagen Katastrophen Was genau ist HA? Bei einigen Anbietern ist bereits eine Uptime von 99% Hochverfügbar. Bei anderen 99,99%. 99% bedeutet in einem Jahr einen Ausfall von mehr als 3 Tagen. 99,99% bedeutet im Jahr einen Ausfall von 52 Minuten. Früher war HA lediglich High-End Servern vorbehalten. Heute ist es nahezu standard. Wer braucht HA? Krankenhäußer Data Warehouse Systeme Telekommunikationsanbieter Onlinedienste Banken / Versicherungen Größere Firmen Folgende Fragen sollten im Vorfeld geklärt werden: Ist ein 24/7 Betrieb notwendig? Ist eine Downtime von mehr als einer Minute verkraftbar? Hängt das Überleben einer Firma davon ab? Ist die Sicherheit eines Unternehmens durch einen Ausfall gefährdet? Sind bei einem Ausfall Menschenleben in Gefahr? Begriffe Bond Mehrere Netzwerkkarten die Zusammengeführt werden – unter Linux bonding genannt mit verschiedenen Modi: acive backup (Redundanz), load balacing (Geschwindigkeit) Trunk (Cisco: Channeling) Switchkonfiguration. Zusammenführen von mehreren Interfaces Interconnect Verbindund zwischen 2 Servern um z.B. das Heartbeatsignal zu übertragen (2 für Redundanz) Client Server 2 Server 1 NAS NAS (Network Attatched Storage) Eine Maschine, die ganz viele Festplatten hat und deren einzige Aufgabe es ist, Speicher zur Verfügung zu stellen. Ausgelegt auf Hochverfügbarkeit. SAN (Storage Attatched Network) Identisch mit NAS, jedoch Fileserverdienste werden zur Verfügung gestellt (z.B. NIS) Verfügbarkeit / HA Ein Service wird als Verfügbar bezeichnet, wenn er in der Lage ist die Aufgaben zu erfüllen für die er Vorgesehen ist Wahrscheinlichkeit, dass ein System innerhalb eines spezifizierten Zeitraumesverfügbar ist. Verfügbarkeit Uptime Uptime Downtime Ein System wird als Hochverfügbar angesehen, wenn eine Anwendung auch im Fehlerfall weiterhin verfügbar ist und ohne unmittelbaren menschlichen Eingriff weiterhin genutzt werden kann der Anwender nimmt nichts von dem Ausfall wahr HA bezeichnet die Fähigkeit eines Systems, auch bei Ausfall einen uneingeschränkten Betrieb zu garantieren. Die Havard Research Group bezieht den Begriff Hochverfügbar auf den prozentualen Wert der Verfügbarkeit. Die Erhöhung der Verfügbarkeit bis hin zur Hochverfügbarkeit wird durch Verringerung der Downtime erreicht. HA-Systeme verfügen meist über folgende Eigenschaften Toleranz und Transparenz gegenüber Fehlern proaktives Monitoring und schnelle Fehlerkennung schnelle Wiederherstellungsmöglichkeiten automatisierte Wiederherstellung ohne menschlichen Eingriff kein (oder geringer) Datenverlust Wichtige Punkte hierzu: Vermeidung Single Point of Failures (Switches, Netzwerk, etc) Hardware Fehlertolerant (RAID Systeme, SAN/NAS) Software Fehlertoleranz Verfügbarkeitsklassen Bezeichnung Verfügbarkeit in % Downtime pro Jahr AEC-0 stabil 99,0% 3,7 Tage AEC-1 verfügbar 99,9% 8,8 Stunden AEC-2 hochverfügbar 99,99% 52,2 Minuten AEC-3 fehlerunempfindlich 99,999% 5,3 Minuten AEC-4 fehlertolerant 99,9999% 32 Sekunden AEC-5 fehlerresistent 99,99999% 3 Sekunden Kosten Verfügbarkeitsklasse 99.0 99.9 99.99 99.999 999.999 999.999 Verfügbarkeit in /% Failover-Cluster Cold Standby Cli Cli Cli public network Primär DB Backup DB SAN Als Cold Standby bezeichnet HA Lösungen, deren Anwendungen im Fehlerfall auf einem Ersatzssystem zur Verfügung gestellt werden. Die Server sind redundant ausgelegt. Der Standby Betrieb ist solange nicht in Betrieb, bis das Primärssystem ausfällt. Die Knoten sind untereinander mit einer Heartbeat Software ausgestattet. Fällt der Primärserver aus, erkennt dies das Ersatzssystem und aktiviert sich selbst. Sicherzustellen ist, das das Primärsystem nicht mehr im Betrieb ist. Notwendige Komponenten: 2 Server mit mind. je 2 Private und Public NICs An beide Server angeschlossene Storage (NAS/SAN) Heartbeat Software Vorteile: Übernahme der Funktionalität ohne administrativen Eingriff Nachteile: Erhöhter Zeitaufwand für Wideranlauf Bei Ausfall des Rechenzentrums fällt der Cluster aus Redundante Hardware kann im Normalbetrieb nicht genutzt werden Warm Standby Cli Cli Cli public network Primär DB SAN / NAS Standby DB SAN / NAS WAN Standby DB SAN / NAS Auch in einem Warm Standby System sind die Server redundant ausgelegt. Anders als beim Cold-Stanby ist der Zweite Server bereits betriebsbereit und kann daher bei einem Ausfall des Primärsystems die Funktionalität schneller übernehmen. Initial wird die Primärdatenbank einmalig über ein Backup auf das Standby System übertragen. Anschließend werden die Transkationen des Primärsystems auf das Standby-System in Echtzeit oder verzögert übertragen. Standby-Systeme können auch für Disaster-Recovery Strategien eingesetzt werden. Man kann diese lokal oder entfernt einsetzen. Notwendige Komponenten: Primär + Standby Server mit eingenem SAN/NAS Vorteile: Bei Ausfall eines Servers Übernahme der Funktionalität ohne administrativen Eingriff Bei Ausfall eines Rechenzentrums kann unter Verwendung eines entfernten Standby-Systems der Betrieb aufrecht erhalten werden. RAC – Real Application Cluster Cli Cli Cli public network Primär DB Standby DB Standby DB SAN / NAS Bei Nutzung eines RAC, sind zwei oder mehrere Rechnerknoten im Cluster aktiviert. Fällt ein Knoten aus, so können sich Clients unmittelbar und ohne Anlaufzeit auf einen verbleibenden Knoten konnektieren. Zudem können Lasten auf alle Clusterknoten verteilt werden. Notwendige Komponenten: Shared Storage für alle beteiligten Clusternodes (konkurrierender Zugriff) Verwendung von Clusterfilesystemen für jeden Clusterknoten mindestens 2 private und 2 public NICs Vorteile: Übernahme der Funktionalität bei Ausfall eines Servers ohne administrativen Eingriff Kein Zeitaufwand für Wiederanlauf, Client Reconnect direkt ohne Zeitversatz auf den Ersatzknoten Redundante Hardware kann auch während des Normalbetriebs genutzt werden Nachteile: Bei Ausfall eines Rechenzentrums (Brand) fällt der gesamte Cluster aus Dieser Fehlerfall kann bei bedarf durch den Einsatz eines zusätzlicher Standby-DB in Kombination mit RAC abgefangen werden. Geo Cluster Systeme Drittanbeter wie Veritas oder Libelle bieten erweiterte Möglichkeiten der Disaster-Absicherung: Clustering ohne geographische Grenzen. Clusterknoten stehen in verschiedenen Rechenzentren, die (teilweise) mehrere 100km entfernt sind. Notwendige Komponenten: abhängig vom Anbieter Vorteile: Datensicherheit auch bei Desaster Szenarien Kosten: Kosten gutes Netzwerk (geographisch) Sämtliche Systeme können auch untereinander kombiniert werden. Open Source HA Linux-HA Project (http://www.linux-ha.org) Generelle Begriffe: Split Brain o private Clusterkommunikation ist gestört o Jeder Knoten glaubt der einzig überlebende zu sein würden Failover initiieren und auf die gemeinsamen Ressourcen zugreifen Dateninkonsistenz Fencing Die Ressource wird gelockt, damit andere Knoten mit nicht definiertem Status nicht mehr drauf zugreifen können o STONITH (Shot the other node in the head) Um sicherzustellen, dass der andere Clusterknoten auch tod ist, wird dieses in die Tat umgesetzt. Heartbeat Software, die überprüft, welcher Knoten aktiv ist (death node detection) und den Switch im Ernstfall vornimmt. Übersicht Open Source Projekt seit 1999 Aktive Community (Koordiniert von IBM) Stable Release 1.2.3 (Sept. 2005 v.2.0.1) einfach aufzusetzen unterstützt redundante prive Heartbeat Verbindungen Serial Interconnect STONITH Plugins DRDB (Distributed Replicated Block Device) Version 0.7 (0.8 bereits vorhanden) http://bccdtsuni.edu http://bofh.be/clusterknoppix http://warewulf.lbv.gov/cgi-bin/trac.cgi Erklärung: Festplatte (Block Device) wird über ein dediziertes Netzwerk auf eine andere Festplatte gespiegelt RAID 1 übers Netz. Funktionsweise: Jeder Host hat einen Status (primary oder secondary). Auf dem primären Host läuft die Applikation. DRDB nimmt die Daten auf dem lokalen Rechner entgegen und sendet diese anschließend an den secondary Host. Auf dem entfernten Host werden die Daten weggeschrieben. Gelesen wird prinzipiell vom Master. Fällt der Primary aus, so erkennt dies das Heartbeat Signal und startet die Applikation auf dem secoundary Host. Ist der ausgefallene Knoten repariert, so ist dieser nun der secondary Knoten und die Daten werden vom primary Master synchronisiert. Einstieg in die Systemprogrammierung (C) Grundsätzlich lassen sich alle wichtigen Funktionen mit man ${NR} $KOMMANDO man 3 except abrufen. Wobei $NR: 1. Ausführbare Programme oder Shell-Kommandos 2. Kernelfunktionen (Linux / Unix Programmers Manual) 3. Bibliotheksfunktionen (Linux / Unix Programmers Manual) 4. Spezielle Dateien (/dev/…) 5. Dateiformate und Konventionen (/etc/passwd) 6. Spiele 7. Makropakete und Konventionen (z.B. man, groff) 8. Systemadministrationsbefehle (in der Regel nur von Root ausführbar) 9. Kernelroutinen (nicht Standard) Headerdateien /usr/include Kompilieren und linken gcc –o Datei Datei1.c Datei2.c … Prozess getpid() Textsegment if( fork() ) forkt erstellt kopie Datensegment Datensegment Stacksegment zu 1 Stacksegment zu 1 E/A CPU Hauptspeicher Systemfunktionen zur Prozessteuerung fork() Erstellen von neuen Prozessen Copy On Write (Cow) Verfahren: Viele Unix-Implementierungen machen immer eine Kopie vom Datensegment, Stacksegment und HEAP des Elternprozesses. Aber oft ist ein solch zeitaufwendiges Kopieren überflüssig, da sich in vielen Anwenderfällen der Kindprozess unmittelbar nach seiner Erstellung durch einen exec-Aufruf mit dem Code und den Daten eines anderen Programms bedient (vfork()). Deswegen wenden viele Unix-Implementierungen das Cow-Verfahren an. Bei diesem Verfahren wird für den Kindprozess zunächst keine Kopie des Daten,Stacksegment und HEAP erstellt, sondern die Originale des Elternprozesses, die der Kern als nur-lesbar einstuft. Erst wenn einer der beiden Prozesse versucht in einem der beiden Speicherbereiche zu schreiben, erzeugt der Kern wirklich eine Kopie. exec Prozesse mit anderem Programmcode übertragen popen Kommunikation zwischen Prozessen wait(int *status)/waitpid(pid_t pid, int *status, int optionen) Warten auf die Beendigung von Prozessen Ein Prozess auf die Beendigung eines seiner Child-Prozesse warten indem er wait() aufruft. Besitzt parent kein Child, wird -1 zurückgegeben. Besitzt parent noch nicht beendete child-Prozesse, wartet wait() bis ein child terminiert. Bei einer normalen oder anormalen Beendigung eines Prozesses wird dem Elternprozess das Signal SIGCHILD gesendet. Um auf die Beendigung eines Kindprozesses zu warten stehen waid() und waitpid() zur Verfügung. Ein Aufruf der o.g. Fkt kann folgendes Verhalten nach sich ziehen 1. Sofortige Rückkehr von wait() bzw waitpid() mit dem Beendigungsstatus eines Kindprozesses 2. ??? 3. Blockierung des aufrufenden Prozesses, wenn die Kindprozesse noch aktiv sind Unterschied zwischen wait() und waitpid(): wait() wartet auf die nächste Beendigung eines beliebigen Kindprozesses, während waitpid() auf die Beendigung eines bestimmten Kindprozesses wartet. wait() blockiert, bis sich ein Kindprozess beendet, während waitpid() mit einer Option die Blockierung des aufrufenden Prozesses unterbunden werden kann. Rückgabewert: Prozess-ID des Kindprozesses bei Erfolg oder -1 bei Fehlern (es existiert kein KindProzess oder wenn durch SIGNAL unterbrochen). Siehe man 2 ${KOMMANDO} Wenn ein Elternprozess sich beendet, bevor all seine Kindprozesse beendet sind, so wird der initProzess (pid: 1) der Elternprozess von allen dessen Kindprozessen. Der Kern setzt dies um, indem er bei jeder Beendigung eines Prozesses die PID aller aktiven Prozesse überprüft. Besitzt ein noch aktiver Prozess PPID die PID des gerade beendeten Prozesses, so erhält er als neue PPID die Nummer 1. So ist imemr sichergestellt, dass jeder Prozess einen Elternprozess hat. Wenn ein Elternprozess nicht auf die Beendigung eines Kindprozesses wartet, so stellt sich die Frage, wie der Elternprozess dann nachträglich den Beendigungsstatus des nun nicht mehr existierenden Kindprozesses abfragen kann. Dieses Problem wird dadurch gelöst, dass der Kern sich über jeden beendeten Prozesses eine gewisse Menge an Informationen (mind. PID, Beendigungsstatus und verbrauchte CPU-Zeit) mittels der beiden Funktionen wait() und waitpid() erfragen kann. Solche Kindprozesse, die sich beendet haben,ohne dass der Elternprozess auf diese Wartet, werden als Zombies angzeigt. Systemfehlermeldungen Bei Fehler liefern die meisten Systemfunktionen -1 als Rückgabewert. Zusätzlich wird die Variable errno auf ungleich Null gesetzt. Diese Variable errno in <errno.h> definiert. ANSI C garantiert nur für den Programmstart, dass die Variable auf Null gesetzt wird. Systemfunktionen setzen die Variable niemals zurück auf Null. Gängige Praxis: Vor Aufruf der Systemfunktion errno auf Null setzen und nach dem Aufruf den Wert überprüfen. Um die Fehlermeldung zu erhalten, die zu einem errno stehenden Fehlercode gehört, schreibt ANSI C die beiden Funktionen perror() und strerror() vor. perror() Die Funktion gibt auf stderr die zum Momentan in errno stehenden Fehlercode gehörende Fehlermeldung aus: # include <stdio.h> void perror(const char * meldung) Signale Diese errno-Fehlermeldung entspricht genau dem Rückgabewert der nachfolgende beschriebenen Funktion strerror(), falls diese mit dem gleichen error-Wert aus Argument aufgerufen wird. strerror() Die Funktion liefert zu einer Fehlernummer (üblicherweise der errno-Wert gehörende Meldung als Rückgabewert. #include <string.h> char * strerror (int fehler_nr) Signale sind asynchrone Ereignisse, die erzeugt werden, wenn während einer Programmausführung besondere Ereignisee eintreten (z.B. Division durch Null wird ein SIGFPE geliefet) Drei möglichkeiten um auf das Eintreffen eines Signals zu reagieren: Ignorieren des Signals Dies ist nicht empfehlendswert für Signale, die einen Hardwarefehler (Division durch Null, Zugriff auf unerlaubte Speicherbereiche) anzeigen, da der weitere Ablauf eines Prozesses zu nicht vorhersehbaren Ergebnissen führen kann. Voreingestellte Reaktion Für jedes mögliche Signal ist eine bestimmte Reaktion festgelegt. (Bei SIGFPE die Beendigung des entsprechenden Prozesses) Ausführen von eigenen Funktionen Für jedes Signal kann ein Prozess durch seine eigene Reaktion festlegen. Bei eintreffen des entsprechenden Signals werden dann automatisch diese eingerichteten Signalhandlern ausgeführt. Allgemein nützliche Funktionen void * malloc (size_t groesse) Allokiert Speicherbereich von n Bytes void * calloc (size_t anzahl, size_t groesse) Allokiert einen Speicherbereich, der groß genug ist, von anzahl objekten von groesse void * realloc ( void * zeiger, size_t groesse) Veraendert die Groesse des Speicherbereichs, auf das Zeiger zeigt, nach groesse void * free ( void * zeiger) Bewirkt die Speicherfreigabe, auf den der Zeiger zeigt void * memchr (const void * adress, int such_zeiger, size_t m) Sucht das erste Vorkommen von such_zeichen in den ersten n zeichen des Speicherbereichs, auf der Adress zeigt int memcmp (const void * adresse1, const void * adresse2, size_t n) verlgeicht die ersten n Zeichen des Speicherbereichs auf den adress21 zeigt mit den ersten n Zeichendes Speicherbereichs auf den adresse2 zeigt void * memcpy (void * ziel, const void * quelle, size_t n) Kopiert n Zeichen vom Speicherplatz, auf den quelle zeigt, in den Speicherbereich auf den ziel zeigt. Bei überlappenden Bereichen ist das Verhalten undefiniert für schnelle, aber unsichere void * memmove (void * ziel, const void * quelle, size_t n) Kopiert n Zeichen vom Speicherplatz auf den Quelle zeig, in den Speicherbereich auf den ziel zeigt. Hier findet bei der Überlappung ein korrekter Kopiervorgang statt (Sicherheit vor Schnelligkeit) Unterschiede zwischen Systemaufrufen und Bibliotheksfunktionen Benutzercode Bibliotheksfunktionen Systemaufrufe Systemkern Systemaufrufe sind Schnittstellen zum Kern. Sie sind in Sektion der Linux/Unix Programmers Manual beschreiben, wo sie in Form von C-Deklarationen angegeben sind. All diese Systemfunktionen befinden sich in der C-Standartbibliothek, so dass ans Benutzersicht kein Unterschied zwischen diesen beiden Funktionsarten besteht. Bibliotheksfunktionen Diese Funktionen (sind in Sektion 3 Programmers Manual beschrieben) stellen keine Schnittstellen zum Systemkern dar, wenn auch einige Biliotheksfunktionen eine oder mehrere Systemfunktionen ihrerseits aufrufen (printf ruft systemfunktion while auf). Bibliotheksfunktionen können leichter ersetzt werden. Systemfunktionen setzten eine Änderung am Systemkern voraus. void exit(int status) Ein Prozess beendet sich durch diesen Call Kein Rücksprung zum aufgerufenen Prozess Übergabe des Integerwerts an den Kernel (Exit Status) Wird ein Prozess ohne Rückgabe eines Exit-Status aufgerufen, so ist dieser undefiniert, was andere Prozesse wuederrum in Schwierigkeiten bringen kann (sauber Programmierstil). Programme: netstat –tpan route –n ifconfig ping Byteanordnung (big endian, little endian) Nimmt man z.B. den Datentyp Integer (32-48 Byte), so gibt es verschiedene Möglichkeiten fuer die Anordnung der Bytes im Speicher: big-endian (LSB -> MSB) Das höchstwertige byte wird an der niedrigsten Adresse gespeichert. z.B. 16 Bit-Wert 0x1234 wird als 0x12, 0x34 gespeichert. little-endian Das niederwertigste Byte wird an der niedrigsten Adresse gespeichert. z.B. 16 Bit Wert: 0x1234 wird als 0x34, 0x12 gespeichert. TCP verwendet big-endian. Die Reihenfolge der Bytes bezeichnet man als Network-Byte-Order / InternetByte-Order. Die Strategie wird nur vorgeschlagen, jedoch nicht überprüft. Hierfür muss sich der Entwickler bemühen. Sockets Sockets sind Endpunkte der kommunikationsbeziehung zwischen Client und Server und werden durch den socket()-Aufurf erzeugt, der einen Socket-Descriptor erzeugt (eindeutiger Integer Wert). Der Socket-Descriptor, wird bei allen folgenden Systemaufrufen übergeben. Das Vorhandensein von 2 möglichen Konstanten für die gleiche Protokollart ist historisch begründet, da ursprünglich eine Protokollfamilie mehrere Adressfamilien unterstützen sollte. Die PF-Konstante sollte dabei beim Anlegen des Sockets und die AF-Konstante (Adress Family) in den Socketadresstrukturen verwendet werden. Da bisher keine Protokollfamilie mehrere Adressfamilien unterstützt, sind die entsprechenden PFKonstanten gleich den AF-Konstanten. Das Socketinterface stellt drei Typen von Sockets bereit: 1. SOCK_DRGRAM (UDP) 2. SOCK_STREAM (IP) 3. SOCK_RAW (RAW) Datagramm Sockets Bei einer Verwendung von Datagramm Sockets (verbindunglose Kommunikation) werden Daten mit den Calls sento() und recvfrom() oder bind() und read() ausgetauscht. Server Client socket() socket() recvfrom() sento() blockt, Daten abarbeiten socket() sento() Stream Sockets (TCP) Der Ablauf bei der Verbindungsorientierten Kommunikation mit Hilfe von Stream Sockets gliedert sich in folgende Schritte: 1. Erschaffen eines Sockets 2. Den socket an einen Namen binden mit bind() 3. Verbindung aufbauen mit listen(),accept(),connect() 4. Daten übertragenmit send(), recv(), read(), write() Lokale Sockets Erstellen von lokalen Sockets # include <sys/types.h> # include <sys/socket.h> /** * domain: AF_LOCAL * typ: SOCK_STREAM oder SOCK_DGRAM * protocol: 0 * die angegebenen sockets werden als sv[0] und sv[1] bereitgestellt */ int socketpair(int domain, int typ, int protocol, int sv[2]); Die Funktion socketpair() ist ähnlich der Funktion pipe(), da sie zwei Deskriptoren bereitstellt, die miteinander verbunden sind. Anders als bei pipes, die halb Duplex sind, sind die beiden zur Verfügung stehenden Sockets vollduplex, was bedeutet, dass von beiden Socjetdeskribtoren gelesen und auch geschrieben werden kann. Siehe Blatt: Beispiel IPC Schliessen von lokalen Sockets #include <sys/socket.h> /** * wie * SHUT_RD: Leseseite schliessen * SHUT_WR: Schreibseite schliessen * SHUT_RDWR: Lese- und schreibseite schliessen -> wie close() */ int shutdown( int socket, int wie); Einführung in Versionsverwaltungssysteme Softwareentwicklung im Team ohne den Einsatz von Versionsverwaltungssystemen ist heute nicht mehr denkbar. Unter Versionsverwaltung versteht man ein System welches typischerweise in der Softwareentwicklung zur Versionisierung und um den gesamten Zugriff auf Quelltexte zu kontrollieren, eingesetzt wird. Hierzu werden alle laufenden Änderungen erfasst und alle Versionsstände der Dateien in einem Archiv mit Zeitstempel und Benutzerkennung gesichert. Es wird sichergestellt, dass jeder Benutzer mit dem aktuellen Stand arbeitet oder auf Wunsch auf die archivierten Stände zurückgreifen kann. Dadurch ist eine Versionsverwaltung nicht nur für professionelle Entwickler in großen Teams sondern auch für allementwickelnde Interessen. Es kann jederzeit eine ältere Version aufgerufen werden, falls eine Änderung nicht funktioniert und man sich nicht sicher ist was geändert wurde. Für Versionsverwaltungssysteme sind die Abkürzungen VCS (Version Control System) oder SCM (Source Code Management Control). Systemaufbau Das zentrale Archiv wird als Repository (vgl. Behälter) bezeichnet. Die meisten Systeme verwenden hierfür ein eigenes Dateiformat (oder eine Datenbank). Die Versionsverwaltungssoftware speichert dabei üblicherweise die Unterschiede zwischen 2 Versionen, um Speicherplatz zu sparen. Dadurch kann eine große Zahl von Versionen archiviert werden. Durch dieses Speicherformat kann jedoch nur mit der Software des Verwaltungssystems auf die Daten zugegriffen werden, die die gewünschte Version bei einem Aufruf unmittelbar aus den abgelegten „Schnipseln“ zusammenbaut. Solche Software ist häufig als Client-Server-System aufgebaut, so dass der Zugriff auf ein Repository über das Netzwerk erfolgen kann. Damit die in der Softwareentwicklung eingesetzten Programme (wie z.B. Compiler) mit den im Repository abgelegten Dateien arbeiten können, ist es erforderlich dass jeder Entwickler sich den aktuellen (oder auch einen älteren) Stand des Projekts in Form von eines Verzeichnisbaums aus herkömmlichen Dateien erzeugten kann. Ein solcher Verzeichnisbaum wird als Arbeitskopie bezeichnet. Ein wichtiger Teil des Versionsverwaltungssystems ist ein Programm, das in der Lage ist, diese Arbeitskopie mit den Daten des Repositorys zu synchronisieren. Das Übertrage einer Version aus dem Repos in die Arbeitskopie wird als Checkout bezeichnet, während die umgekehrte Übertragung als checkin oder commit genannt wird. Solche Programme sind entweder Kommandozeilen orientiert, mit grafischer Benutzeroberfläche oder als Plugin für Softwareentwicklungsumgebungen ausgeführt. Hauptaufgaben: Protokollierungen oder Änderungen Es kann jederzeit nachvollzogen werden, wer wann was geändert hat. Wiederherstellung von alten Ständen einzelner Dateien -> somit können versehentliche Änderungen jederzeit wieder rückgängig gemacht werden Archivierung der einzelnen Release Stände eines Projekts. Dadurch ist es jederzeit möglich auf alle ausgelieferten Versionen zurückzugreifen. Koordinierung des gemeinsammen Zugriffs von mehreren Enwicklern auf die Dateien Gleichzeitige Entwicklung mehrerer Entwicklungszweige (branches) eines Projekt (z.B. stabile Release Version und Entwickler Version mit größeren nicht getesteten Änderungen) Hier wird der Entwickler bei der Übernahme von einzelnen Änderungen zwischen den Zweigen und der Hauptversion unterstützt. Arbeitsweisen der Versionsverwaltung Lock Modify Write Dies ist die traditionelle Arbeitsweise eines VCS. Einzelne Dateien müssen vor einer Änderung durch den Benutzer gesperrt und nach der Änderung wieder freigegeben werden. Während die Dateien gesperrt sind, verhindert das System Änderungen vom Benutzer. Copy Modify Merge Ein solches System lässt gleichzeitige Änderungen mehrerer Benutzer an einer Datei zu. Anschließend werden die Änderungen automatisch oder manuell zusammengeführt (merge). Somit wird die Arbeit des Entwicklers wesentlich erleichtert, da Änderungen nicht im Voraus angekündigt werden müssen insbesondere, wenn mehrere Entwickler räumlich getrennt sind arbeiten, wie es z.B. bei OpenSource Projekten der Fall ist, ermöglicht dies ein deutlich flüssigeres Arbeiten ermöglich