GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux – Warum ist kein Rootfs-Dateisystem auf dem System vorhanden?

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:

  1. Auf alten Systemen mount kann mit /proc/mounts nicht übereinstimmen
  2. Meistens werden Sie rootfs nicht sehen in /proc/mounts , aber es ist immer noch gemountet.
  3. 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

  1. Ändern Sie das aktuelle Arbeitsverzeichnis (wie in /proc/self/cwd ), zum Einhängepunkt des neuen Dateisystems:

    cd /newmount
    
  2. Verschieben Sie das neue Dateisystem, d. h. ändern Sie seinen Einhängepunkt, sodass es direkt über dem Stammverzeichnis liegt.

    mount --move . /
    
  3. Ä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).


Linux
  1. Linux – Wie finde ich die Implementierungen von Linux-Kernel-Systemaufrufen?

  2. Linux – Warum kann der Kernel Init nicht ausführen?

  3. Warum heißt die Close-Funktion im Linux-Kernel in `struct file_operations` release?

  4. Warum gibt pr_debug des Linux-Kernels keine Ausgabe aus?

  5. Linux - Prüfen Sie, ob am Ende einer Datei eine leere Zeile steht

Einführung in das Linux-Dateisystem

Ist Linux ein Betriebssystem oder ein Kernel?

Wählen Sie das beste Dateisystem für Ihr Linux

Linux – Warum gibt es eine Linux-Kernel-Richtlinie, um den Benutzerbereich niemals zu unterbrechen?

Alles, was Sie über das Linux-Dateisystem wissen müssen

Verstehen der /etc/fstab-Datei unter Linux