¿Montar un sistema de archivos de solo lectura y redirigir las escrituras a la RAM?

Respuestas:

18

Es posible usar una capa de sistema de archivos de unión como aufs .

Manifestación:

Crear una imagen del sistema de archivos

# dd if=/dev/zero of=/tmp/image bs=1024 count=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.0028428 s, 369 MB/s
# mke2fs /tmp/image 
...

Montarlo, poblarlo

# mkdir /tmp/imgmnt
# mount -o loop /tmp/image /tmp/imgmnt
# echo hello > /tmp/imgmnt/hello.txt
# umount /tmp/imgmnt

Montarlo solo lectura

# mount -o loop,ro /tmp/image /tmp/imgmnt
# echo blah > /tmp/imgmnt/hello.txt 
-su: /tmp/imgmnt/hello.txt: Read-only file system

Un pequeño sistema de archivos RAM

# mkdir /tmp/rammnt
# mount -t tmpfs -o size=1M none /tmp/rammnt

Combinar ambos

# mkdir /tmp/combined
# mount -t aufs -o br:/tmp/rammnt:/tmp/imgmnt=ro none /tmp/combined

Esa opción de montaje para crear una nueva "rama" ( br) apilando /tmp/rammnt(lectura-escritura) encima de /tmp/imgmnt(solo lectura). Esta "rama" se hace visible como un sistema de archivos (lectura-escritura) en /tmp/combined.

(Consulte la página del comando man aufs (5) para obtener todos los detalles).

Ahora todo lo que está hecho, esto es lo que tienes:

# ls /tmp/combined
hello.txt  lost+found
# cat /tmp/combined/hello.txt 
hello
# echo bye > /tmp/combined/hello.txt 
# cat /tmp/combined/hello.txt 
bye

# cat imgmnt/hello.txt 
hello
# cat rammnt/hello.txt 
bye

Por lo tanto, las escrituras "stop" en el tmpfssistema de archivos, no intentan propagarse de nuevo al archivo de imagen montado en bucle.

Podría haber utilizado un directorio simple (en un sistema de archivos de lectura / escritura), o posiblemente un directorio debajo /dev/shmsi eso funciona para usted, en lugar de crear un específico tmpfspara eso.


Esta técnica (o variaciones de la misma) es utilizada por alguna distribución LiveCD. La entrada de Wikipedia aufs enumera algunos.

Estera
fuente
+1 gracias! Una pregunta: (1) ¿es posible hacer esto con fstabel punto de montaje /? (es decir, por lo que el sistema arranca desde una imagen descartable, más o menos.)
Mehrdad
No lo creo. Si quieres hacer eso por /, creo que estás mejor con un initrd (creo que así es como se hace para livecds). Es posible que pueda hacerlo desde un script de inicio, aunque eso suena complicado.
Mat
8

Actualizar:

Parece que hay otras 2 formas más simples de hacer esto en Ubuntu (al menos las versiones posteriores):

  1. sudo apt-get install overlayrootseguido de establecer overlayroot="tmpfs:swap=1,recurse=0"en/etc/overlayroot.local.conf .

  2. sudo apt-get install fsprotectseguido de pasar fsprotectcomo un parámetro del núcleo


¡Finalmente descubrí cómo hacer esto con el sistema de archivos raíz (en Ubuntu 11.04)!

Los pasos para hacer un sistema arrancable son simples. Utilicé esta guía en combinación con esta guía y un montón de búsquedas web para descubrir cómo hacer que funcione correctamente, sin errores.

Resumen:

  1. Correr:

    sudo apt-get install fsprotect apparmor-utils
    
  2. Guarda esto en /etc/initramfs-tools/scripts/init-bottom/__rootaufs. No creo que el nombre realmente importe, pero el principio __podría usarse para hacer pedidos, por lo que si cambia el nombre, es posible que desee mantener los guiones bajos. (Esta es una copia de este archivo ).

    #!/bin/sh -e
    
    case $1 in
      prereqs)
        exit 0
        ;;
    esac
    
    for x in $(cat /proc/cmdline); do
      case $x in
        root=*)
          ROOTNAME=${x#root=}
          ;;
        aufs=*)
          UNION=${x#aufs=}
        case $UNION in
          LABEL=*)
            UNION="/dev/disk/by-label/${UNION#LABEL=}"
            ;;
          UUID=*)
            UNION="/dev/disk/by-uuid/${UNION#UUID=}"
            ;;
        esac    
          ;;
      esac
    done
    
    if [ -z "$UNION" ]; then
        exit 0
    fi
    
    # make the mount points on the init root file system
    mkdir /aufs /ro /rw
    
    # mount read-write file system
    if [ "$UNION" = "tmpfs" ]; then
      mount -t tmpfs rw /rw -o noatime,mode=0755
    else
      mount $UNION /rw -o noatime
    fi
    
    # move real root out of the way
    mount --move ${rootmnt} /ro
    
    mount -t aufs aufs /aufs -o noatime,dirs=/rw:/ro=ro
    
    # test for mount points on union file system
    [ -d /aufs/ro ] || mkdir /aufs/ro
    [ -d /aufs/rw ] || mkdir /aufs/rw
    
    mount --move /ro /aufs/ro
    mount --move /rw /aufs/rw
    
    # strip fstab off of root partition
    grep -v $ROOTNAME /aufs/ro/etc/fstab > /aufs/etc/fstab
    
    mount --move /aufs /root
    
    exit 0
    
  3. En /etc/default/grub, encuentre la línea que comienza con GRUB_CMDLINE_LINUX_DEFAULT, y dentro de las comillas que siguen, agregue el parámetro aufs=tmpfs.

    Bonificación: si necesita desactivar ocasionalmente la redirección temporalmente, simplemente elimine este argumento de la lista de parámetros del kernel. Probablemente pueda hacer esto manteniendo presionada la tecla Mayús cuando el sistema se está iniciando, para mostrar el menú GRUB; luego presione e para editar los parámetros, y simplemente borre el aufs=...parámetro de la lista.

  4. Agregue estas líneas a /etc/sysctl.conf. ( Advertencia : riesgo potencial de seguridad).

    kernel.yama.protected_nonaccess_hardlinks = 0
    kernel.yama.protected_sticky_symlinks = 0
    
  5. Ejecute estas líneas:

    sudo aa-complain dhclient3
    sudo chmod 0755 /etc/initramfs-tools/scripts/init-bottom/__rootaufs
    sudo update-initramfs -k all -u
    sudo update-grub
    

Si todo salió bien, cuando reinicies, lo harás en un sistema de archivos temporal. La parte de RAM estará en /rw, y la imagen del disco estará en /ro, pero por supuesto será de solo lectura.

Sin embargo, si ha iniciado en un sistema temporal pero necesita hacer un cambio permanente, puede volver a montar el /rosistema de archivos diciendo

sudo mount -o remount,rw /ro

para que se pueda escribir, y luego puede realizar las modificaciones necesarias en ese directorio.

Mehrdad
fuente
2

Sí, por unionfs, ver unionfs.filesystems.org . Ha montado el primer sistema de archivos de solo lectura y como segundo sistema de archivos RAM de lectura y escritura a través de unionfs.

En Ubuntu puede encontrar el paquete unionfs-fuse, que es otra implementación de las mismas cosas, pero en el espacio del usuario, no como un módulo del núcleo.

Jan Marek
fuente
0

También puede hacer esto en el nivel del dispositivo, sin uniones como aufs. Ver dispositivo-mapper snapshot-origin.

Tor Klingberg
fuente