Schließen eines Sockets, der einen untergeordneten Prozess wartet, wenn der übergeordnete Prozess beendet wurde

965
Peregring-lk

Die Situation ist die folgende:

  • Ein Dienst / übergeordneter Prozess ist mit einem "öffentlichen Port" verbunden (der übergeordnete Prozess ist ein Dienst). Dieser "öffentliche Port" ist 11000. Wenn neue Anforderungen vom übergeordneten Port 11000 an den übergeordneten Prozess eintreffen, sendet der Server diese Anforderungen über einen "privaten" Port (Socket) an einen untergeordneten Prozess. Sie wissen, die typische Art der Implementierung von Servern.

  • Der übergeordnete Prozess wird beendet, aber der Socket wird nicht geschlossen (ich weiß noch nicht, warum).

  • Der verwaiste Prozess wartet, bis der Socket geschlossen ist, und pkill funktioniert nicht (es befindet sich im unterbrechungsfreien Schlaf).

  • Ich kann den Server nicht erneut ausführen, da der Server die Adresse (0.0.0.0:11000) bereits verwendet.

Ich habe also zwei Möglichkeiten, den "internen Socket" zu schließen, um den verwaisten Prozess zu beenden, oder "free", um die Adresse / den Port 0.0.0.0:11000 irgendwie auszuführen, um den Server erneut auszuführen, und den verwaisten Prozess im Wartezustand belassen. Vermeiden Sie es, den Server jedes Mal neu zu starten, wenn er ausfällt, während ich das Problem untersuche.

Nützliche Informationen über die Situation (die PID des Kinderprozesses ist 1993):

$ sudo lsof -np 1993  [...] proc 1993 root 16u IPv4 14997 0t0 TCP 127.0.0.1:42982->127.0.0.1:37528 (CLOSE_WAIT) 

Der Port, den ich schließen möchte, ist also 37528. Der Dateideskriptor des entsprechenden Socket lautet 16u (oder meiner Meinung nach).

$ sudo strace -p 1993  Process 1993 attached futex(0x2fff414, FUTEX_WAIT_PRIVATE, 1, NULL  $ netstat -np [...] tcp 0 0 127.0.0.1:42982 127.0.0.1:37528 CLOSE_WAIT -  

Wenn ich versuche, mich mit dem verwaisten Prozess zu verbinden gdb:

$ gdb -p 1993 Attaching to process 1993 (deleted): No such file or directory. 

Ich denke, weil der übergeordnete Prozess beendet wird. Die Sache ist, ich kann keine Verbindung zum verwaisten Prozess herstellen, um angerufen zu werden close(16u).

Wie kann ich die Situation "lösen"?

HINWEISE : Ich habe bereits versucht, den networkingDienst neu zu starten, aber es funktioniert nicht. Es ist ein Ubuntu Server 14.04 (VirtualBox), und ich verbinde mich mit ssh mit meinem Rechner. Es gibt keinen Netzwerkmanager.

Ich habe versucht ifdown, ifupauf jedes Interface (eth0, eth1, lo y virbr) anzuwenden, aber sie schließen den Socket nicht.

0

1 Antwort auf die Frage

1
MariusMatutiae

Es gibt keinen einfachen Weg. Erstens hat dies nichts mit Vernetzung zu tun : CLOSE_WAIT ist der Status, in den Ihr untergeordneter Prozess eingeht, nachdem Sie mit einem ACK auf ein FIN- Paket geantwortet haben, und bevor der Socket geschlossen und ein FIN- Paket an seinen Peer gesendet wird. Während des CLOSE_WAIT- Status führt der Prozess eine Operation aus, an deren Ende er close () aufruft, wodurch der Kernel das FIN-Paket aussendet.

Mit anderen Worten, während des CLOSE_WAIT- Status versucht der Prozess, eine Operation abzuschließen und nicht auf etwas von einem Peer zu warten. Das Herunterfahren des Netzwerks, das erneute Starten von Schnittstellen usw. führt zu nichts.

Im großen und ganzen sollte dies an sich kein großes Problem sein: Es ist nichts falsch daran, wenn einige Prozesse in einem CLOSE_WAIT- Zustand hängen . Was Sie daran stört, ist schwer zu verstehen: Sie geben an, dass der übergeordnete Prozess Port 11000 abhört, und dann das untergeordnete Element an Port 37528 anrufen. Sie geben jedoch an, dass nach dem Tod des übergeordneten Prozesses keine neue Instanz des Servers gestartet werden kann der Port 11000 ist nicht freigegeben. Sie haben jedoch gerade erklärt, dass es nicht der Kindprozess ist, der ihn verwendet! Also wer ist

Jedenfalls gibt es nur ein paar Dinge, die Sie ausprobieren können.

  1. Haben Sie versucht, einen Prozess mit der Option -9 zu beenden? Es ist das Stärkste, das du brauen kannst.

  2. Sie können strace von Anfang an verwenden, um Systemaufrufe auch in den untergeordneten Prozessen (oder untergeordneten Prozessen?) Mithilfe von zu verfolgen

    strace -f YourParentProcess 

    Dies wird auch den * fork () * ed-Prozessen folgen.

  3. Meine Vermutung ist, dass Sie möglicherweise das Kind vergessen und herausfinden wollen, warum und von wem Port 11000 belegt ist. Sie sollten den Handier-Befehl versuchen

    ss -lntp | grep 11000 

    die Angelegenheit untersuchen.