1 puntos por GN⁺ 2024-07-03 | Aún no hay comentarios. | Compartir por WhatsApp
  • Es un experimento para arrancar Arch Linux usando Google Drive como sistema de archivos raíz en lugar de un disco local o NFS
  • En la etapa de initramfs, monta un sistema de archivos FUSE y crea con Dracut una imagen EFI personalizada con la red y los binarios necesarios
  • Primero validó el concepto con S3 y s3fs, y luego evitó los fallos de switch_root y pivot_root ejecutando chroot como PID 1
  • Al aplicar esto a Google Drive, usó google-drive-ocamlfuse, pero por limitaciones de enlaces simbólicos, enlaces duros, permisos y velocidad necesitó correcciones manuales y ajustes de timeout
  • Al final logró arrancar incluso en una laptop sin almacenamiento, usando un archivo EFI unificado en USB y un controlador de red por cable, aunque con poca utilidad práctica; aun así, muestra variantes posibles como una raíz sobre SSHFS o basada en Git

Usar Google Drive como sistema de archivos raíz

  • Tras ver un caso de arranque de Linux desde NFS, intentó algo más complicado: arrancar con una raíz en Google Drive
  • Como quería una estructura autosuficiente sin una máquina auxiliar separada, eligió FUSE, que funciona como un controlador de sistema de archivos en espacio de usuario
  • La condición clave era incluir en initramfs el programa FUSE y la configuración de red, montar el sistema de archivos raíz remoto y luego continuar con el arranque normal

En qué punto intervenir en el proceso de arranque de Linux

  • El flujo de arranque de Linux se divide, a grandes rasgos, en estas etapas
    • El firmware BIOS/UEFI inicia el cargador de arranque
    • El cargador de arranque carga el kernel
    • El kernel descomprime en RAM initramfs, un sistema de archivos temporal, y usa herramientas para montar el sistema de archivos real
    • El kernel cambia al sistema de archivos real y ejecuta el sistema init del nuevo sistema de archivos
  • Si se monta un sistema de archivos FUSE en la tercera etapa, se puede seguir arrancando usando el almacenamiento remoto como raíz

Prueba de concepto con S3 hecha con Dracut

  • Para generar un initramfs personalizado usó Dracut
  • Eligió Arch Linux como distribución base por ser relativamente ligera y familiar
  • En el módulo de Dracut incluyó binarios relacionados con FUSE como fusermount, fuseiso y mkisofs
  • Creó una imagen EFI con dracut.sh y la ejecutó en QEMU; tras una advertencia de que faltaba el parámetro root=, entró a una shell de depuración
  • En la shell de depuración realizó manualmente las tareas necesarias para el arranque
    • Cargó los controladores con modprobe fuse y modprobe e1000
    • Configuró la red con dhclient eth0 y ajustes de enrutamiento
    • Montó un bucket S3 local en /sysroot con s3fs

Fallo de switch_root y desvío con chroot

  • Aunque la raíz de Arch Linux aparecía en /sysroot, switch_root /sysroot /sbin/init fallaba con Input/output error
  • pivot_root tampoco se podía usar en el rootfs de initramfs, así que devolvía Invalid argument
  • Según una respuesta de Stack Exchange que consultó, en el rootfs de initramfs no se puede usar pivot_root ni desmontar, así que hay que superponer el nuevo root, hacer chroot y ejecutar init
  • Si en la shell simplemente se ejecutaba chroot /sysroot /sbin/init, systemd no arrancaba correctamente porque no era PID 1
  • Modificó init.sh de Dracut para incluir la configuración de red, el montaje con s3fs, los bind mounts de /sys, /dev y /proc, y al final ejecutar exec chroot /sysroot /sbin/init, con lo que logró arrancar desde una raíz en S3

Problema de DNS revelado en la raíz sobre S3

  • Tras arrancar, confirmó con mount que / estaba montado como tipo s3fs
  • Al ejecutar pacman -Sy fastfetch, fallaba porque no podía resolver hosts de mirrors de paquetes como geo.mirror.pkgbuild.com
  • Como el sistema de archivos raíz estaba en S3, pudo montar esa raíz desde otra máquina y entrar con chroot para instalar herramientas
  • systemd-resolved no arrancaba por un problema de permisos al conectar stdout al socket del journal, así que evitó el problema de DNS agregando nameserver 1.1.1.1 a /etc/resolv.conf

Migración a Google Drive

  • Como implementación FUSE para Google Drive usó google-drive-ocamlfuse
  • Creó secretos OAuth2 en su cuenta de Google, activó la API e instaló el paquete AUR en una VM de Arch Linux
  • Después de montar Google Drive, copió los archivos de Arch Linux al Drive con una larga tarea de rsync
  • En la raíz basada en Google Drive, las diferencias de comportamiento del sistema de archivos siguieron causando problemas
    • No funcionaban los enlaces simbólicos que apuntaban a otros enlaces simbólicos, lo que afectaba elementos relacionados con /usr/lib
    • Los enlaces duros no funcionaban
    • Los enlaces simbólicos relativos no funcionaban
    • No se permitían enlaces simbólicos rotos
    • No funcionaban los enlaces simbólicos que apuntaban fuera de Google Drive
    • Los permisos y atributos no funcionaban
    • La velocidad era muy baja
  • Para mantener la condición de no modificar ni el controlador FUSE ni el kernel, se basó en los logs de rsync fallido y creó manualmente enlaces simbólicos para resolverlo

Ajustes de initramfs para Google Drive

  • En initramfs incluyó el archivo de token generado en la laptop, el binario FUSE de Google Drive y certificados SSL
  • Añadió al imagen de Dracut archivos relacionados con /.gdfuse/default/config, /.gdfuse/default/state, /etc/ssl y /etc/ca-certificates
  • Al arrancar con una raíz en Google Drive aparecía chroot: /sbin/init: File not found
  • En Linux, aunque el archivo exista, si faltan bibliotecas dependientes o la ruta del enlazador dinámico, puede devolver File not found
  • Por el problema de los enlaces simbólicos relativos, el kernel terminaba buscando /sysroot/sysroot dentro de /sysroot; lo resolvió creando /sysroot/sysroot y haciendo un bind mount de /sysroot dentro de ese directorio
  • Incluso después de eso, el arranque seguía siendo muy lento
    • Regenerar la caché del enlazador dinámico tomaba unos 5 minutos
    • Cada unidad de systemd tardaba cerca de 1 minuto
    • El arranque se detenía por el timeout de espera de /dev/ttyS0
  • Configuró JobTimeoutSec=infinity en /etc/systemd/system/dev-ttyS0.device y cambió LOGIN_TIMEOUT a 0 en /etc/login.defs para evitar el timeout de inicio de sesión
  • Una vez acumulada la caché, la lectura de archivos pasó a ser menos lenta que al principio

Ejecución en una laptop sin almacenamiento

  • Probó arrancarlo en hardware real usando una laptop de repuesto sin almacenamiento
  • Cambió varios elementos de la configuración usada para QEMU para adaptarlos al hardware
    • Usó el controlador r8169 para el puerto Ethernet de la laptop en lugar del e1000 predeterminado
    • No usó pantalla serie
    • Cambió la configuración de red para ajustarla a la topología de su red doméstica
  • Usó Powerline en lugar de un cable Ethernet largo
  • Compiló un archivo EFI unificado, lo colocó en la ruta de arranque EFI de una unidad USB y arrancó la laptop desde ahí
  • Como no encontró la directiva modprobe para el teclado integrado, cargó hid_usb y configuró la red con un teclado externo
  • El resultado final fue una “Cloud Native Computer” que funciona con una raíz basada en Google Drive y sin almacenamiento local

Variantes posibles y limitaciones

  • Aunque el proyecto tiene un carácter claramente juguetón, el mismo enfoque permitiría arrancar Linux sobre SSHFS
  • Con gitfs también sería posible arrancar Linux desde un repositorio Git y rastrear los cambios en Git
  • Las posibilidades son muchas, pero la utilidad práctica es limitada
  • Como próximo experimento, se le ocurrió probar una instalación de Nix

Aún no hay comentarios.

Aún no hay comentarios.