główny system plików btrfs na raspbian

11

Pomyślałem, że mogę wykonać expresment z btrfs jako partycją root, aby zobaczyć, jak radzi sobie z uszkodzeniem plików podczas przerw w zasilaniu. Ale nie mogę go uruchomić.

Co ja zrobiłem:

  1. na PI przed przełączeniem:

    apt-get install btrfs-tools 2. Z komputera z systemem Linux:

    btrfs-convert / dev / sda2

  2. W /etc/fstabzamian ext4nabtrfs

  3. W /cmdline.txtzamian ext4nabtrfs

Gdy próbuję uruchomić system, pojawia się panika jądra. Czy powinienem zrobić coś jeszcze?

GuySoft
źródło

Odpowiedzi:

7

Jeśli btrfs jest skompilowany jako moduł jądra, musisz utworzyć initramfs, aby załadować moduł podczas rozruchu. Na Raspian (i innych pochodnych Debiana) update-initramfsjest to najłatwiejsza metoda.

Jeśli initramfs-toolsjest zainstalowany, to za każdym razem apt-getinstaluje nowe jądro, powinno się uruchomić update-initramfsautomatycznie.

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

Jeśli jednak użyjesz rpi-updatedo zainstalowania nowego jądra, musisz uruchomić update-initramfsręcznie przed ponownym uruchomieniem do nowego jądra:

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

Spowoduje to utworzenie lub aktualizację initramfs w /boot/initrd.img-<kernel-version>.

Ostatnim krokiem jest dodanie go do konfiguracji rozruchu: dodaj następujący wiersz do /boot/config.txt:

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>musi dokładnie odpowiadać nazwie pliku w /boot.

Powtórz te kroki za każdym razem, gdy uruchomisz rpi-update.

bennettp123
źródło
2

Mój szybki test pokazuje, że obsługa btrfs jest wbudowana w Raspbian jako moduł zewnętrzny, niepowiązany bezpośrednio z jądrem.

Oznacza to, że jądro musi mieć możliwość załadowania tego modułu (który jest przechowywany w głównym systemie plików), zanim będzie wiedział, jak zamontować główny system plików. Oczywiście to nie działa.

Podejście 1:

Zbuduj własne jądro i popraw jego konfigurację, aby wstępnie połączyć btrfs. Dostosowanie konfiguracji jest łatwe, jeśli nauczysz się budować i ładować własne jądro.

Podejście 2:

Dostosuj rzeczy, aby jądro i moduły znajdowały się w systemie plików ext4, a dane, które najbardziej chcesz skompresować, znajdują się na partycji btrfs.

Podejście 2A:

Pozostaw partycję root jako ext4 i utwórz nową partycję opartą na btrfs, ale to nie pomaga zmniejszyć instalacji systemu operacyjnego (jeśli to jest twój cel).

Podejście 2B:

Utwórz partycję rozruchową, która jest mała i zawiera jądro i moduły, pozostawiając wszystko inne na btrfs. Nie mam pojęcia, jak to zrobić dla bootloadera Pi, ani jakie są wokół tego ograniczenia.

DonGar
źródło
A co z kopiowaniem modułów btrfs na partycję rozruchową i ładowaniem ich stamtąd wcześniej?
GuySoft,
3
Czy nie można również zacząć od initrd.img?
Anders
Tak, i initrd.img wygląda na najprostszy sposób na rozwiązanie tego problemu! Po prostu nigdy tego nie użyłem. Poszukaj dokumentów na temat „mkinitrd”.
DonGar
Hmm wydaje się, że CONFIG_BLK_DEV_INITRD nie jest włączony w najnowszej wersji Raspbian. Oznacza to, że musisz ponownie skompilować jądro, aby włączyć obsługę initd.
GuySoft,
1
Zobacz paxswill.com/blog/2013/11/04/encrypted-raspberry-pi - Tam initramfs służy do szyfrowania roota. Podobnie, wsparcie dla cryptsetup (tutaj btrfs) jest potrzebne, zanim root będzie dostępny.
Rbjz
1

Aby znaleźć moją zewnętrzną partycję główną BTRFS, musiałem jawnie określić UUID partycji głównej w partycji rozruchowej cmdline.txt. Na przykład:

dwc_otg.lpm_enable = 0 konsola = root tty1 = PARTUUID = 123e4567-e89b-12d3-a456-426655440000 rootfstype = btrfs winda = ostateczny termin rootwait cichy plusk

Możesz określić UUID partycji BTRFS za pomocą lsblk -f.

Geremia
źródło
1

Jądro Raspbian domyślnie nie obsługuje btrfs; początkowe etapy rozruchu działają normalnie, ale gdy jądro się załaduje, nie zobaczy żadnego systemu plików, który mógłby zamontować - i wpadnie w panikę. Istnieje rozwiązanie: dodaj btrfs jako moduł jądra w initramfs. W dużej mierze dzięki trzem różnym artykułom skonfigurowałem to w następujący sposób:

  • Zainstaluj wymagane pakiety - moduł jądra i narzędzia do aktualizacji initramfs: sudo apt install btrfs-tools initramfs-tools
  • Powiedz initramfs, aby załadował moduł btrfs (powinno się to dziać automatycznie, z jakiegoś powodu nie działało na moim RPi1) - dołącz linię z „btrfs” do listy wymaganych modułów: echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • Utwórz hook initramfs (do budowania obrazu) i skrypt (do bootowania) dla btrfs - podane są wartości domyślne, ale w moich testach nie były używane w sposób automatyczny, musiałem je skopiować do / 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
  • Utwórz ( -c) nowe initramfs dla bieżącej wersji jądra (uname -r) - jeśli aktualizujesz istniejącą, musisz -uzamiast tego użyć update ( ). Spowoduje to utworzenie pliku o nazwie jak /boot/initrd.img-*, gdzie * jest bieżącą wersją jądra. Zanotuj wygenerowaną nazwę (skrypt ją wypisze), wykorzystamy ją w następnym kroku.update-initramfs -c -k $(uname -r)
  • Edytuj, /boot/config.txtaby użyć tego initramfs, dodając initramfs initrd.img-3.11.0+ followkernelNazwa pliku jest bez ścieżki, to ta wygenerowana w poprzednim kroku; „followkernel” kontroluje lokalizację w pamięci ( dokumentacja config.txt ).
  • To rozwiązuje bieżące jądro, ale jak wskazał @Ingo, aktualizacja jądra spowodowałaby uszkodzenie systemu. Aby to naprawić, użyłem jego skryptów przechwytujących instalujących jądro :

    • Edytuj / etc / default / raspberrypi-kernel i odkomentuj INITRD=Yes
    • usunąć /etc/kernel/postinst.d/initramfs-tools
    • dodaj rpi-initramfs-tools do /etc/kernel/postinst.d/ i chmod +xto
    • opcjonalnie pobierz update-rpi-initramfs, aby uprościć ręczne aktualizacje initramfs.
  • W tym momencie mamy system, który mógłby używać btrfs jako urządzenia root. Testuj przez ponowne uruchomienie: system nadal będzie się uruchamiał z partycji ext4 (lub cokolwiek co znajduje się w /boot/cmdline.txt ), ale dmesg | grep -i btrfspowinien teraz wyświetlać wiersz zawierający „załadowano Btrfs”. Teraz musimy faktycznie utworzyć i używać partycji btrfs.

  • Wykonaj kopię zapasową /partycji (ext4) - zakładając, że jest to / dev / mmcblk0p2 - zazwyczaj: zamknij RPi, wyjmij kartę SD, zamontuj ją gdzie indziej (w tym przykładzie sudo mount /dev/mmcblk0p2 /mntna komputerze z systemem Linux) i zarchiwizuj zawartość; pamiętaj, że musisz użyć narzędzia, które zachowuje własność i uprawnienia, np. tar: cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *(a następnie ponownie odmontuj kartę SD)

  • Utwórz gdzieś partycję btrfs - ponownie użyłem karty SD, zastępując partycję ext4 (/ dev / mmcblk0p2); jeśli chcesz utworzyć tablicę raid btrfs, nadszedł czas, aby to zrobić ( jest to jeden z argumentów mkfs.btrfs , wykraczający poza zakres tej odpowiedzi):mkfs.btrfs /dev/mmcblk0p2
  • Zamontuj partycję btrfs i przywróć na niej kopię zapasową: sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • Edytuj fstab na partycji btrfs :sudo nano /mnt/etc/fstab

Powinien być wiersz podobny do tego:

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

Zmień to na (nowy typ FS to btrfs i używa domyślnych opcji):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • Odmontuj partycję, ale nie wyjmuj jeszcze karty SD! sudo umount /mnt
  • Musimy powiedzieć RPi, że uruchomi się z btrfs
  • Znajdź UUID nowej partycji btrfs - znajdź linię za pomocą / dev / mmcblk0p2 i skopiuj UUID = część, używając (nie UUID_SUB, nie PARTUUID! To spowodowałoby błąd w bootloaderze, a jądro nie uruchomiłoby się .):sudo blkid

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

  • Zamontuj partycję rozruchową (FAT32): sudo mount /dev/mmcblk0p1 /mnt

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

Znajdź te dwa parametry

 root=PARTUUID=1234-5678 rootfstype=ext4

I zamień na

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

Zauważ, że UUID to ten, który skopiowaliśmy wcześniej, tylko bez cudzysłowów.

  • Odmontuj partycję rozruchową RPi: sudo umount /mnt
  • Włóż kartę SD do RPi i uruchom.
  • Na RPi sprawdź, czy rzeczywiście korzystasz z rootowania btrfs: mount

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

  • Zrobione! Nie do końca wskaż i kliknij, ale stojąc na ramionach gigantów, mogłem sprawić, że to zadziała. (To też zrobiło repo .)

Piskvor opuścił budynek
źródło
1
W przypadku pierwszego, sudo apt upgradejeśli zaktualizuje także jądro, ta konfiguracja nie powiedzie się dramatycznie podczas rozruchu, ponieważ nowe jądro próbuje załadować stare initramfs, które ulegną awarii, a jądro nie może załadować sterowników btrfs. I nie jest to łatwy sposób, aby to naprawić, przynajmniej chrootw systemie armhf.
Ingo
Czy aktualizacja-initramfs nie byłaby wywoływana przy aktualizacji jądra?
Piskvor opuścił budynek
1
Nie, domyślny Raspbian nie generuje nowego initramfs. Nie jest skonfigurowany do tego. Zawsze musisz monitorować na własne oczy, co apt upgradesię dzieje, i jeśli to konieczne, ręcznie wygeneruj initramfs - przed uruchomieniem nowego jądra. Nie jest to wykonalne zadanie dla początkującego, ponieważ jego niepowodzenie jest dramatyczne. Możesz rzucić okiem Jak mogę użyć ramdysku init (initramfs) podczas uruchamiania Raspberry Pi?
Ingo
1
Ma mały błąd, który właśnie znalazłem, ale do tej pory go nie naprawiłem. Jądro obsługuje dwa modele, na przykład 4.14.98+a 4.14.98-v7+. Jeśli update-initramfs zostanie wyzwolony przez aktualizację jądra, wygeneruje dwa initrd.img *, po jednym dla każdego modelu. Nie pasuje to do /bootpartycji (błąd - brak miejsca) i generowanie się nie kończy.
Ingo
1
Rozważam użyć MODULES=list.
Ingo