GNU/Linux >> Tutoriales Linux >  >> Linux

Linux:¿por qué no hay un sistema de archivos Rootfs presente en el sistema?

La documentación del kernel de Linux afirma:

Rootfs es una instancia especial de ramfs (o tmpfs, si está habilitado),
que siempre está presente en los sistemas 2.6. No puedes desmontar rootfs...

En todos los sistemas Linux que probé (kernel> 2.6 y procedimiento de arranque normal afaik, por ejemplo, ubuntu 12.04), mount no muestra un rootfs entrada.

Sin embargo, con una imagen buildroot al arrancar con un .cpio externo archivo, está presente.

¿En qué casos hay un rootfs entrada en mount ?

Respuesta aceptada:

  1. En sistemas antiguos, mount puede no estar de acuerdo con /proc/mounts
  2. La mayoría de las veces no verá rootfs en /proc/mounts , pero todavía está montado.
  3. ¿Podemos probar que rootfs todavía está montado?

1. En sistemas antiguos, mount puede no estar de acuerdo con /proc/mounts

man mount dice:“Los programas mount y umount tradicionalmente mantenía una lista de los sistemas de archivos actualmente montados en el archivo /etc/mtab .”

El antiguo enfoque realmente no funciona para el sistema de archivos raíz. El sistema de archivos raíz puede haber sido montado por el kernel, no por mount . Por lo tanto, entradas para / en el /etc/mtab puede ser bastante artificial y no estar necesariamente sincronizado con la lista actual de montajes del kernel.

No lo he comprobado con seguridad, pero en la práctica no creo que ningún sistema que utilice el esquema anterior inicialice mtab para mostrar una línea con rootfs . (En teoría, si mount muestra rootfs dependería del software que primero instaló el mtab archivo).

man mount continúa:“el archivo mtab real todavía es compatible, pero en los sistemas Linux actuales es mejor convertirlo en un enlace simbólico a /proc/mounts, porque un archivo mtab normal mantenido en el espacio de usuario no puede funcionar de manera confiable con espacios de nombres, contenedores y otros Linux avanzados. características.”

mtab se convierte en un enlace simbólico en Debian 7 y en Ubuntu 15.04.

1.1 Fuentes

Informe de Debian n.° 494001 – “instalador de debian:/etc/mtab debe ser un enlace simbólico a /proc/mounts con linux>=2.6.26”

#494001 se resuelve en sysvinit-2.88dsf-14. Consulte el mensaje de cierre, fechado el 14 de diciembre de 2011. El cambio está incluido en Debian 7 "Wheezy", publicado el 4 de mayo de 2013. (Utiliza sysvinit-2.88dsf-41).

Ubuntu retrasó este cambio hasta sysvinit_2.88dsf-53.2ubuntu1. Esa página de registro de cambios muestra que el cambio ingresa "vívido", que es el nombre en clave de Ubuntu 15.04.

2. La mayoría de las veces no verá rootfs en /proc/mounts , pero todavía está montado

A partir de Linux v4.17, esta documentación del kernel aún está actualizada. rootfs siempre está presente y nunca se puede desmontar. Pero la mayoría de las veces no puede verlo en /proc/mounts.

Puede ver rootfs si arranca en un shell initramfs. Si su initramfs es dracut , como en Fedora Linux, puede hacer esto agregando la opción rd.break a la línea de comandos del kernel. (Por ejemplo, dentro del cargador de arranque GRUB).

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

Cuando dracut cambia el sistema al sistema de archivos raíz real, ya no puede ver rootfs en /proc/mounts. dracut puede usar switch_root o systemd para hacer esto. Ambos siguen la misma secuencia de operaciones, que se recomiendan en el documento del kernel vinculado.

En algunas otras publicaciones, las personas pueden ver rootfs en /proc/mounts después de desconectarse de initramfs. Por ejemplo en Debian 7:'¿Cómo puedo obtener información sobre "rootfs"'? Creo que esto debe ser porque el kernel cambió la forma en que muestra /proc/mounts, en algún momento entre la versión del kernel en Debian 7 y mi kernel v4.17 actual. De búsquedas posteriores, creo que rootfs se muestra en Ubuntu 14.04, pero no se muestra en Ubuntu 16.04 con Ubuntu kernel 4.4.0-28-generic.

Relacionado:Linux:¿Qué significa la letra 'u' en /dev/urandom?

Incluso si no uso un initramfs y hago que el kernel monte el sistema de archivos raíz, no puedo ver rootfs en /proc/mounts. Esto tiene sentido ya que el código del kernel también parece seguir la misma secuencia de operaciones.

La operación que oculta rootfs es 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. ¿Podemos probar que rootfs todavía está montado?

Notoriamente, un simple chroot se puede escapar cuando se está ejecutando como un usuario privilegiado. Si switch_root no hizo nada más que chroot , podríamos revertirlo y volver a ver 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

Sin embargo, el switch_root completo la secuencia no puede ser revertida por esta técnica. La secuencia completa sí

  1. Cambiar el directorio de trabajo actual (como en /proc/self/cwd ), al punto de montaje del nuevo sistema de archivos:

    cd /newmount
    
  2. Mueva el nuevo sistema de archivos, es decir, cambie su punto de montaje, para que quede directamente encima del directorio raíz.

    mount --move . /
    
  3. Cambiar el directorio raíz actual (como en /proc/self/root ) para que coincida con el directorio de trabajo actual.

    chroot .
    

En el escape chroot anterior, pudimos atravesar desde el directorio raíz de ext4 sistema de archivos de vuelta a rootfs usando .. , porque el ext4 el sistema de archivos se montó en un subdirectorio de rootfs . El método de escape no funciona cuando ext4 el sistema de archivos está montado en la raíz directorio de rootfs.

Pude encontrar el rootfs usando un método diferente. (Al menos un importante desarrollador del kernel piensa que esto es un error en 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);
}

Probado en 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

(También confirmé que este sistema de archivos está vacío como se esperaba y se puede escribir).


Linux
  1. Linux:¿cómo encontrar las implementaciones de las llamadas al sistema del kernel de Linux?

  2. Linux:¿por qué existe una política de kernel de Linux para nunca romper el espacio del usuario?

  3. ¿Por qué la función de cierre se llama release en `struct file_operations` en el kernel de Linux?

  4. ¿Por qué pr_debug del kernel de Linux no da ningún resultado?

  5. Linux:compruebe si hay una línea vacía al final de un archivo

Introducción al sistema de archivos de Linux

¿Linux es un sistema operativo o un kernel?

Elija el mejor sistema de archivos para su Linux

Linux:¿por qué el kernel no puede ejecutar Init?

Todo lo que necesita saber sobre el sistema de archivos de Linux

Comprender el archivo /etc/fstab en Linux