File system radice btrfs su raspbian


11

Ho pensato che avrei potuto esplodere con btrfs come partizione di root per vedere come gestisce la corruzione dei file durante le interruzioni di corrente. Ma non riesco ad avviarlo.

Cosa ho fatto:

  1. sul PI prima di passare:

    apt-get install btrfs-tools 2. Da un computer linux:

    btrfs-convert / dev / sda2

  2. In /etc/fstabcambio ext4abtrfs

  3. In /cmdline.txtcambio ext4abtrfs

Ottengo il panico del kernel se provo a fare il boot. Dovrei fare qualcos'altro?

Risposte:


7

Se btrfs viene compilato come modulo del kernel, è necessario creare un initramfs per caricare il modulo all'avvio. Su Raspian (e altri derivati ​​debian), update-initramfsè il metodo più semplice per farlo.

Se initramfs-toolsè installato, in qualsiasi momento apt-getinstalla un nuovo kernel, dovrebbe attivarsi update-initramfsautomaticamente.

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

Tuttavia, se si utilizza rpi-updateper installare un nuovo kernel, è necessario eseguire update-initramfsmanualmente prima di riavviare nel nuovo kernel:

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

Questo creerà o aggiornerà initramfs in /boot/initrd.img-<kernel-version>.

Il passaggio finale è aggiungerlo alla configurazione di avvio: aggiungere la seguente riga a /boot/config.txt:

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>deve corrispondere esattamente al nome del file in /boot.

Dovrai ripetere questi passaggi ogni volta che corri rpi-update.


2

Il mio test rapido mostra che il supporto di btrfs è costruito come modulo esterno in raspbian, non collegato direttamente al kernel.

Ciò significa che il kernel deve essere in grado di caricare quel modulo (che è memorizzato nel file system radice) prima di sapere come montare il file system radice. Ovviamente, questo non funziona.

Approccio 1:

Costruisci il tuo kernel e modifica la configurazione per precollegare btrfs. Modificare la configurazione è facile se hai capito come compilare e caricare il tuo kernel.

Approccio 2:

Regola di nuovo le cose in modo che kernel e moduli si trovino su un filesystem ext4 e che i dati che desideri maggiormente comprimere siano su una partizione btrfs.

Approccio 2A:

Lascia la partizione root come ext4 e crea una nuova partizione basata su btrfs, ma ciò non aiuta a ridurre l'installazione del sistema operativo (se questo è il tuo obiettivo).

Approccio 2B:

Crea una partizione di avvio che è piccola e contiene il kernel e i moduli, lasciando tutto il resto su btrfs. Non ho idea di come farlo per il bootloader di un Pi, o quali siano i limiti al riguardo.


Che ne dici di copiare i moduli btrfs nella partizione di avvio e caricarli da lì in anticipo?
GuySoft,

3
Non è anche possibile iniziare con un initrd.img?
Anders,

Sì, e initrd.img sembra il modo più semplice per risolverlo! Non l'ho mai usato. Cerca documenti su "mkinitrd".
DonGar,

Hmm sembra che CONFIG_BLK_DEV_INITRD non sia abilitato nell'ultima versione di Raspbian. Ciò significa che è necessario ricompilare il kernel per abilitare il supporto di initd.
GuySoft

1
Vedi paxswill.com/blog/2013/11/04/encrypted-raspberry-pi - Qui initramfs viene utilizzato per consentire il root crittografato. Allo stesso modo, è necessario il supporto per cryptsetup (qui btrfs) prima che root sia disponibile.
Rbjz,

1

Per farlo trovare la mia partizione root BTRFS esterna, dovevo specificare esplicitamente l' UUID della partizione root nella partizione di boot cmdline.txt. Per esempio:

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

È possibile determinare l'UUID della partizione BTRFS utilizzando lsblk -f.


1

Il kernel di Raspbian non include il supporto btrfsper impostazione predefinita; le fasi iniziali di avvio funzionano normalmente, ma quando il kernel si carica, non vedrà alcun filesystem che potrebbe montare - e panico. Esiste una soluzione: aggiungere btrfs come modulo kernel, in initramfs. In gran parte grazie a tre diversi articoli , l'ho impostato così:

  • Installa i pacchetti richiesti: il modulo del kernel e gli strumenti per aggiornare initramfs con esso: sudo apt install btrfs-tools initramfs-tools
  • Di 'a initramfs di caricare il modulo btrfs (dovrebbe accadere automagicamente, per qualche motivo, non ha funzionato sul mio RPi1) - aggiungi una riga con "btrfs" all'elenco dei moduli richiesti: echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • Crea un hook di initramfs (per la creazione dell'immagine) e uno script (per l'avvio) per btrfs: vengono forniti i valori predefiniti, ma nei miei test non sono stati utilizzati automagicamente, dovevo copiarli in / 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
  • Crea ( -c) il nuovo initramfs per l'attuale versione del kernel (uname -r) - se ne stai aggiornando uno esistente, dovrai invece usare update ( -u). Questo creerà un file chiamato come /boot/initrd.img-*, dove * è la versione corrente del kernel. Nota il nome generato (lo script lo produrrà), lo useremo nel prossimo passaggio.update-initramfs -c -k $(uname -r)
  • Modifica /boot/config.txtper usare questo initramfs, aggiungendo initramfs initrd.img-3.11.0+ followkernelIl nome del file è senza percorso, è quello generato nel passaggio precedente; "followkernel" controlla la posizione in memoria ( documentazione config.txt ).
  • Ciò risolve il kernel corrente, ma come sottolineato da @Ingo, l' aggiornamento del kernel spezzerebbe il sistema. Per risolvere questo problema, ho usato i suoi script hook per l'installazione del kernel :

    • Modifica / etc / default / raspberrypi-kernel e decomment INITRD=Yes
    • Elimina /etc/kernel/postinst.d/initramfs-tools
    • aggiungi rpi-initramfs-tools a /etc/kernel/postinst.d/ e chmod +xesso
    • facoltativamente, scarica update-rpi-initramfs per aggiornamenti manuali più semplici di initramfs.
  • A questo punto, abbiamo un sistema che potrebbe usare btrfs come dispositivo root. Test al riavvio: il sistema si avvierà comunque dalla partizione ext4 (o qualunque cosa sia nel tuo /boot/cmdline.txt ), ma dmesg | grep -i btrfsora dovrebbe mostrare una riga contenente "Btrfs caricato". Ora dobbiamo effettivamente creare e utilizzare una partizione btrfs.

  • Effettuare un backup della /partizione (ext4) - supponendo che sia / dev / mmcblk0p2 - in genere: spegnere RPi, estrarre la scheda SD, montarla da qualche altra parte (in questo esempio sudo mount /dev/mmcblk0p2 /mntsu un computer Linux) e archiviare il contenuto; si noti che è necessario utilizzare uno strumento che preserva la proprietà e le autorizzazioni, ad esempio tar: cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *(e quindi smontare di nuovo la scheda SD)

  • Crea una partizione btrfs da qualche parte - Ho riutilizzato la scheda SD, sostituendo la partizione ext4 (/ dev / mmcblk0p2); se stai cercando di creare un array btrfs-raid, questo è il momento di farlo ( è uno degli argomenti di mkfs.btrfs , oltre lo scopo di questa risposta):mkfs.btrfs /dev/mmcblk0p2
  • Montare la partizione btrfs e ripristinare il backup in essa: sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • Modifica fstab sulla partizione btrfs :sudo nano /mnt/etc/fstab

Dovrebbe esserci una riga simile a questa:

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

Modificalo in questo (il nuovo tipo di FS è btrfs e utilizza le opzioni predefinite):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • Smonta la partizione, ma non rimuovere ancora la scheda SD! sudo umount /mnt
  • Dobbiamo dire all'RPi che verrà avviato da btrfs
  • Trova l'UUID della tua nuova partizione btrfs - trova la linea con / dev / mmcblk0p2 e copia la parte UUID =, con (non UUID_SUB, non PARTUUID! Ciò causerebbe un bug nel bootloader e il kernel non si avvia .):sudo blkid

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

  • Montare la partizione di avvio (FAT32): sudo mount /dev/mmcblk0p1 /mnt

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

Trova questi due parametri

 root=PARTUUID=1234-5678 rootfstype=ext4

E sostituisci con

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

Si noti che l'UUID è quello che abbiamo copiato in precedenza, solo senza virgolette.

  • Smonta la partizione di avvio di RPi: sudo umount /mnt
  • Sostituisci la scheda SD in RPi e avvia.
  • Su RPi, vedi che stai effettivamente eseguendo un mount root di btrfs: mount

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

  • Et voilà! Non abbastanza punta e clicca, ma stando sulle spalle dei giganti, potrei farlo funzionare. (Trasformato anche questo in un repository .)


1
Con il primo sudo apt upgradese aggiorna anche il kernel, questa installazione fallirà drammaticamente all'avvio perché il nuovo kernel tenta di caricare i vecchi initramfs che falliranno e il kernel non può caricare i driver btrfs. E non è un modo semplice per risolverlo, almeno con un chrootsistema su un armhf.
Ingo,

Update-initramfs non verrebbe invocato all'aggiornamento del kernel?
Piskvor lasciò l'edificio il

1
No, Raspbian predefinito non riesce a generare un nuovo initramfs. Non è configurato per questo. Devi sempre monitorare con gli occhi cosa apt upgradesta facendo e, se necessario, generare un initramfs a mano, prima di avviare il nuovo kernel. Non è un compito fattibile per un principiante perché fallirlo è drammatico. Potresti dare un'occhiata a Come posso usare un init ramdisk (initramfs) all'avvio di Raspberry Pi?
Ingo,

1
Ha un piccolo bug che ho appena trovato ma non risolto finora. Il kernel supporta due modelli, ad esempio 4.14.98+e 4.14.98-v7+. Se update-initramfs viene attivato da un aggiornamento del kernel genererà due initrd.img *, uno per ciascun modello. Questo non si adatta alla /bootpartizione (errore - spazio esaurito) e la generazione non termina.
Ingo,

1
Considero di usare MODULES=list.
Ingo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.