¿Cómo saber si algún proceso está vinculado a un socket de dominio Unix?
Estoy escribiendo un servidor de socket de dominio Unix para Linux.
Una peculiaridad de los sockets de dominio de Unix que descubrí rápidamente es que, al crear un socket de Unix que escucha, crea la entrada del sistema de archivos correspondiente, cerrar el socket no lo elimina. Además, hasta que la entrada del sistema de archivos se elimine manualmente, no es posiblebind()
un zócalo a la misma ruta de nuevo:bind()
falla conEADDRINUSE
si la ruta que se proporciona ya existe en el sistema de archivos.
omo consecuencia, la entrada del sistema de archivos del socket debe serunlink()
'ed en el apagado del servidor para evitar obtenerEADDRINUSE
en el reinicio del servidor. Sin embargo, esto no siempre se puede hacer (es decir: bloqueo del servidor). La mayoría de las preguntas frecuentes, publicaciones en foros, sitios web de preguntas y respuestas que encontré solo aconsejan, como solución alternativa, aunlink()
el zócalo antes de llamar abind()
. Sin embargo, en este caso, es deseable saber si un proceso está vinculado a este socket antes deunlink()
'ing.
En efecto,unlink()
'en un socket Unix mientras un proceso todavía está vinculado a él y luego volver a crear el socket de escucha no genera ningún error. Como resultado, sin embargo, el antiguo proceso del servidor todavía se está ejecutando pero es inalcanzable: el socket de escucha antiguo está "enmascarado" por el nuevo. Este comportamiento tiene que ser evitado.
Idealmente, usando sockets de dominio Unix, la API de socket debería haber expuesto el mismo comportamiento de "exclusión mutua" que se expone al vincular sockets TCP o UDP: " Quiero vincular el socket S a la dirección A; si un proceso ya está vinculado a esta dirección, ¡solo quejarse!" Por desgracia, este no es el caso..
¿Hay alguna forma de hacer cumplir este comportamiento de "exclusión mutua"? O, dada una ruta del sistema de archivos, ¿hay alguna manera de saberlo,ví la API de socket, si algún proceso en el sistema tiene un socket de dominio Unix vinculado a esta ruta? ¿Debo usar una primitiva de sincronización externa a la API de socket flock()
, ...)? O me estoy perdiendo algo
Gracias por tus sugerencias.
Nota: los sockets Unix del espacio de nombres abstracto de Linux parecen resolver este problema, ya que no hay una entrada del sistema de archivos enunlink()
. Sin embargo, el servidor que estoy escribiendo pretende ser genérico: debe ser robusto contra ambos tipos de sockets de dominio Unix, ya que no soy responsable de elegir las direcciones de escucha.