btrfs root Dateisystem auf raspbian


11

Ich dachte, ich könnte mit btrfs als Root-Partition experimentieren, um zu sehen, wie es die Dateibeschädigung bei Stromausfällen behandelt. Aber ich kann es nicht zum Booten bringen.

Was ich getan habe:

  1. auf dem PI vor dem Umschalten:

    apt-get install btrfs-tools 2. Von einem Linux-Computer:

    btrfs-convert / dev / sda2

  2. Im /etc/fstabWechsel ext4zubtrfs

  3. Im /cmdline.txtWechsel ext4zubtrfs

Ich bekomme eine Kernel-Panik, wenn ich versuche, zu booten. Soll ich noch etwas tun?

Antworten:


7

Wenn btrfs als Kernelmodul kompiliert wird, müssen Sie ein initramfs erstellen, um das Modul beim Booten zu laden. Bei Raspian (und anderen Debian-Derivaten) update-initramfsist dies die einfachste Methode.

Wenn initramfs-toolsinstalliert, sollte jedes Mal, wenn apt-getein neuer Kernel installiert wird, dieser update-initramfsautomatisch ausgelöst werden.

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

Wenn Sie rpi-updatejedoch einen neuen Kernel installieren, müssen Sie ihn update-initramfsmanuell ausführen, bevor Sie den neuen Kernel neu starten :

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

Dadurch werden die initramfs in erstellt oder aktualisiert /boot/initrd.img-<kernel-version>.

Der letzte Schritt besteht darin, es Ihrer Boot-Konfiguration hinzuzufügen: Fügen Sie die folgende Zeile hinzu /boot/config.txt:

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>muss genau mit dem Namen der Datei in übereinstimmen /boot.

Sie müssen diese Schritte jedes Mal wiederholen, wenn Sie ausgeführt werden rpi-update.


2

Mein schneller Test zeigt, dass die Unterstützung von btrfs als externes Modul in Raspbian erstellt wurde und nicht direkt mit dem Kernel verknüpft ist.

Das bedeutet, dass der Kernel das Modul (das im Root-Dateisystem gespeichert ist) laden kann, bevor er weiß, wie das Root-Dateisystem bereitgestellt wird. Offensichtlich funktioniert das nicht.

Ansatz 1:

Erstellen Sie Ihren eigenen Kernel und optimieren Sie die Build-Konfiguration, um btrfs vorab zu verknüpfen. Das Ändern der Konfiguration ist einfach, wenn Sie herausgefunden haben, wie Sie Ihren eigenen Kernel erstellen und laden können.

Ansatz 2:

Passen Sie die Einstellungen so an, dass sich der Kernel und die Module in einem ext4-Dateisystem befinden und die Daten, die Sie am meisten komprimieren möchten, auf einer btrfs-Partition liegen.

Ansatz 2A:

Belassen Sie die Root-Partition als ext4 und erstellen Sie eine neue Partition, die auf btrfs basiert. Dies hilft jedoch nicht, die Betriebssysteminstallation zu verkleinern (wenn dies Ihr Ziel ist).

Ansatz 2B:

Erstellen Sie eine kleine Boot-Partition, die den Kernel und die Module enthält, während alles andere auf dem btrfs verbleibt. Ich habe keine Ahnung, wie dies für den Bootloader eines Pi zu tun ist oder welche Einschränkungen diesbezüglich bestehen.


Was ist mit dem Kopieren der btrfs-Module auf die Boot-Partition und dem vorherigen Laden von dort?
GuySoft

3
Ist es nicht auch möglich, mit einem initrd.img zu beginnen?
Anders

Ja, und initrd.img scheint der einfachste Weg zu sein, es zu lösen! Ich habe es einfach nie benutzt. Suchen Sie nach Dokumenten auf "mkinitrd".
DonGar

Hmm scheint, dass CONFIG_BLK_DEV_INITRD im neuesten Raspbian nicht aktiviert ist. Dies bedeutet, dass Sie den Kernel neu kompilieren müssen, um die initd-Unterstützung zu aktivieren.
GuySoft

1
Siehe paxswill.com/blog/2013/11/04/encrypted-raspberry-pi - Dort wird initramfs verwendet, um verschlüsselte root zuzulassen. Ebenso ist Unterstützung für Cryptsetup (hier btrfs) erforderlich, bevor root verfügbar ist.
Rbjz

1

Um meine externe BTRFS-Root-Partition zu finden, musste ich die UUID der Root-Partition in der Boot-Partition explizit angeben cmdline.txt. Beispielsweise:

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

Sie können die UUID der BTRFS-Partition mithilfe von bestimmen lsblk -f.


1

Der Raspbian-Kernel bietet btrfsstandardmäßig keine Unterstützung . Die ersten Startphasen werden normal ausgeführt, aber wenn der Kernel geladen wird, wird kein Dateisystem angezeigt, das gemountet werden könnte - und es kommt zu Panik. Es gibt eine Lösung: Fügen Sie btrfs als Kernelmodul in initramfs hinzu. Vor allem dank drei verschiedener Artikel habe ich es so eingerichtet:

  • Installieren Sie die erforderlichen Pakete - das Kernelmodul und die Tools zum Aktualisieren von initramfs damit: sudo apt install btrfs-tools initramfs-tools
  • Weisen Sie initramfs an, das btrfs-Modul zu laden (sollte aus irgendeinem Grund automatisch ablaufen, funktionierte auf meinem RPi1 nicht) - fügen Sie der Liste der erforderlichen Module eine Zeile mit "btrfs" hinzu: echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • Erstellen Sie einen initramfs-Hook (zum Erstellen des Images) und ein Skript (zum Booten) für btrfs - Standardeinstellungen werden bereitgestellt, aber in meinen Tests wurden sie nicht automatisch verwendet, sondern mussten in / etc. Kopiert werden. 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
  • Create ( -c) die neuen initramfs für die aktuelle Kernelversion (uname -r) - Wenn Sie eine vorhandene aktualisieren, müssen Sie -ustattdessen update ( ) verwenden. Dadurch wird eine Datei mit dem Namen /boot/initrd.img-* erstellt, wobei * die aktuelle Kernelversion ist. Beachten Sie den generierten Namen (das Skript gibt ihn aus). Wir werden ihn im nächsten Schritt verwenden.update-initramfs -c -k $(uname -r)
  • Bearbeiten Sie /boot/config.txt, um dieses Initramfs zu verwenden, und fügen Sie hinzu. initramfs initrd.img-3.11.0+ followkernelDer Dateiname ist ohne Pfad. Er wurde im vorherigen Schritt generiert. "followkernel" steuert den Speicherort im Speicher ( Dokumentation zu config.txt ).
  • Das löst den aktuellen Kernel, aber wie @Ingo hervorhob, würde ein Upgrade des Kernels das System beschädigen . Um dies zu beheben, habe ich seine Kernel-Installations-Hook- Skripte verwendet :

    • Bearbeiten Sie / etc / default / raspberrypi-kernel und kommentieren Sie INITRD=Yes
    • löschen /etc/kernel/postinst.d/initramfs-tools
    • füge rpi-initramfs-tools zu /etc/kernel/postinst.d/ hinzu und chmod +xes
    • Laden Sie optional update-rpi-initramfs herunter, um die manuellen Updates der initramfs zu vereinfachen.
  • An dieser Stelle haben wir ein System , das könnte Btrfs als Root - Gerät verwenden. Test durch Neustart: Das System bootet weiterhin von der ext4-Partition (oder was auch immer in Ihrer /boot/cmdline.txt steht ), dmesg | grep -i btrfssollte aber jetzt eine Zeile mit "Btrfs geladen" anzeigen . Jetzt müssen wir tatsächlich eine btrfs-Partition erstellen und verwenden.

  • /Erstellen Sie eine Sicherungskopie der (ext4) -Partition - vorausgesetzt, dies ist / dev / mmcblk0p2 - normalerweise: Fahren Sie das RPi herunter, nehmen Sie die SD-Karte heraus, mounten Sie sie sudo mount /dev/mmcblk0p2 /mntan einer anderen Stelle (in diesem Beispiel auf einem Linux-Computer) und archivieren Sie den Inhalt. Beachten Sie, dass Sie ein Tool verwenden müssen, das den Besitz und die Berechtigungen cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *beibehält , z. B. tar: (und dann die SD-Karte wieder aushängen)

  • Erstellen Sie irgendwo eine btrfs-Partition - Ich habe die SD-Karte wiederverwendet und die ext4-Partition (/ dev / mmcblk0p2) ersetzt. Wenn Sie ein btrfs-raid-Array erstellen möchten , ist dies der richtige Zeitpunkt ( dies ist eines der Argumente für mkfs.btrfs , die über den Rahmen dieser Antwort hinausgehen):mkfs.btrfs /dev/mmcblk0p2
  • Hängen Sie die btrfs-Partition ein und stellen Sie die Sicherung wieder her: sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • Bearbeiten Sie fstab auf der btrfs-Partition :sudo nano /mnt/etc/fstab

Es sollte eine ähnliche Zeile geben:

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

Ändern Sie dies in diesen (der neue FS-Typ ist btrfs und verwendet Standardoptionen):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • Hängen Sie die Partition aus, aber entfernen Sie die SD-Karte noch nicht! sudo umount /mnt
  • Wir müssen dem RPi mitteilen, dass es von btrfs booten wird
  • Suchen Sie die UUID Ihrer neuen btrfs-Partition - suchen Sie die Zeile mit / dev / mmcblk0p2 und kopieren Sie den UUID = -Teil mit (nicht UUID_SUB, nicht PARTUUID! Dies würde einen Fehler im Bootloader auslösen und der Kernel würde nicht booten .):sudo blkid

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

  • Mounten Sie die Boot-Partition (FAT32): sudo mount /dev/mmcblk0p1 /mnt

  • Bearbeiten Sie cmdline.txt: sudo nano /mnt/cmdline.txt

Finden Sie diese beiden Parameter

 root=PARTUUID=1234-5678 rootfstype=ext4

Und ersetzen durch

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

Beachten Sie, dass die UUID die zuvor kopierte ist, nur ohne Anführungszeichen.

  • Hängen Sie die RPi-Startpartition aus: sudo umount /mnt
  • Ersetzen Sie die SD-Karte in RPi und starten Sie.
  • Stellen Sie auf dem RPi sicher, dass Sie tatsächlich von einem btrfs-Root-Mount ausgeführt werden: mount

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

  • Et voilà! Nicht ganz per Mausklick, aber wenn ich auf den Schultern von Riesen stehe, kann ich es zum Laufen bringen. (Hat das auch zu einem Repo gemacht .)


1
Beim ersten sudo apt upgradeUpgrade des Kernels schlägt dieses Setup beim Booten dramatisch fehl, da der neue Kernel versucht, die alten Initramfs zu laden, die fehlschlagen, und der Kernel keine btrfs-Treiber laden kann. Und es ist keine einfache Möglichkeit, dies zu beheben, zumindest mit einem chrootArmhf-System.
Ingo

Würden update-initramfs nicht beim Kernel-Upgrade aufgerufen?
Piskvor verließ das Gebäude

1
Nein, Standard-Raspbian generiert kein neues Initramfs. Es ist nicht dafür konfiguriert. Sie müssen immer mit Ihren Augen überwachen, was apt upgradegerade passiert, und bei Bedarf ein Initramfs von Hand generieren - bevor Sie den neuen Kernel starten. Keine machbare Aufgabe für einen Anfänger, weil es dramatisch ist, sie nicht zu bestehen. Sie können einen Blick darauf werfen, wie ich eine Init-Ramdisk (initramfs) beim Booten von Raspberry Pi verwenden kann.
Ingo

1
Es hat einen kleinen Fehler, den ich gerade gefunden, aber noch nicht behoben habe. Der Kernel unterstützt zwei Modelle, z . B. 4.14.98+und 4.14.98-v7+. Wenn update-initramfs durch ein Kernel-Update ausgelöst wird, werden zwei initrd.img * generiert, eine für jedes Modell. Dies passt nicht auf die /bootPartition (Fehler - nicht genügend Speicherplatz) und die Generierung wird nicht abgeschlossen.
Ingo

1
Ich überlege zu verwenden MODULES=list.
Ingo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.