sistema de archivos raíz btrfs en raspbian

11

Pensé que podría experimentar con btrfs como la partición raíz para ver cómo maneja la corrupción de archivos durante los cortes de energía. Pero no puedo hacer que arranque.

Lo que hice:

  1. en el PI antes de cambiar:

    apt-get install btrfs-tools 2. Desde una computadora Linux:

    btrfs-convert / dev / sda2

  2. A /etc/fstabcambio ext4debtrfs

  3. A /cmdline.txtcambio ext4debtrfs

Me da pánico en el kernel si intento hacer el arranque. ¿Debo hacer algo más?

GuySoft
fuente

Respuestas:

7

Si btrfs se compila como un módulo de kernel, entonces debe crear un initramfs para cargar el módulo en el arranque. En Raspian (y otros derivados de Debian), update-initramfses el método más fácil para hacer esto.

Si initramfs-toolsestá instalado, cada vez que apt-getinstale un nuevo núcleo, debería activarse update-initramfsautomáticamente.

sudo apt-get update
sudo apt-get install initramfs-tools

Sin embargo, si utiliza rpi-updatepara instalar un nuevo núcleo, deberá ejecutarlo update-initramfsmanualmente antes de reiniciar en el nuevo núcleo:

sudo update-initramfs -u -k <kernel-version>

Esto creará o actualizará initramfs en /boot/initrd.img-<kernel-version>.

El último paso es agregarlo a su configuración de arranque: agregue la siguiente línea a /boot/config.txt:

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>debe coincidir exactamente con el nombre del archivo en /boot.

Tendrá que repetir estos pasos cada vez que corra rpi-update.

bennettp123
fuente
2

Mi prueba rápida muestra que el soporte de btrfs está construido como un módulo externo en raspbian, no vinculado directamente al núcleo.

Eso significa que el núcleo debe poder cargar ese módulo (que está almacenado en el sistema de archivos raíz) antes de que sepa cómo montar el sistema de archivos raíz. Obviamente, esto no funciona.

Enfoque 1:

Cree su propio núcleo y modifique su configuración de compilación para preenlazar btrfs. Ajustar la configuración es fácil si has descubierto cómo construir y cargar tu propio núcleo.

Enfoque 2:

Reajuste las cosas para que el núcleo y los módulos estén en un sistema de archivos ext4 y los datos que más desea comprimir estén en una partición btrfs.

Enfoque 2A:

Deje la partición raíz como ext4 y cree una nueva partición basada en btrfs, pero eso no ayuda a reducir la instalación del sistema operativo (si ese es su objetivo).

Enfoque 2B:

Cree una partición de arranque que sea pequeña y contenga el núcleo y los módulos, mientras deja todo lo demás en los btrfs. No tengo idea de cómo hacer esto para el cargador de arranque de un Pi, o cuáles son las limitaciones en torno a esto.

DonGar
fuente
¿Qué hay de copiar los módulos btrfs a la partición de arranque y cargarlos desde allí de antemano?
GuySoft
3
¿No es posible también comenzar con un initrd.img?
Anders
Sí, ¡y initrd.img parece la forma más fácil de resolverlo! Nunca lo he usado. Busque documentos en "mkinitrd".
DonGar
Hmm parece que CONFIG_BLK_DEV_INITRD no está habilitado en la última versión de Raspbian. Esto significa que necesita volver a compilar el núcleo para habilitar el soporte de initd.
GuySoft
1
Consulte paxswill.com/blog/2013/11/04/encrypted-raspberry-pi : allí initramfs se utiliza para permitir la raíz encriptada. Del mismo modo, se necesita soporte para cryptsetup (aquí btrfs) antes de que la raíz esté disponible.
Rbjz
1

Para que encuentre mi partición raíz BTRFS externa, necesitaba especificar explícitamente el UUID de la partición raíz en la partición de arranque cmdline.txt. Por ejemplo:

dwc_otg.lpm_enable = 0 console = tty1 root = PARTUUID = 123e4567-e89b-12d3-a456-426655440000 rootfstype = btrfs elevator = fecha límite rootwait quiet splash

Puede determinar el UUID de la partición BTRFS usando lsblk -f.

Geremia
fuente
1

El núcleo de Raspbian no incluye soporte btrfspor defecto; las etapas iniciales de arranque se ejecutan normalmente, pero cuando se carga el kernel, no verá ningún sistema de archivos que pueda montar, y entra en pánico. Existe una solución: agregue btrfs como un módulo del núcleo, en initramfs. En gran parte gracias a tres artículos diferentes , lo he configurado así:

  • Instale los paquetes necesarios: el módulo del núcleo y las herramientas para actualizar initramfs con él: sudo apt install btrfs-tools initramfs-tools
  • Dígale a initramfs que cargue el módulo btrfs (debería estar sucediendo automáticamente, por alguna razón, no funcionó en mi RPi1) - agregue una línea con "btrfs" a la lista de módulos requeridos: echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • Crear un gancho initramfs (para construir la imagen) y un script (para arrancar) para btrfs: se proporcionan valores predeterminados, pero en mis pruebas, no se usaron automáticamente, tuvieron que copiarlos en / etc. sudo mkdir -p /etc/initramfs-tools/hooks ; sudo mkdir -p /etc/initramfs-tools/scripts/local-premount ; sudo cp /usr/share/initramfs-tools/hooks/btrfs /etc/initramfs-tools/hooks ; sudo cp /usr/share/initramfs-tools/scripts/local-premount/btrfs /etc/initramfs-tools/scripts/local-premount; sudo chmod +x /etc/initramfs-tools/hooks/btrfs /etc/initramfs-tools/scripts/local-premount/btrfs
  • Cree ( -c) los nuevos initramfs para la versión actual del kernel (uname -r): si está actualizando uno existente, deberá usar update ( -u) en su lugar. Esto creará un archivo llamado como /boot/initrd.img-*, donde * es la versión actual del kernel. Tenga en cuenta el nombre generado (el script lo generará), lo usaremos en el siguiente paso.update-initramfs -c -k $(uname -r)
  • Edite /boot/config.txtpara usar este initramfs, agregando initramfs initrd.img-3.11.0+ followkernelEl nombre del archivo no tiene ruta, es el generado en el paso anterior; "followkernel" controla la ubicación en la memoria ( documentación de config.txt ).
  • Eso resuelve el núcleo actual, pero como señaló @Ingo, actualizar el núcleo rompería el sistema. Para solucionar esto, utilicé sus scripts de enlace de instalación de kernel :

    • Edite / etc / default / raspberrypi-kernel y descomente INITRD=Yes
    • Eliminar /etc/kernel/postinst.d/initramfs-tools
    • añadir RPI-initramfs-herramientas a /etc/kernel/postinst.d/ y chmod +xse
    • opcionalmente, descargue update-rpi-initramfs para actualizaciones manuales más simples de initramfs.
  • En este punto, tenemos un sistema que podría usar btrfs como dispositivo raíz. Pruebe reiniciando: el sistema aún se iniciará desde la partición ext4 (o lo que esté en su /boot/cmdline.txt ), pero dmesg | grep -i btrfsahora debería mostrar una línea que contiene "Btrfs cargado". Ahora necesitamos hacer y usar una partición btrfs.

  • Haga una copia de seguridad de la /partición (ext4), suponiendo que sea / dev / mmcblk0p2, normalmente: apague el RPi, saque la tarjeta SD, móntela en otro lugar (en este ejemplo sudo mount /dev/mmcblk0p2 /mnten una computadora Linux) y archive el contenido; tenga en cuenta que debe usar una herramienta que conserve la propiedad y los permisos, por ejemplo, tar: cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *(y luego desmonte la tarjeta SD nuevamente)

  • Cree una partición btrfs en alguna parte: he reutilizado la tarjeta SD, reemplazando la partición ext4 (/ dev / mmcblk0p2); Si está buscando crear una matriz btrfs-raid, este es el momento de hacerlo ( es uno de los argumentos de mkfs.btrfs , más allá del alcance de esta respuesta):mkfs.btrfs /dev/mmcblk0p2
  • Monte la partición btrfs y restaure la copia de seguridad en ella: sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • Edite fstab en la partición btrfs :sudo nano /mnt/etc/fstab

Debería haber una fila similar a esta:

/dev/mmcblk0p2  / ext4 foo,bar,baz 0 1

Cámbielo a esto (el nuevo tipo de FS es btrfs y usa las opciones predeterminadas):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • ¡Desmonta la partición, pero todavía no quites la tarjeta SD! sudo umount /mnt
  • Necesitamos decirle al RPi que va a arrancar desde btrfs
  • Encuentre el UUID de su nueva partición btrfs: busque la línea con / dev / mmcblk0p2 y copie la parte UUID =, con el (¡no UUID_SUB, no PARTUUID! Eso provocaría un error en el gestor de arranque, y el núcleo no arrancaría) .):sudo blkid

    / dev / mmcblk0p2: UUID = "cafebeef-0000-1234-aaaa-12346589" UUID_SUB = "ababccdd-2345-cafe-beee-587989991110" TYPE = "btrfs" PARTUUID = "beef0bee-02"

  • Monte la partición de arranque (FAT32): sudo mount /dev/mmcblk0p1 /mnt

  • Editar cmdline.txt: sudo nano /mnt/cmdline.txt

Encuentra estos dos parámetros

 root=PARTUUID=1234-5678 rootfstype=ext4

Y reemplazar con

 root=UUID=cafebeef-0000-1234-aaaa-12346589 rootfstype=btrfs

Tenga en cuenta que el UUID es el que copiamos anteriormente, solo sin comillas.

  • Desmontar la partición de arranque RPi: sudo umount /mnt
  • Vuelva a colocar la tarjeta SD en RPi y arranque.
  • En el RPi, vea que realmente está ejecutando desde un montaje raíz btrfs: mount

    / dev / mmcblk0p2 en / type btrfs (rw, space_cache, subvol = /)

  • Et voilà! No es solo apuntar y hacer clic, pero al estar de pie sobre los hombros de gigantes, podría hacer que funcione. ( También convirtió esto en un repositorio ).

Piskvor salió del edificio
fuente
1
Con el primero, sudo apt upgradesi también actualiza el núcleo, esta configuración fallará dramáticamente en el arranque porque el nuevo núcleo intenta cargar los viejos initramfs que fallarán y el núcleo no puede cargar los controladores btrfs. Y no es una manera fácil de arreglarlo, al menos con un chrootsistema armhf.
Ingo
¿No se invocaría update-initramfs en la actualización del kernel?
Piskvor dejó el edificio
1
No, el Raspbian predeterminado no puede generar un nuevo initramfs. No está configurado para esto. Siempre debe monitorear con los ojos lo que apt upgradeestá haciendo y generar un initramfs a mano si es necesario, antes de iniciar el nuevo kernel. No es una tarea factible para un principiante porque fallar es dramático. Puede echar un vistazo a ¿Cómo puedo usar un disco de inicio (initramfs) en el arranque de Raspberry Pi?
Ingo
1
Tiene un pequeño error que acabo de encontrar pero que aún no he solucionado. El núcleo admite dos modelos, por ejemplo, 4.14.98+y 4.14.98-v7+. Si update-initramfs es activado por una actualización del núcleo, generará dos initrd.img *, uno para cada modelo. Esto no cabe en la /bootpartición (error - sin espacio) y la generación no termina.
Ingo
1
Considero usar MODULES=list.
Ingo