Explorons les *namespaces*
--------------------------

Maintenant que nous avons quelques notions de base sur les espaces de nom,
voyons quelles surprises nous réserve notre système...


### Voir les *namespace*s de notre système

La première commande que l'on va utiliser est `lsns(8)`, afin d'afficher tous
les *namespace*s actuels de notre machine.

<div lang="en-US">
```bash
42sh# lsns
        NS TYPE   NPROCS PID USER             COMMAND
4026531834 time   238      1 root             /sbin/init
4026531835 cgroup 238      1 root             /sbin/init
4026531836 pid    239      1 root             /sbin/init
4026531837 user   227      1 root             /sbin/init
4026531838 uts    231      1 root             /sbin/init
4026531839 ipc    228      1 root             /sbin/init
4026531840 net    228      1 root             /sbin/init
4026531841 mnt    223      1 root             /sbin/init
4026532230 uts      1    227 root             ├─/usr/lib/systemd/systemd-udevd
4026532483 mnt      4    366 root             ├─/usr/lib/systemd/systemd-userdbd
4026532485 mnt      1    363 systemd-resolve  ├─/usr/lib/systemd/systemd-resolved
4026532486 mnt      1    364 systemd-timesync ├─/usr/lib/systemd/systemd-timesyncd
4026532491 mnt      1    381 root             ├─/usr/lib/systemd/systemd-logind
4026532569 mnt      1    428 systemd-network  └─/usr/lib/systemd/systemd-networkd
4026531862 mnt      1     33 root             kdevtmpfs
[...]
```
</div>

Cette commande nous dévoile déjà de nombreuses choses :

- Chaque processus se trouve dans un *namespace* de chaque type : le noyau n'a
  pas de notion de « processus hôte » (sans *namespace*) et « processus
  contenerisé » (dans un *namespace*). Le processus initial de la machine se
  retrouve donc dans des espaces de nom, tout comme les processus d'un conteneur.

- On aperçoit un genre de hiérarchie dans certain cas.

- La première colonne nous renseigne sur l'identifiant du *namespace*.

- `kdevtmpfs` : un *thread* du noyau, s'exécute dans un espace de nom `mnt`
  dédié.


Vous verrez surement davantage de processus si vous exécutez cette commande sur
une machine que vous utilisez : chaque conteneur y sera bien entendu listé,
quelque soit la technologie sous-jacente (Docker, podman, CRI-O, snapd, ...),
mais chose plus étonnante, Chrome et Firefox tirent également parti des espaces
de nom pour de la défense en profondeur.


### Voir les *namespace*s d'un processus

Chaque processus lancé est donc rattaché à une liste d'espaces de nom, y
compris s'il est issu du système de base (« l'hôte »).

Nous pouvons dès lors consulter le dossier `/proc/<PID>/ns/` de chaque
processus, pour consulter les différents espaces de nom de nos processus.

Tous les processus ont la même liste de fichiers. Ils sont tous liés à un
espace de noms par *namespace* utilisable avec la version noyau dont on
dispose. D'une machine à l'autre, d'une version du noyau à l'autre, il est
normal d'avoir une liste de *namespace*s différente, mais d'un processus à
l'autre sur un même noyau, nous aurons les mêmes espaces de nom disponibles,
donc les mêmes fichiers.

Ces fichiers sont en fait des liens symboliques un peu particuliers, car ils ne
pointent pas vers une destination "valide" :

<div lang="en-US">
```bash
42sh$ ls -l /proc/self/ns
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 ipc    -> 'ipc:[4026531839]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 mnt    -> 'mnt:[4026531840]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 net    -> 'net:[4026532008]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 pid    -> 'pid:[4026531836]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 time   -> 'time:[4026531834]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 time_for_children -> 'time:[4026531834]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 user   -> 'user:[4026531837]'
lrwxrwxrwx 1 nemunaire 1 oct. 23:42 uts    -> 'uts:[4026531838]'
```
</div>

Les liens référencent une structure du noyau résidant en mémoire. Les numéros
entre crochets sont les *inodes* du système de fichiers `nsfs`, que l'on a pu
voir dans la première colonne de `lsns(8)`. Ce sont les identifiants des
espaces de nom.

Ces *inodes* seront les mêmes pour deux processus qui partagent le même espace
de noms : la structure pointée sera identique. Elle sera par contre différente
si l'espace de nom est différent, l'*inode* sera donc différent.


::::: {.question}

##### `*_for_children` {-}

Vous avez peut-être remarqué des fichiers `*_for_children` dans le dossier `ns`
de vos processus. Les espaces de noms *PID* et *Time*, lorsqu'on les change
pour un processus, ne s'appliquent pas directement au processus en cours
d'exécution, la dissociation de *namespace* ne pourra se faire que pour les
processus/threads fils.

`pid_for_children` et `time_for_children` représentent donc les *namespace*s
qui seront attribués aux processus fils lancés par un `clone(2)` ou un
`fork(2)`.

En attendant notre processus courant conserve ses espaces de nom `pid` et
`time`.

:::::
