La documentation du noyau Linux affirme :
Rootfs est une instance spéciale de ramfs (ou tmpfs, si elle est activée),
qui est toujours présente dans les systèmes 2.6. Vous ne pouvez pas démonter rootfs…
Sur tous les systèmes Linux que j'ai testés (noyau> 2.6 et procédure de démarrage normale, par exemple ubuntu 12.04), mount
n'affiche pas de rootfs
entrée.
Cependant, avec une image buildroot lors du démarrage avec un .cpio
externe archive, il est présent.
Dans quels cas y a-t-il un rootfs
entrée dans mount
?
Réponse acceptée :
- Sur les anciens systèmes,
mount
peut être en désaccord avec/proc/mounts
- La plupart du temps, vous ne verrez pas
rootfs
dans/proc/mounts
, mais il est toujours monté. - Pouvons-nous prouver que rootfs est toujours monté ?
1. Sur les anciens systèmes, mount
peut être en désaccord avec /proc/mounts
man mount
dit :"Les programmes mount
et umount
conservait traditionnellement une liste des systèmes de fichiers actuellement montés dans le fichier /etc/mtab
."
L'ancienne approche ne fonctionne pas vraiment pour le système de fichiers racine. Le système de fichiers racine peut avoir été monté par le noyau, pas par mount
. Par conséquent, les entrées pour /
dans le /etc/mtab
peut être assez artificiel et pas nécessairement synchronisé avec la liste actuelle des montages du noyau.
Je n'ai pas vérifié avec certitude, mais en pratique, je ne pense pas qu'un système utilisant l'ancien schéma initialise mtab
pour afficher une ligne avec rootfs
. (En théorie, si mount
affiche rootfs
dépendrait du logiciel qui a d'abord installé le mtab
fichier).
man mount
continue:"le vrai fichier mtab est toujours pris en charge, mais sur les systèmes Linux actuels, il est préférable d'en faire un lien symbolique vers /proc/mounts à la place, car un fichier mtab régulier maintenu dans l'espace utilisateur ne peut pas fonctionner de manière fiable avec les espaces de noms, les conteneurs et autres Linux avancé fonctionnalités."
mtab est converti en lien symbolique dans Debian 7 et dans Ubuntu 15.04.
1.1 Sources
Rapport Debian #494001 – « Debian-installer :/etc/mtab doit être un lien symbolique vers /proc/mounts avec Linux>=2.6.26 »
#494001 est résolu dans sysvinit-2.88dsf-14. Voir le message de clôture, daté du 14 décembre 2011. Le changement est inclus dans Debian 7 "Wheezy", publié le 4 mai 2013. (Il utilise sysvinit-2.88dsf-41).
Ubuntu a retardé ce changement jusqu'à sysvinit_2.88dsf-53.2ubuntu1. Cette page du journal des modifications indique que le changement entre "vivid", qui est le nom de code d'Ubuntu 15.04.
2. La plupart du temps, vous ne verrez pas rootfs
dans /proc/mounts
, mais il est toujours monté
Depuis Linux v4.17, cette documentation du noyau est toujours à jour. rootfs est toujours présent et ne peut jamais être démonté. Mais la plupart du temps, vous ne pouvez pas le voir dans /proc/mounts.
Vous pouvez voir rootfs si vous démarrez dans un shell initramfs. Si votre initramfs est dracut
, comme dans Fedora Linux, vous pouvez le faire en ajoutant l'option rd.break
à la ligne de commande du noyau. (Par exemple, dans le chargeur de démarrage GRUB).
switch_root:/# grep rootfs /proc/mounts
rootfs / rootfs rw 0 0
Lorsque dracut bascule le système vers le véritable système de fichiers racine, vous ne pouvez plus voir rootfs dans /proc/mounts. dracut peut utiliser soit switch_root
ou systemd
pour faire ça. Ces deux opérations suivent la même séquence d'opérations, qui sont conseillées dans la documentation liée du noyau.
Dans certains autres messages, les utilisateurs peuvent voir rootfs dans /proc/mounts après avoir quitté initramfs. Par exemple sur Debian 7 :‘Comment puis-je en savoir plus sur ‘rootfs’’. Je pense que cela doit être dû au fait que le noyau a changé la façon dont il affiche /proc/mounts, à un moment donné entre la version du noyau dans Debian 7 et mon noyau actuel v4.17. D'après d'autres recherches, je pense que rootfs est affiché sur Ubuntu 14.04, mais n'est pas affiché sur Ubuntu 16.04 avec le noyau Ubuntu 4.4.0-28-generic.
En relation :Linux – Que signifie la lettre « u » dans /dev/urandom ?Même si je n'utilise pas d'initramfs et que le noyau monte le système de fichiers racine à la place, je ne peux pas voir rootfs dans /proc/mounts. Cela a du sens car le code du noyau semble également suivre la même séquence d'opérations.
L'opération qui cache rootfs est chroot
.
switch_root:/# cd /sysroot
switch_root:/sysroot# mount --bind /proc proc
switch_root:/sysroot# grep rootfs proc/mounts
rootfs / rootfs rw 0 0
switch_root:/sysroot# chroot .
sh-4.4# cat proc/mounts
/dev/sda3 / ext4 ro,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
3. Pouvons-nous prouver que rootfs est toujours monté ?
Notoirement, un simple chroot
peut être échappé lorsque vous exécutez en tant qu'utilisateur privilégié. Si switch_root
n'a rien fait de plus que chroot
, nous pourrions l'inverser et revoir le rootfs.
sh-4.4# python3
...
>>> import os
>>> os.system('mount --bind / /mnt')
>>> os.system('cat proc/mounts')
/dev/sda3 / ext4 ro,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
/dev/sda3 /mnt ext4 ro,relatime 0 0
>>> os.chroot('/mnt')
>>>
>>> # now the root, "/", is the old "/mnt"...
>>> # but the current directory, ".", is outside the root :-)
>>>
>>> os.system('cat proc/mounts')
/dev/sda3 / ext4 ro,relatime 0 0
>>> os.chdir('..')
>>> os.system('bash')
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
bash-4.4# chroot .
sh-4.4# grep rootfs proc/mounts
rootfs / rootfs rw 0 0
Cependant, le switch_root
complet la séquence ne peut pas être inversée par cette technique. La séquence complète ne
-
Changer le répertoire de travail actuel (comme dans
/proc/self/cwd
), au point de montage du nouveau système de fichiers :cd /newmount
-
Déplacez le nouveau système de fichiers, c'est-à-dire modifiez son point de montage, afin qu'il se trouve directement au-dessus du répertoire racine.
mount --move . /
-
Changez le répertoire racine actuel (comme dans
/proc/self/root
) pour correspondre au répertoire de travail actuel.chroot .
Dans l'échappement chroot ci-dessus, nous avons pu traverser depuis le répertoire racine du ext4
système de fichiers vers rootfs
en utilisant ..
, car le ext4
filesystem a été monté sur un sous-répertoire de rootfs
. La méthode d'échappement ne fonctionne pas lorsque le ext4
le système de fichiers est monté sur la racine répertoire du rootfs.
J'ai pu trouver le rootfs
en utilisant une méthode différente. (Au moins un important développeur de noyau considère cela comme un bogue sous Linux).
http://archive.today/2018.07.22-161140/https://lore.kernel.org/lkml/[email protected]/
/* CURSED.c - DO NOT RUN THIS PROGRAM INSIDE YOUR MAIN MOUNT NAMESPACE */
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /* open() */
#include <sys/mount.h>
#include <sched.h> /* setns() */
#include <sys/statfs.h>
int main() {
int fd = open("/proc/self/ns/mnt", O_RDONLY);
/* "umount -l /" - lazy unmount everything we can see */
umount2("/", MNT_DETACH);
/* reset root, by re-entering our mount namespace */
setns(fd, CLONE_NEWNS);
/* "stat -f /" - inspect the root */
struct statfs fs;
statfs("/", &fs);
}
Testé sur Linux 4.17.3-200.fc28.x86_64 :
$ make CURSED
cc CURSED.c -o CURSED
$ sudo unshare -m strace ./CURSED
...
openat(AT_FDCWD, "/proc/self/ns/mnt", O_RDONLY) = 3
umount2("/", MNT_DETACH) = 0
setns(3, CLONE_NEWNS) = 0
statfs("/", {f_type=RAMFS_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID}) = 0
^
^ result: rootfs uses ramfs code on this system
(J'ai également confirmé que ce système de fichiers est vide comme prévu et accessible en écriture).