rds-Subroutine

Zweck

Reliable Datagram Sockets (RDS) bietet eine zuverlässige, in der Reihenfolge befindliche Datenpaketzustellung zwischen Sockets über verschiedene Netztransporte.

Bibliothek

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/bypass.h>
#include <net/rds_rdma.h>

Beschreibung

RDS ist eine Implementierung der RDS -API (Application Programming Interface). RDS kann über InfiniBand und Loopback transportiert werden. RDS über TCP ist inaktiviert. RDS verwendet die AF_INET -Standardadressen zur Identifizierung der Endpunkte.

Socketerstellung

RDS -Sockets werden wie folgt erstellt:
rds_socket = socket(AF_BYPASS, SOCK_SEQPACKET, BYPASSPROTO_RDS);

Socketoptionen

RDS unterstützt mehrere Socketoptionen über die Aufrufe setsockopt und getsockopt . Die folgenden Optionen für die Socketebene SOL_SOCKET sind wichtig.
SO_RCVBUF
Gibt die Größe des Empfangspuffers an. Siehe Überlastungssteuerung.
SO_SNDBUF
Gibt die Größe des Sendepuffers an Siehe Nachrichtenübertragung.
SO_SNDTIMEO (SO_SNDTIMEO
Gibt das Sendezeitlimit des Sockets an, wenn Sie eine Nachricht in ein Socket mit einer vollen Warteschlange im Blockierungsmodus einreihen.
RDS unterstützt auch mehrere protokollspezifische Optionen mit der SOL_RDS -Socketebene.

Bindung

Ein neuer RDS hat keine lokale Adresse, wenn er ursprünglich vom Aufruf socket zurückgegeben wird. Der Socket muss durch Ausführen des Systemaufrufs bind an eine lokale Adresse gebunden werden, bevor Nachrichten gesendet oder empfangen werden. Der Aufruf bind ordnet das Socket einem bestimmten Netztransport zu, der auf dem Typ der Schnittstelle basiert, der die lokale Adresse zugeordnet ist. Ab dem Punkt, an dem der Aufruf an das Socket angehängt wird, kann das Socket die Ziele erreichen, die über diesen Netztransport verfügbar sind.

Wenn die Bindung beispielsweise an die Adresse einer InfiniBand -Schnittstelle wie ib0erfolgt, verwendet das Socket das InfiniBand -Transportsystem. Wenn RDS der spezifischen Adresse kein Transportsystem zuordnen kann, wird der Wert EADDRNOTAVAIL zurückgegeben.

Ein RDS -Socket kann nur an eine Adresse und nur ein Socket an eine bestimmte Adresse oder ein bestimmtes Portpaar gebunden werden. Wenn in der Bindungsadresse kein Port angegeben ist, wird ein nicht gebundener Port zufällig ausgewählt.

RDS lässt nicht zu, dass die Anwendung ein zuvor gebundenes Socket an eine andere Adresse bindet. Die Bindung an die Platzhalteradresse INADDR_ANY ist nicht zulässig.

Verbindungen herstellen

Im Standardbetriebsmodus verwendet RDS nicht verbundene Sockets und gibt die Zieladresse als Argument für die Subroutine sendmsg an. Mit RDS können Sockets jedoch über die Subroutine connect mit einem fernen Endpunkt verbunden werden. Wenn ein Socket verbunden ist, können Sie die Subroutine sendmsg aufrufen, ohne eine Zieladresse anzugeben, und die Subroutine verwendet die ferne Adresse, die zuvor angegeben wurde.

Überlastungssteuerung

RDS verfügt nicht über einen expliziten Überlastungssteuerungsmechanismus wie die gängigen Streaming-Protokolle wie TCP. Für die Sockets gelten zwei Warteschlangenbegrenzungen: send queue size und receive queue size. Nachrichten werden basierend auf der Anzahl der Bytes der Nutzdaten berücksichtigt.

send queue size begrenzt die Daten, die die lokalen Prozesse in die Warteschlange eines lokalen Sockets stellen können. Wenn der Grenzwert überschritten wird, akzeptiert der Kernel keine Nachrichten, bis die Warteschlange frei ist und Nachrichten vom fernen Host zugestellt und bestätigt werden.

receive queue size begrenzt die Daten, die RDS in der Empfangswarteschlange eines Sockets speichert, bevor das Socket als überlastetmarkiert wird. Wenn ein Socket überlastet wird, sendet RDS eine Überlastungsmap -Aktualisierung an die anderen teilnehmenden Hosts, von denen erwartet wird, dass sie das Senden weiterer Nachrichten an diesen Port stoppen.

Es gibt ein Zeitfenster, in dem ein ferner Host weiterhin Nachrichten an einen überlasteten Port senden kann. RDS löst das Zeitfenster auf, indem Nachrichten akzeptiert werden, auch wenn die Empfangswarteschlange des Sockets den Grenzwert überschreitet.

Wenn die Anwendung eingehende Nachrichten aus der Empfangswarteschlange über den Systemaufruf recvmsg empfängt, verringert sich die Anzahl der Bytes in der Empfangswarteschlange unter die Größe der Empfangswarteschlange und der Port wird als uncongestedmarkiert. Eine Überlastungsaktualisierung wird an alle teilnehmenden Hosts gesendet.

Die Werte für die Sendepuffergröße und die Empfangspuffergröße können von der Anwendung über die Socketoptionen SO_SNDBUF und SO_RCVBUF optimiert werden.

Blockierungsverhalten

Die Aufrufe sendmsg und recvmsg können in verschiedenen Situationen blockiert werden. Ein Aufruf kann blockiert oder mit einem Fehler zurückgegeben werden, abhängig von der nicht blockierenden Einstellung des Dateideskriptors und dem Nachrichtenflag MSG_DONTWAIT . Wenn der Dateideskriptor auf den Blockierungsmodus (Standardeinstellung) gesetzt und das Flag MSG_DONTWAIT nicht angegeben ist, wird der Aufruf blockiert.

Die Socketoptionen SO_SNDTIMEO und SO_RCVTIMEO werden verwendet, um ein Zeitlimit (in Sekunden) anzugeben, nach dem der Aufruf beendet wird und einen Fehler zurückgibt. Das Standardzeitlimit ist 0, sodass RDS unbegrenzt blockiert werden kann.

Nachrichtenübertragung

Nachrichten können mit dem Aufruf sendmsg gesendet werden, nachdem das RDS -Socket gebunden wurde. Die Nachrichtenlänge darf 4 GB nicht überschreiten, da das Verbindungsprotokoll eine 32-Bit-Ganzzahl ohne Vorzeichen verwendet, um die Nachrichtenlänge auszudrücken.

RDS unterstützt keine Daten, die extern sind. Anwendungen können Daten nur an Unicastadressen senden, wenn Broadcast oder Multicast nicht unterstützt werden.

Ein erfolgreicher sendmsg -Aufruf stellt die Nachricht in die Übertragungswarteschlange des Sockets, wo sie verbleibt, bis das Ziel bestätigt, dass sich die Nachricht nicht mehr im Netz befindet, oder die Anwendung die Nachricht aus der Sendewarteschlange entfernt.

Nachrichten können mit der Socketoption RDS_CANCEL_SENT_TO aus der Sendewarteschlange entfernt werden.

Wenn sich eine Nachricht in der Übertragungswarteschlange befindet, werden ihre Nutzdatenbyte berücksichtigt. Wird versucht, eine Nachricht zu senden, wenn die Übertragungswarteschlange nicht frei ist, blockiert der Aufruf oder gibt den Wert EAGAIN zurück.

Wenn Nachrichten an ein Ziel gesendet werden, das als überlastet markiert ist, wird der Aufruf blockiert oder der WertENOBUFS zurückgegeben.

Eine Nachricht, die ohne Nutzdatenbyte gesendet wird, benötigt keinen Speicherplatz im Sendepuffer des Ziels, aber ein Nachrichtenempfang wird an das Ziel gesendet. Der Empfänger kann keine Nutzdaten abrufen, aber die Adresse des Absenders kann angezeigt werden.

Nachrichten, die an einen Port gesendet werden, an den kein Socket gebunden ist, werden vom Zielhost verworfen. Dem Absender werden keine Fehlernachrichten gemeldet.

Nachrichtenempfang

Nachrichten können mit dem Aufruf recvmsg in RDS empfangen werden, nachdem sie an eine Quellenadresse gebunden wurde. RDS gibt Nachrichten in derselben Reihenfolge zurück, in der der Absender die Nachrichten gesendet hat.

Die Adresse des Absenders wird in der Sockaddr_in -Struktur zurückgegeben, auf die das Feld Nachrichtenname verweist, wenn das Feld festgelegt ist.

Wenn das Flag MSG_PEEK gesetzt ist, wird die erste Nachricht in der Empfangswarteschlange zurückgegeben, ohne die Nachricht aus der Warteschlange zu entfernen.

Der Speicher, der von Nachrichten belegt wird, die auf Zustellung warten, begrenzt nicht die Anzahl der Nachrichten, die zum Empfangen in die Warteschlange eingereiht werden können. RDS versucht, eine Überlastung zu steuern.

Wenn die Länge der Nachricht die Größe des Puffers überschreitet, der für den recvmsg -Aufruf bereitgestellt wird, werden die verbleibenden Bytes in der Nachricht verworfen und das Flag MSG_TRUNC wird im Feld msg_flags gesetzt. In diesem Fall gibt der Aufruf recvmsg die Anzahl der kopierten Bytes zurück. Es gibt nicht die Länge der gesamten Nachricht zurück. Wenn MSG_TRUNC im Flagargument auf recvmsggesetzt ist, wird die Anzahl der Bytes in der gesamten Nachricht zurückgegeben. Sie können die Größe der nächsten Nachricht in der Empfangswarteschlange anzeigen, ohne einen Puffer mit Nulllänge anzugeben und die Optionen MSG_PEEK und MSG_TRUNC im Argument "flags" festzulegen.

Die Sendeadresse einer Nachricht mit der Länge null wird im Feld Nachrichtenname angegeben.

Steuernachrichten

RDS verwendet Steuernachrichten, bei denen es sich um Hilfsdaten handelt, mithilfe der Felder msg_control und msg_controllen in den Aufrufen sendmsg und recvmsg . Von RDS generierte Steuernachrichten haben den Wert sol_rdsfür cmsg_level . Die meisten Steuernachrichten beziehen sich auf die Schnittstelle zerocopy, die in RDS Version 3 hinzugefügt wurde, und werden in der Subroutine rds-rdma beschrieben.

Die einzige Ausnahme ist die Nachricht RDS_CMSG_CONG_UPDATE .

Abfragen

Die Unterstützung für die Schnittstelle poll ist begrenzt. POLLIN wird zurückgegeben, wenn eine RDS -Nachricht oder eine Steuernachricht in der Empfangswarteschlange des Sockets wartet. POLLOUT wird zurückgegeben, wenn in der Sendewarteschlange des Sockets Speicherplatz vorhanden ist.

Das Senden von Nachrichten an die überlasteten Ports erfordert einen speziellen Bearbeitungsmechanismus. Wenn eine Anwendung versucht, eine Nachricht an ein überlastete Ziel zu senden, gibt der Systemaufruf den Wert ENOBUFS zurück. RDS kann POLLOUT nicht abfragen, da die Übertragungswarteschlange weiterhin die Nachrichten aufnehmen kann und der Aufruf an die poll -Schnittstelle möglicherweise sofort zurückgegeben wird, auch wenn das Ziel überlastet ist.

Sie können eine der folgenden Methoden ausführen, um die Überlastung zu handhaben:
  • Fragen Sie die Option POLLIN ab. Standardmäßig wird ein Prozess, der sich in der Schnittstelle poll im Ruhemodus befindet, aktiviert, wenn die Überlastungsmap aktualisiert wird. Die Anwendung kann jede zuvor überlastete Sendeoperation wiederholen.
  • Überwachen Sie die explizite Überlastung, die der Anwendung mehr Kontrolle gibt.
Bei expliziter Überwachung fragt die Anwendung die Option POLLIN wie zuvor ab und verwendet zusätzlich die Socketoption RDS_CONG_MONITOR , um einen 64-Bit-Maskenwert im Socket zu installieren, wobei jedes Bit einer Gruppe von Ports entspricht. Wenn eine Überlastungsaktualisierung empfangen wird, überprüft das RDS -Socket die Gruppe der Ports, die zu uncongested wurden, anhand der im Socket installierten Bitmaske. Wenn sie sich überschneiden, wird eine Steuernachricht auf dem Socket eingereiht und die Anwendung aktiviert. Wenn der Aufruf recvmsg aufgerufen wird, gibt RDS die Steuernachricht an, die die Bitmap am Socket enthält.

Die Überlastungsüberwachungsbitmaske kann mithilfe des Aufrufs setsockopt mit der Option RDS_CONG_MONITOR und einem Zeiger auf die 64-Bit-Maskenvariable festgelegt und abgefragt werden.

Überlastungsaktualisierungen werden der Anwendung über die RDS_CMSG_CONG_UPDATE -Steuernachrichten zugestellt. Die Steuernachrichten werden separat zugestellt, jedoch nie mit RDS -Datennachrichten. Das Feld cmsg_data der Steuernachricht enthält acht Byte lange Daten, die den 64-Bit-Maskenwert enthalten.

Anwendungen können die folgenden Makros verwenden, um Bit in der Bitmaske zu testen und zu setzen:
#define RDS_CONG_MONITOR_SIZE   64
#define RDS_CONG_MONITOR_BIT(port)  (((unsigned int) port) % RDS_CONG_MONITOR_SIZE)
#define RDS_CONG_MONITOR_MASK(port) (1 << RDS_CONG_MONITOR_BIT(port))

Abbrechen von Nachrichten

Eine Anwendung kann Nachrichten aus der Sendewarteschlange abbrechen, indem sie die Socketoption RDS_CANCEL_SENT_TO im Aufruf setsockopt verwendet. Der Aufruf setsockopt verwendet eine optionale sockaddr_in -Adressstruktur als Argument. Nur Nachrichten an die durch die sockaddr_in -Adresse angegebene Zieladresse werden gelöscht. Wenn keine Adresse angegeben wird, werden alle anstehenden Nachrichten gelöscht.
Anmerkung: Dieser Aufruf wirkt sich auf Nachrichten aus, die nicht übertragen werden, und Nachrichten, die übertragen werden, aber keine Bestätigung vom fernen Host empfangen werden.

Zuverlässigkeit

Wenn der sendmsg erfolgreich ist, garantiert RDS , dass die Nachricht für recvmsg auf einem Socket sichtbar ist, der an die Zieladresse gebunden ist, solange dieser Zielsocket geöffnet bleibt.

Wenn am Ziel kein Socket gebunden ist, wird die Nachricht gelöscht. Wenn der RDS , der Nachrichten sendet, nicht sicher ist, ob ein Socket gebunden ist, versucht er, die Nachricht unbegrenzt zu senden, bis er sicher ist oder die gesendete Nachricht abgebrochen wird.

Wenn ein Socket geschlossen wird, werden die anstehenden gesendeten Nachrichten auf dem Socket abgebrochen und können vom Empfänger nicht angezeigt werden.

Mit der Socketoption RDS_CANCEL_SENT_TO können alle anstehenden Nachrichten an ein bestimmtes Ziel abgebrochen werden.

Wenn ein empfangendes Socket mit anstehenden Nachrichten geschlossen wird, betrachtet der Absender diese Nachrichten als Nachrichten, die das Netz verlassen haben, und überträgt sie nicht erneut.

Der Aufruf recvmsg sieht eine Nachricht, sofern nicht MSG_PEEK angegeben ist. Wenn die Nachricht zugestellt wird, wird sie aus der Übertragungswarteschlange des sendenden Sockets entfernt.

Alle Nachrichten, die von demselben Socket an dasselbe Ziel gesendet werden, werden in der Reihenfolge zugestellt, in der sie gesendet wurden. Nachrichten, die von verschiedenen Sockets oder an verschiedene Ziele gesendet werden, werden nach dem Zufallsprinzip zugestellt.