Cerrar un socket que sigue esperando un proceso hijo, cuando el proceso padre ha sido eliminado

0

La situación es la siguiente:

  • Un servicio / proceso padre está conectado a un "puerto público" (el proceso padre es un servicio). Ese "puerto público" es 11000. Cuando llegan nuevas solicitudes al proceso primario desde el puerto 11000, el servidor envía esas solicitudes a un proceso secundario utilizando un puerto (socket) "privado". Ya sabes, la forma típica de implementar servidores.

  • El proceso padre se cierra pero el socket no está cerrado (todavía no sé el motivo).

  • El proceso huérfano está esperando que el socket esté cerrado y pkill no funciona (está en suspensión ininterrumpida).

  • No puedo volver a ejecutar el servidor porque el servidor dice que la dirección (0.0.0.0:11000) ya está en uso.

Entonces, tengo dos opciones, cerrar el "socket interno" para finalizar el proceso huérfano, o "liberar" de alguna manera la dirección / puerto 0.0.0.0:11000 para ejecutar el servidor nuevamente, y dejar el proceso huérfano en estado de espera. Lo importante es evitar reiniciar el servidor cada vez que falla, mientras investigo el problema.

Información útil sobre la situación (el pid del proceso hijo es 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)

Entonces, el puerto que quiero cerrar es 37528. El descriptor de archivo del socket correspondiente es 16u (o eso es lo que creo).

$ 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  -  

Si trato de conectarme al proceso huérfano por medio de gdb:

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

Porque el proceso de los padres es asesinado, creo. La cuestión es que no puedo conectarme al proceso huérfano para llamar close(16u).

¿Cómo puedo "resolver" la situación?

NOTAS : Ya he intentado reiniciar el networkingservicio, pero no funciona. Es un Ubuntu Server 14.04 (VirtualBox), y me conecto a mi máquina usando ssh. No hay administrador de red.

He intentado aplicar ifdown, ifupa cada interfaz (eth0, eth1, y lo virbr), pero no cierre el zócalo.

Peregring-lk
fuente

Respuestas:

1

No hay manera fácil. Primero, esto no tiene nada que ver con la creación de redes : CLOSE_WAIT es el estado en el que ingresa su proceso secundario después de responder a un paquete FIN con un ACK , y antes de cerrar el socket y enviar un paquete FIN a su par . Durante el estado CLOSE_WAIT , el proceso está completando una operación al final de la cual llamará a close () , lo que le indica al núcleo que envíe el paquete FIN.

En otras palabras, durante el estado CLOSE_WAIT , el proceso intenta completar alguna operación, sin esperar algo de un par; por lo tanto, cerrar la red, reiniciar las interfaces, etc., no logrará nada.

En general, esto no debería ser un gran problema per se : no hay nada de malo en tener algunos procesos colgando en un estado CLOSE_WAIT . Lo que le molesta de esto es difícil de entender: usted declara que el proceso padre escucha en el puerto 11000, luego se comunica con el niño en el puerto 37528, pero declara que, después de que el proceso padre ha muerto, no puede iniciar una nueva instancia del servidor porque el puerto 11000 no se libera. ¡Pero usted acaba de decir que no es el proceso hijo el que lo está usando! Entonces quien es?

En cualquier caso, hay algunas cosas que puedes probar;

  1. ¿Has intentado matar un proceso con la opción -9 ? Es lo más fuerte que puedes inventar.

  2. Puede usar strace desde el principio para rastrear las llamadas del sistema incluso en los procesos secundarios (¿o son procesos secundarios?), Mediante

    strace -f YourParentProcess
    

    Esto seguirá los procesos * fork () * ed también.

  3. Supongo que es muy posible que se olvide del niño e intente determinar por qué el puerto 11000 parece ocupado y por quién. Deberías probar el comando más práctico

    ss -lntp | grep 11000
    

    para investigar el asunto.

MariusMatutiae
fuente