GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:perché non è presente alcun file system Rootfs sul sistema?

La documentazione del kernel Linux afferma:

Rootfs è un'istanza speciale di ramfs (o tmpfs, se abilitato),
che è sempre presente nei sistemi 2.6. Non puoi smontare rootfs...

Su tutti i sistemi Linux che ho testato (kernel> 2.6 e procedura di avvio normale afaik, ad esempio ubuntu 12.04), mount non mostra un rootfs voce.

Tuttavia, con un'immagine buildroot all'avvio con un .cpio esterno archivio, è presente.

In quali casi esiste un rootfs voce in mount ?

Risposta accettata:

  1. Sui vecchi sistemi, mount potrebbe non essere d'accordo con /proc/mounts
  2. Il più delle volte non vedrai rootfs in /proc/mounts , ma è ancora montato.
  3. Possiamo provare che rootfs è ancora montato?

1. Sui vecchi sistemi, mount potrebbe non essere d'accordo con /proc/mounts

man mount dice:“I programmi mount e umount tradizionalmente manteneva un elenco di filesystem attualmente montati nel file /etc/mtab ."

Il vecchio approccio non funziona davvero per il filesystem di root. Il filesystem di root potrebbe essere stato montato dal kernel, non da mount . Quindi voci per / nel /etc/mtab può essere abbastanza artificioso e non necessariamente sincronizzato con l'attuale elenco di mount del kernel.

Non ho verificato con certezza, ma in pratica non credo che nessun sistema che utilizza il vecchio schema inizializzerà mtab per mostrare una riga con rootfs . (In teoria, se mount mostra rootfs dipende dal software che ha installato per primo mtab file).

man mount continua:“il vero file mtab è ancora supportato, ma sugli attuali sistemi Linux è meglio renderlo un collegamento simbolico a /proc/mounts, perché un normale file mtab mantenuto nello spazio utente non può funzionare in modo affidabile con namespace, container e altri Linux avanzati caratteristiche."

mtab viene convertito in un collegamento simbolico in Debian 7 e in Ubuntu 15.04.

1.1 Fonti

Debian report #494001 – "debian-installer:/etc/mtab deve essere un collegamento simbolico a /proc/mounts con linux>=2.6.26"

#494001 è stato risolto in sysvinit-2.88dsf-14. Vedi il messaggio di chiusura, datato 14 dicembre 2011. La modifica è inclusa in Debian 7 “Wheezy”, rilasciata il 4 maggio 2013. (Utilizza sysvinit-2.88dsf-41).

Ubuntu ha ritardato questa modifica fino a sysvinit_2.88dsf-53.2ubuntu1. Quella pagina del registro delle modifiche mostra che la modifica entra in "vivid", che è il nome in codice di Ubuntu 15.04.

2. La maggior parte delle volte non vedrai rootfs in /proc/mounts , ma è ancora montato

A partire da Linux v4.17, questa documentazione del kernel è ancora aggiornata. rootfs è sempre presente e non può mai essere smontato. Ma la maggior parte delle volte non puoi vederlo in /proc/mounts.

Puoi vedere rootfs se avvii in una shell initramfs. Se il tuo initramfs è dracut , come in Fedora Linux, puoi farlo aggiungendo l'opzione rd.break alla riga di comando del kernel. (Ad esempio all'interno del boot loader di GRUB).

switch_root:/# grep rootfs /proc/mounts
rootfs / rootfs rw 0 0

Quando dracut passa il sistema al filesystem root reale, non puoi più vedere rootfs in /proc/mounts. dracut può usare sia switch_root o systemd per farlo. Entrambi seguono la stessa sequenza di operazioni, che sono consigliate nel documento del kernel collegato.

In alcuni altri post, le persone possono vedere rootfs in /proc/mounts dopo essere usciti da initramfs. Ad esempio su Debian 7:'Come posso scoprire "rootfs"'. Penso che questo debba essere dovuto al fatto che il kernel ha cambiato il modo in cui mostra /proc/mounts, ad un certo punto tra la versione del kernel in Debian 7 e il mio attuale kernel v4.17. Da ulteriori ricerche, penso che rootfs sia mostrato su Ubuntu 14.04, ma non su Ubuntu 16.04 con il kernel Ubuntu 4.4.0-28-generico.

Correlati:Linux – Cosa significa la lettera 'u' in /dev/urandom?

Anche se non uso un initramfs e ho invece il kernel di montare il filesystem di root, non riesco a vedere rootfs in /proc/mounts. Questo ha senso poiché anche il codice del kernel sembra seguire la stessa sequenza di operazioni.

L'operazione che nasconde rootfs è 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. Possiamo provare che rootfs è ancora montato?

Notoriamente, un semplice chroot può essere eseguito l'escape durante l'esecuzione come utente privilegiato. Se switch_root non ha fatto altro che chroot , potremmo invertirlo e vedere di nuovo i 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

Tuttavia, il completo switch_root sequenza non può essere invertita con questa tecnica. L'intera sequenza lo fa

  1. Cambia la directory di lavoro corrente (come in /proc/self/cwd ), al punto di montaggio del nuovo filesystem:

    cd /newmount
    
  2. Sposta il nuovo filesystem, cioè cambia il suo punto di montaggio, in modo che si trovi direttamente sopra la directory principale.

    mount --move . /
    
  3. Cambia la directory principale corrente (come in /proc/self/root ) in modo che corrisponda alla directory di lavoro corrente.

    chroot .
    

Nell'escape chroot sopra, siamo stati in grado di attraversare dalla directory principale di ext4 filesystem torna a rootfs usando .. , perché ext4 filesystem è stato montato in una sottodirectory di rootfs . Il metodo escape non funziona quando ext4 il filesystem è montato sulla root directory dei rootfs.

Sono riuscito a trovare il rootfs utilizzando un metodo diverso. (Almeno un importante sviluppatore del kernel lo considera un bug in Linux).

http://archive.today/2018.07.22-161140/https://lore.kernel.org/lkml/[email protetta]/

/* 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);
}

Testato su 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

(Ho anche confermato che questo filesystem è vuoto come previsto e scrivibile).


Linux
  1. Linux:con quale frequenza viene aggiornato il file system Proc su Linux?

  2. Linux:perché esiste una politica del kernel Linux per non rompere mai lo spazio utente?

  3. Linux:perché il kernel non può eseguire Init?

  4. Perché la funzione di chiusura si chiama release in `struct file_operations` nel kernel di Linux?

  5. Perché pr_debug del kernel Linux non fornisce alcun output?

Introduzione al file system Linux

Linux è un sistema operativo o un kernel?

Scegli il miglior file system per il tuo Linux

Linux:come trovare le implementazioni delle chiamate di sistema del kernel Linux?

Tutto ciò che devi sapere sul file system Linux

Comprendere il file /etc/fstab in Linux