2010-12-14 5 views
7

Ich versuche einen Platz im Linux-Kernel zu finden, wo es nach dem Prozess-Löschen bereinigt. Insbesondere möchte ich sehen, ob/wie offene TCP-Verbindungen behandelt werden, nachdem der Prozess mit -9-Signal beendet wurde. Ich bin mir ziemlich sicher, dass es alle Verbindungen schließt, aber ich möchte Details sehen, und wenn es eine Chance gibt, dass Verbindungen nicht richtig geschlossen werden.Wohin führt der Linux-Kernel die Bereinigung von TCP-Verbindungen nach dem Prozess ab?

Zeiger auf Linux-Kernel-Quellen sind willkommen.

+0

Ich bin neugierig, wenn Sie eine Antwort mögen, und wenn es ein Kernel-Problem oder ein Netzwerkproblem war. Auch das Aktualisieren Ihrer Frage würde anderen helfen, die später darüber stolpern. – JimB

+0

@ JimB, Wenn Sie an unserem Netzwerkproblem interessiert sind, dann nein, ich weiß nicht, was das Problem ist/war. Wir haben diese inaktiven Verbindungen hinzugefügt, überprüfen und verwenden so_keepalive jetzt, aber es gibt so viel Verkehr, dass es sehr schwer ist, Traffic Dump zu machen und zu überprüfen, ob bestimmte Pakete verloren gehen oder nicht. Über dieses Schließen habe ich Quellen überprüft, die caf in seiner Antwort erwähnt hat, und ich glaube, dass der Linux-Kernel * versucht * die Sockets zu schließen, wenn der Prozess beendet wird. Wenn es gelingt oder nicht, ist eine andere Frage. –

Antwort

10

Das Fleisch der Prozessbeendigung wird von exit.c:do_exit() gehandhabt. Diese Funktion ruft exit_files() auf, die wiederum put_files_struct() aufruft, die close_files() aufruft.

close_files() Schleifen über alle Datei-Deskriptoren der Prozess offen hat (die alle Buchsen einschließt), ruft filp_close() auf jeder, der auf dem fput()struct file Objekt aufruft. Wenn die letzte Referenz auf struct file gesetzt wurde, ruft fput() die Methode .release() des Dateiobjekts auf, die für Sockets die sock_close()-Funktion in net/socket.c ist.

6

Ich bin ziemlich sicher, dass die Socket-Bereinigung mehr eine Nebenwirkung der Freigabe aller Dateideskriptoren nach dem Prozess stirbt, und nicht direkt durch die Prozessbereinigung.

Ich gehe jedoch auf ein Bein und gehe davon aus, dass Sie eine gemeinsame Fallstricke mit Netzwerkprogrammierung treffen. Wenn ich richtig rate, dass Ihr Problem ist, dass Sie eine "Adresse in Verwendung" -Fehler (EADDRINUSE) erhalten, wenn Sie versuchen, an eine Adresse zu binden, nachdem ein Prozess getötet wurde, dann laufen Sie in die TIME_WAIT des Sockets.

Wenn dies der Fall ist, können Sie entweder auf das Timeout warten, in der Regel 60 Sekunden, oder Sie können den Socket so ändern, dass er sofort wieder verwendet werden kann.

int sock, ret, on; 
struct sockaddr_in servaddr; 

sock = socket(AF_INET, SOCK_STREAM, 0): 

/* Enable address reuse */ 
on = 1; 
ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 

[EDIT]

Aus Ihren Kommentaren, Es klingt wie Sie Probleme mit halboffene Verbindungen haben, und nicht vollständig verstehen, wie TCP funktioniert. TCP hat keine Möglichkeit zu wissen, ob ein Client tot ist oder gerade leer ist. Wenn Sie einen Clientprozess kill -9 ausführen, wird der vier-wege schließende Handshake nie abgeschlossen. Dies sollte jedoch keine offenen Verbindungen auf Ihrem Server hinterlassen, so dass Sie immer noch einen Netzwerk-Dump benötigen, um sicher zu sein, was vor sich geht.

Ich kann nicht sicher sagen, wie Sie damit umgehen sollten, ohne genau zu wissen, was Sie tun, aber Sie können über TCP Keepalive here lesen. Einige andere Optionen senden in regelmäßigen Abständen leere oder leere Nachrichten an den Client (möglicherweise müssen Sie Ihr Protokoll ändern) oder feste Zeitgeber für inaktive Verbindungen festlegen (dies kann zu ungültigen Verbindungen führen).

+0

Danke ... Das Aufräumen von Dateideskriptoren würde tatsächlich zum Schließen der Verbindung führen. Übrigens, ich stoße auf ein anderes Problem ;-) Unser Server sieht veraltete Verbindungen von Clients, die mit -9 getötet wurden, und wir versuchen herauszufinden, warum.Zur Zeit haben wir die Aufgabe, unbelegte Verbindungen vom Server automatisch zu schließen und SO_KEEPALIVE zu verwenden, aber wir versuchen auch, das Problem zu verstehen. –

+0

Dann scheint es, dass Sie Probleme mit halboffenen Verbindungen haben. Ich werde meine Antwort aktualisieren. – JimB

+0

Danke für das Update. Ich habe Tcp keepalive faq erst gestern gelesen. Wir haben das Löschen von Verbindungen im Leerlauf zum Server hinzugefügt. Das Ändern des Protokolls zum Senden von "Pings" vom Server ist keine Option, aber wir werden SO_KEEPALIVE mit dem Löschen von inaktiven Verbindungen kombinieren, und das sollte für uns ausreichen. Was mich verwirrt ist, dass, wenn ich lokal mit kill -9 spiele, der Kernel versucht, diese Verbindung zu schließen. BTW, Clients und Server haben beide die Kontrolle über dasselbe Netzwerk. Dieses Problem tritt nur bei einer Bereitstellung auf. –

Verwandte Themen