Como se describe en el registro de confirmación del kernel vinculado por jiliagre arriba, el nsfs
filesystem es un sistema de archivos virtual que hace que los espacios de nombres del kernel de Linux estén disponibles. Está separado del /proc
sistema de archivos "proc", donde algunas entradas del directorio de procesos hacen referencia a inodos en el nsfs
sistema de archivos para mostrar qué espacios de nombres está utilizando actualmente un determinado proceso (o subproceso).
El nsfs
no aparece en /proc/filesystems
(mientras que proc
lo hace), por lo que no se puede montar explícitamente. mount -t nsfs ./namespaces
falla con "tipo de sistema de archivos desconocido". Esto es, como nsfs
ya que está estrechamente entrelazado con el proc
sistema de archivos.
El tipo de sistema de archivos nsfs
solo se vuelve visible a través de /proc/$PID/mountinfo
al montar un vínculo de sistema de archivos de espacio de nombres existente (!) a otro destino. Como Stephen Kitt sugiere acertadamente arriba, esto es para mantener los espacios de nombres existentes incluso si ningún proceso los usa más.
Por ejemplo, cree un nuevo espacio de nombres de usuario con un nuevo espacio de nombres de red, luego móntelo y luego salga:el espacio de nombres todavía existe, pero lsns
no lo encontrará, ya que no aparece en /proc/$PID/ns
más, pero existe como un punto de montaje (bind).
# bind mount only needs an inode, not necessarily a directory ;)
touch mynetns
# create new network namespace, show its id and then bind-mount it, so it
# is kept existing after the unshare'd bash has terminated.
# output: net:[##########]
NS=$(sudo unshare -n bash -c "readlink /proc/self/ns/net && mount --bind /proc/self/ns/net mynetns") && echo $NS
# notice how lsns cannot see this namespace anymore: no match!
lsns -t net | grep ${NS:5:-1} || echo "lsns: no match for net:[${NS:5:-1}]"
# however, findmnt does locate it on the nsfs...
findmnt -t nsfs | grep ${NS:5:-1} || echo "no match for net:[${NS:5:-1}]"
# output: /home/.../mynetns nsfs[net:[##########]] nsfs rw
# let the namespace go...
echo "unbinding + releasing network namespace"
sudo umount mynetns
findmnt -t nsfs | grep ${NS:5:-1} || echo "findmnt: no match for net:[${NS:5:-1}]"
# clean up
rm mynetns
La salida debe ser similar a esta:
net:[4026532992]
lsns: no match for net:[4026532992]
/home/.../mynetns nsfs[net:[4026532992]] nsfs rw
unbinding + releasing network namespace
findmnt: no match for net:[4026532992]
Tenga en cuenta que no es posible crear espacios de nombres a través del sistema de archivos nsfs, solo a través de syscalls clone() (CLONE_NEW...
) y dejar de compartir. El nsfs
solo refleja el estado actual del kernel w.r.t. espacios de nombres, pero no puede crearlos ni destruirlos.
Los espacios de nombres se destruyen automáticamente cuando no queda ninguna referencia a ellos, no hay procesos (por lo que no hay /proc/$PID/ns/...
) Y tampoco hay montajes de enlace, como hemos explorado en el ejemplo anterior.
Ese es el "Sistema de archivos de espacio de nombres", utilizado por el setns
llamada del sistema y, como muestra su código fuente, ioctl relacionados con el espacio de nombres (por ejemplo, NS_GET_USERNS
, NS_GET_OWNER_UID
...)
NSFS
las entradas de los pseudoarchivos solían ser proporcionadas por el /proc
sistema de archivos hasta Linux 3.19. Aquí está el compromiso de este cambio.
Vea el comentario de Stephen Kitt sobre una posible explicación sobre la presencia de estos archivos.