Comme décrit dans le journal de validation du noyau lié à jiliagre ci-dessus, le nsfs
filesystem est un système de fichiers virtuel rendant disponibles les espaces de noms du noyau Linux. Il est distinct du /proc
système de fichiers "proc", où certaines entrées du répertoire de processus font référence à des inodes dans le nsfs
système de fichiers afin de montrer quels espaces de noms un certain processus (ou thread) utilise actuellement.
Le nsfs
n'est pas répertorié dans /proc/filesystems
(tandis que proc
fait), il ne peut donc pas être monté explicitement. mount -t nsfs ./namespaces
échoue avec "type de système de fichiers inconnu". C'est, comme nsfs
car il est étroitement lié au proc
système de fichiers.
Le type de système de fichiers nsfs
ne devient visible que via /proc/$PID/mountinfo
lors du montage par liaison d'un lien de système de fichiers d'espace de noms existant (!) vers une autre cible. Comme Stephen Kitt le suggère à juste titre ci-dessus, il s'agit de maintenir les espaces de noms existants même si aucun processus ne les utilise plus.
Par exemple, créez un nouvel espace de noms utilisateur avec un nouvel espace de noms réseau, puis montez-le en liaison, puis quittez :l'espace de noms existe toujours, mais lsns
ne le trouvera pas, car il n'est pas répertorié dans /proc/$PID/ns
plus, mais existe en tant que point de montage (de liaison).
# 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
Le résultat devrait ressembler à celui-ci :
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]
Veuillez noter qu'il n'est pas possible de créer des espaces de noms via le système de fichiers nsfs, uniquement via le syscalls clone() (CLONE_NEW...
) et annuler le partage. Le nsfs
ne reflète que l'état actuel du noyau w.r.t. espaces de noms, mais il ne peut ni les créer ni les détruire.
Les espaces de noms sont automatiquement détruits chaque fois qu'il n'y a plus aucune référence à eux, aucun processus (donc pas de /proc/$PID/ns/...
) ET pas de montages liés non plus, comme nous l'avons exploré dans l'exemple ci-dessus.
C'est le "Name Space File System", utilisé par le setns
appel système et, comme le montre son code source, les ioctl liés à l'espace de noms (par exemple, NS_GET_USERNS
, NS_GET_OWNER_UID
...)
NSFS
les entrées de pseudo-fichiers étaient autrefois fournies par le /proc
système de fichiers jusqu'à Linux 3.19. Voici le commit de ce changement.
Voir le commentaire de Stephen Kitt sur une explication possible de la présence de ces fichiers.