Ya hice una pregunta sobre cómo enumerar todos los espacios de nombres en Linux, pero no hubo respuestas correctas y exactas, así que quiero encontrar un método que pueda ayudarme a encontrar el espacio de nombres de PID de algún proceso o grupo de procesos. ¿Cómo se puede hacer en Linux?
Respuesta aceptada:
Intentaré responder tanto a esta como a su pregunta anterior, ya que están relacionadas.
Las puertas a los espacios de nombres son archivos en /proc/*/ns/*
y /proc/*/task/*/ns/*
.
Un espacio de nombres es creado por un proceso dejar de compartir su espacio de nombres. Luego, un espacio de nombres se puede hacer permanente mediante bind-mounting los ns
archivo a algún otro lugar.
Eso es lo que ip netns
hace por ejemplo para net espacios de nombres Deja de compartir su net
espacio de nombres y montajes de enlace /proc/self/ns/net
a /run/netns/netns-name
.
En un /proc
montado en el espacio de nombres del pid raíz, puede enumerar todos los espacios de nombres que tienen un proceso haciendo lo siguiente:
# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]
El número entre corchetes es el número de inodo.
Para obtener eso para un proceso dado:
# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid
Ahora, puede haber permanente espacios de nombres que no tienen ningún proceso en ellos. Descubrirlos puede ser mucho más complicado AFAICT.
En primer lugar, hay que tener en cuenta que puede haber varios montaje espacios de nombres.
# awk '$9 == "proc" {print FILENAME,$0}' /proc/*/task/*/mountinfo | sort -k2 -u
/proc/1070/task/1070/mountinfo 15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/19877/task/19877/mountinfo 50 49 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 57 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/1070/task/1070/mountinfo 66 39 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 68 67 0:3 / /mnt/1/a rw,nosuid,nodev,noexec,relatime unbindable - proc proc rw
Esos /mnt/1/a
, /run/netns/a
pueden ser archivos de espacio de nombres.
Podemos obtener un número de inodo:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a
Pero eso no nos dice mucho más que no está en la lista calculada arriba.
Podemos intentar introducirlo como cualquiera de los diferentes tipos:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --pid=/mnt/1/a true
nsenter: reassociate to namespace 'ns/pid' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --mount=/mnt/1/a true
nsenter: reassociate to namespace 'ns/mnt' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --net=/mnt/1/a true
#
Bien, eso fue una net
archivo de espacio de nombres.
Así que parecería que tenemos un método para listar los espacios de nombres:list the ns
directorios de todas las tareas, luego busque todos los proc
puntos de montaje en todos los /proc/*/task/*/mountinfo
y descubra su tipo tratando de ingresarlos.