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:
na PI przed przełączeniem:
apt-get install btrfs-tools 2. Z komputera z systemem Linux:
btrfs-convert / dev / sda2
W /etc/fstabzamian ext4nabtrfs
W /cmdline.txtzamian ext4nabtrfs
Gdy próbuję uruchomić system, pojawia się panika jądra. Czy powinienem zrobić coś jeszcze?
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.
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.
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.
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
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
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.
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:Możesz określić UUID partycji BTRFS za pomocą
lsblk -f
.źródło
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:sudo apt install btrfs-tools initramfs-tools
echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
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
-c
) nowe initramfs dla bieżącej wersji jądra (uname -r) - jeśli aktualizujesz istniejącą, musisz-u
zamiast 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)
/boot/config.txt
aby użyć tego initramfs, dodającinitramfs initrd.img-3.11.0+ followkernel
Nazwa 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 :
INITRD=Yes
/etc/kernel/postinst.d/initramfs-tools
chmod +x
toW 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 btrfs
powinien 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ładziesudo mount /dev/mmcblk0p2 /mnt
na 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)mkfs.btrfs /dev/mmcblk0p2
sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
sudo nano /mnt/etc/fstab
Powinien być wiersz podobny do tego:
Zmień to na (nowy typ FS to btrfs i używa domyślnych opcji):
sudo umount /mnt
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
sudo nano /mnt/cmdline.txt
Znajdź te dwa parametry
I zamień na
Zauważ, że UUID to ten, który skopiowaliśmy wcześniej, tylko bez cudzysłowów.
sudo umount /mnt
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 .)
źródło
sudo apt upgrade
jeś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ć, przynajmniejchroot
w systemie armhf.apt upgrade
się 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?4.14.98+
a4.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/boot
partycji (błąd - brak miejsca) i generowanie się nie kończy.MODULES=list
.