Die Linux-Kernel-Dokumentation behauptet:
Rootfs ist eine spezielle Instanz von ramfs (oder tmpfs, falls aktiviert),
die in 2.6-Systemen immer vorhanden ist. Sie können rootfs nicht unmounten …
Auf allen von mir getesteten Linux-Systemen (Kernel> 2.6 und afaik normaler Bootvorgang, z. B. Ubuntu 12.04), mount
zeigt kein rootfs
an Eintrag.
Allerdings mit einem buildroot-Image beim Booten mit einer externen .cpio
Archiv, es ist vorhanden.
In welchen Fällen gibt es ein rootfs
Eintrag in mount
?
Akzeptierte Antwort:
- Auf alten Systemen
mount
kann mit/proc/mounts
nicht übereinstimmen - Meistens werden Sie
rootfs
nicht sehen in/proc/mounts
, aber es ist immer noch gemountet. - Können wir beweisen, dass rootfs noch gemountet ist?
1. Auf alten Systemen mount
kann mit /proc/mounts
nicht übereinstimmen
man mount
sagt:„Die Programme mount
und umount
pflegte traditionell eine Liste der aktuell gemounteten Dateisysteme in der Datei /etc/mtab
.“
Der alte Ansatz funktioniert nicht wirklich für das Root-Dateisystem. Das Root-Dateisystem wurde möglicherweise vom Kernel gemountet, nicht von mount
. Daher Einträge für /
in /etc/mtab
kann ziemlich erfunden sein und nicht unbedingt mit der aktuellen Mountliste des Kernels synchron sein.
Ich habe es nicht genau überprüft, aber in der Praxis glaube ich nicht, dass ein System, das das alte Schema verwendet, mtab
initialisieren wird um eine Zeile mit rootfs
anzuzeigen . (Theoretisch, ob mount
zeigt rootfs
von der Software abhängen, die mtab
zuerst installiert hat Datei).
man mount
fährt fort:„Die echte mtab-Datei wird immer noch unterstützt, aber auf aktuellen Linux-Systemen ist es besser, stattdessen einen symbolischen Link zu /proc/mounts zu erstellen, da eine normale mtab-Datei, die im Userspace verwaltet wird, nicht zuverlässig mit Namespaces, Containern und anderen fortgeschrittenen Linuxen arbeiten kann Funktionen.“
mtab wird in Debian 7 und in Ubuntu 15.04 in einen Symlink umgewandelt.
1.1 Quellen
Debian-Bericht Nr. 494001 – „debian-installer:/etc/mtab muss ein symbolischer Link zu /proc/mounts mit Linux>=2.6.26 sein“
#494001 wird in sysvinit-2.88dsf-14 aufgelöst. Siehe die Abschlussnachricht vom 14. Dezember 2011. Die Änderung ist in Debian 7 „Wheezy“ enthalten, das am 4. Mai 2013 veröffentlicht wurde. (Es verwendet sysvinit-2.88dsf-41).
Ubuntu verzögerte diese Änderung bis sysvinit_2.88dsf-53.2ubuntu1. Diese Änderungsprotokollseite zeigt, dass die Änderung „lebendig“ eingeht, was der Codename für Ubuntu 15.04 ist.
2. Meistens werden Sie rootfs
nicht sehen in /proc/mounts
, aber es ist immer noch gemountet
Ab Linux v4.17 ist diese Kernel-Dokumentation immer noch aktuell. rootfs ist immer vorhanden und kann niemals ausgehängt werden. Aber meistens sieht man es nicht in /proc/mounts.
Sie können rootfs sehen, wenn Sie in eine initramfs-Shell booten. Wenn Ihr initramfs dracut
ist , wie in Fedora Linux, können Sie dies tun, indem Sie die Option rd.break
hinzufügen zur Kernel-Befehlszeile. (z. B. im GRUB-Bootloader).
switch_root:/# grep rootfs /proc/mounts
rootfs / rootfs rw 0 0
Wenn dracut das System auf das echte Root-Dateisystem umschaltet, können Sie rootfs nicht mehr in /proc/mounts sehen. dracut kann entweder switch_root
verwenden oder systemd
um dies zu tun. Beide folgen der gleichen Abfolge von Operationen, die in der verlinkten Kernel-Dokumentation empfohlen werden.
In einigen anderen Beiträgen können Leute rootfs in /proc/mounts sehen, nachdem sie aus dem initramfs gewechselt haben. Zum Beispiel bei Debian 7:„How can I find out about „rootfs““. Ich denke, das muss daran liegen, dass der Kernel geändert hat, wie er /proc/mounts anzeigt, irgendwann zwischen der Kernel-Version in Debian 7 und meinem aktuellen Kernel v4.17. Bei weiteren Suchen denke ich, dass rootfs auf Ubuntu 14.04 angezeigt wird, aber nicht auf Ubuntu 16.04 mit Ubuntu-Kernel 4.4.0-28-generic.
Siehe auch:Linux – Was bedeutet der Buchstabe „u“ in /dev/urandom?Selbst wenn ich kein initramfs verwende und den Kernel stattdessen das Root-Dateisystem mounten lasse, kann ich rootfs in /proc/mounts nicht sehen. Dies ist sinnvoll, da der Kernel-Code ebenfalls der gleichen Abfolge von Operationen zu folgen scheint.
Die Operation, die rootfs verbirgt, ist 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. Können wir beweisen, dass rootfs noch gemountet ist?
Bekanntermaßen eine einfache chroot
kann entgangen werden, wenn Sie als privilegierter Benutzer ausgeführt werden. Wenn switch_root
tat nichts anderes als chroot
, könnten wir es rückgängig machen und die rootfs wieder sehen.
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
Die vollständige switch_root
Reihenfolge kann durch diese Technik nicht umgekehrt werden. Die vollständige Sequenz tut es
-
Ändern Sie das aktuelle Arbeitsverzeichnis (wie in
/proc/self/cwd
), zum Einhängepunkt des neuen Dateisystems:cd /newmount
-
Verschieben Sie das neue Dateisystem, d. h. ändern Sie seinen Einhängepunkt, sodass es direkt über dem Stammverzeichnis liegt.
mount --move . /
-
Ändern Sie das aktuelle Root-Verzeichnis (wie in
/proc/self/root
) passend zum aktuellen Arbeitsverzeichnis.chroot .
Im obigen Chroot-Escape konnten wir vom Root-Verzeichnis von ext4
aus traversieren Dateisystem zurück zu rootfs
mit ..
, weil die ext4
Dateisystem wurde in einem Unterverzeichnis von rootfs
gemountet . Die Escape-Methode funktioniert nicht, wenn ext4
Dateisystem wird im Root gemountet Verzeichnis des rootfs.
Ich konnte das rootfs
finden mit einer anderen Methode. (Mindestens ein wichtiger Kernel-Entwickler hält dies für einen Fehler in 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);
}
Getestet auf 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
(Ich habe auch bestätigt, dass dieses Dateisystem wie erwartet leer und beschreibbar ist).