btrfs root filesystem pada raspbian

11

Saya pikir saya mungkin experement dengan btrfs sebagai partisi root untuk melihat bagaimana menangani file korupsi selama pemadaman listrik. Tapi saya tidak bisa mendapatkannya untuk boot.

Apa yang saya lakukan:

  1. pada PI sebelum beralih:

    apt-get install btrfs-tools 2. Dari komputer linux:

    btrfs-convert / dev / sda2

  2. Di /etc/fstabubah ext4menjadibtrfs

  3. Di /cmdline.txtubah ext4menjadibtrfs

Saya mendapatkan kepanikan kernel jika saya mencoba melakukan boot. Haruskah saya melakukan hal lain?

GuySoft
sumber

Jawaban:

7

Jika btrf dikompilasi sebagai modul kernel, maka Anda perlu membuat initramfs untuk memuat modul saat boot. Pada Raspian (dan turunan debian lainnya), update-initramfsadalah metode termudah untuk melakukan ini.

Jika initramfs-toolsdiinstal, maka setiap saat apt-getmenginstal kernel baru, itu akan memicu update-initramfssecara otomatis.

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

Namun, jika Anda menggunakan rpi-updateuntuk menginstal kernel baru, maka Anda harus menjalankan update-initramfssecara manual sebelum me-reboot ke kernel baru:

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

Ini akan membuat atau memperbarui initramfs di /boot/initrd.img-<kernel-version>.

Langkah terakhir adalah menambahkannya ke konfigurasi boot Anda: tambahkan baris berikut ke /boot/config.txt:

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>harus sama persis dengan nama file di /boot.

Anda harus mengulangi langkah-langkah ini setiap kali Anda menjalankan rpi-update.

bennettp123
sumber
2

Tes cepat saya menunjukkan bahwa dukungan btrf dibangun sebagai modul eksternal dalam raspbian, tidak terhubung langsung ke kernel.

Itu berarti bahwa kernel harus dapat memuat modul itu (yang disimpan pada sistem file root) sebelum ia tahu cara me-mount sistem file root. Jelas, ini tidak berhasil.

Pendekatan 1:

Bangun kernel Anda sendiri, dan atur itu membangun config ke btrf pra-tautan. Tweak konfigurasi itu mudah jika Anda sudah tahu cara membangun dan memuat kernel Anda sendiri.

Pendekatan 2:

Menyesuaikan hal-hal sehingga kernel dan modul berada pada sistem file ext4 dan data yang paling ingin Anda kompres ada di partisi btrfs.

Pendekatan 2A:

Biarkan partisi root sebagai ext4 dan buat partisi baru yang berbasis btrfs, tetapi itu tidak membantu mengecilkan instalasi OS (jika itu tujuan Anda).

Pendekatan 2B:

Buat partisi boot yang kecil, dan pegang kernel dan modul, sambil meninggalkan yang lainnya di btrfs. Saya tidak tahu bagaimana melakukan ini untuk bootloader Pi, atau batasan apa yang ada di sekitar ini.

DonGar
sumber
Bagaimana dengan menyalin modul btrfs ke partisi boot dan memuatnya dari sana sebelumnya?
GuySoft
3
Bukankah mungkin juga untuk memulai dengan initrd.img?
Anders
Ya, dan initrd.img sepertinya cara termudah untuk menyelesaikannya! Saya tidak pernah menggunakannya. Cari dokumen di "mkinitrd".
DonGar
Hmm sepertinya CONFIG_BLK_DEV_INITRD tidak diaktifkan di Raspbian terbaru. Ini berarti Anda perlu mengkompilasi ulang kernel untuk mengaktifkan dukungan initd.
GuySoft
1
Lihat paxswill.com/blog/2013/11/04/encrypted-raspberry-pi - Ada initramfs digunakan untuk memungkinkan root terenkripsi. Demikian pula, dukungan untuk cryptsetup (di sini btrfs) diperlukan sebelum root tersedia.
Rbjz
1

Untuk mendapatkannya untuk menemukan partisi root BTRFS eksternal saya, saya perlu secara eksplisit menentukan UUID partisi root di partisi boot cmdline.txt. Sebagai contoh:

dwc_otg.lpm_enable = 0 konsol = tty1 root = PARTUUID = 123e4567-e89b-12d3-a456-426655440000 rootfstype = btrfs lift = tenggat waktu rootwait tenggat tenang

Anda dapat menentukan UUID partisi BTRFS menggunakan lsblk -f.

Geremia
sumber
1

Kernel Raspbian tidak menyertakan dukungan btrfssecara default; tahap boot awal berjalan secara normal, tetapi ketika kernel dimuat, ia tidak akan melihat sistem file mana pun yang bisa dipasang - dan panik. Ada solusi: tambahkan btrfs sebagai modul kernel, di initramfs. Sebagian besar berkat tiga artikel berbeda , saya telah mengaturnya sebagai berikut:

  • Instal paket yang diperlukan - modul kernel, dan alat-alat untuk memperbarui initramfs dengan itu: sudo apt install btrfs-tools initramfs-tools
  • Beri tahu initramfs untuk memuat modul btrfs (harus terjadi secara otomatis, karena alasan tertentu, tidak berfungsi pada RPi1 saya) - tambahkan baris dengan "btrfs" ke daftar modul yang diperlukan: echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • Buat kait initramfs (untuk membangun gambar) dan skrip (untuk booting) untuk btrfs - default disediakan, tetapi dalam pengujian saya, mereka tidak digunakan secara otomatis, harus menyalinnya ke / 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
  • Buat ( -c) initramfs baru untuk versi kernel saat ini (uname -r) - jika Anda memperbarui yang sudah ada, Anda harus menggunakan pembaruan ( -u). Ini akan membuat file dengan nama /boot/initrd.img-*, di mana * adalah versi kernel saat ini. Perhatikan nama yang dihasilkan (skrip akan menampilkannya), kami akan menggunakannya pada langkah berikutnya.update-initramfs -c -k $(uname -r)
  • Edit /boot/config.txtuntuk menggunakan initramfs ini, menambahkan initramfs initrd.img-3.11.0+ followkernelNama file tanpa path, itu adalah yang dihasilkan pada langkah sebelumnya; "followkernel" mengontrol lokasi dalam memori ( dokumentasi config.txt ).
  • Itu memecahkan kernel saat ini, tetapi seperti yang ditunjukkan @Ingo, memutakhirkan kernel akan merusak sistem. Untuk memperbaikinya, saya menggunakan skrip kait-instal kernel-nya :

    • Edit / etc / default / raspberrypi-kernel dan batalkan komentar INITRD=Yes
    • menghapus /etc/kernel/postinst.d/initramfs-tools
    • tambahkan rpi-initramfs-tools ke /etc/kernel/postinst.d/ dan chmod +xitu
    • secara opsional, unduh pembaruan-rpi-initramfs untuk pembaruan manual yang lebih sederhana dari initramfs.
  • Pada titik ini, kami memiliki sistem yang dapat menggunakan btrfs sebagai perangkat root. Tes dengan mem-boot ulang: sistem masih akan mem-boot dari partisi ext4 (atau apa pun yang ada di /boot/cmdline.txt Anda ), tetapi dmesg | grep -i btrfssekarang harus memperlihatkan baris yang berisi "Btrfs dimuat". Sekarang kita harus benar-benar membuat dan menggunakan partisi btrfs.

  • Buat cadangan /partisi (ext4) - dengan asumsi ini adalah / dev / mmcblk0p2 - biasanya: matikan RPi, keluarkan kartu SD, pasang kartu itu di tempat lain (dalam contoh ini sudo mount /dev/mmcblk0p2 /mntdi komputer Linux) dan arsipkan isinya; perhatikan bahwa Anda perlu menggunakan alat yang mempertahankan kepemilikan dan izin, misalnya tar: cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *(dan kemudian lepaskan kartu SD lagi)

  • Buat partisi btrfs di suatu tempat - Saya telah menggunakan kembali kartu SD, menggantikan partisi ext4 (/ dev / mmcblk0p2); jika Anda ingin membuat array btrfs-raid, inilah saatnya untuk melakukan ini ( ini adalah salah satu argumen untuk mkfs.btrfs , di luar cakupan jawaban ini):mkfs.btrfs /dev/mmcblk0p2
  • Pasang partisi btrfs dan kembalikan cadangan ke dalamnya: sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • Edit fstab pada partisi btrfs :sudo nano /mnt/etc/fstab

Seharusnya ada baris yang mirip dengan ini:

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

Ubah ke ini (tipe FS baru adalah btrfs, dan menggunakan opsi default):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • Lepaskan partisi, tetapi jangan keluarkan kartu SD! sudo umount /mnt
  • Kita perlu memberi tahu RPi bahwa itu akan boot dari btrfs
  • Temukan UUID dari partisi btrfs baru Anda - temukan baris dengan / dev / mmcblk0p2, dan salin bagian UUID =, dengan (bukan UUID_SUB, bukan PARTUUID! Itu akan memicu bug di bootloader, dan kernel tidak mau boot .):sudo blkid

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

  • Pasang partisi boot (FAT32): sudo mount /dev/mmcblk0p1 /mnt

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

Temukan dua parameter ini

 root=PARTUUID=1234-5678 rootfstype=ext4

Dan ganti dengan

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

Perhatikan bahwa UUID adalah yang kami salin sebelumnya, hanya tanpa tanda kutip.

  • Lepaskan partisi boot RPi: sudo umount /mnt
  • Ganti kartu SD menjadi RPi, dan boot.
  • Pada RPi, lihat bahwa Anda memang menjalankan dari mount root btrfs: mount

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

  • Dan lagi! Bukan titik-dan-klik, tetapi dengan berdiri di atas bahu raksasa, saya bisa membuatnya bekerja. (Membuat ini menjadi repo juga.)

Piskvor meninggalkan gedung
sumber
1
Dengan yang pertama sudo apt upgradejika itu juga meningkatkan kernel, pengaturan ini akan gagal secara dramatis saat boot karena kernel baru mencoba memuat initramf lama yang akan gagal dan kernel tidak dapat memuat driver btrfs. Dan itu bukan cara mudah untuk memperbaikinya, setidaknya dengan chrootsistem armhf.
Ingo
Tidakkah pembaruan-initramfs dilakukan pada peningkatan kernel?
Piskvor meninggalkan gedung
1
Tidak, Raspbian default gagal menghasilkan initramf baru. Ini tidak dikonfigurasi untuk ini. Anda selalu harus memantau dengan mata Anda apa yang apt upgradesedang dilakukan dan harus menghasilkan initramfs dengan tangan jika diperlukan - sebelum mem-boot kernel baru. Bukan tugas yang bisa dilakukan untuk pemula karena gagal itu dramatis. Anda mungkin telah melihat Bagaimana saya bisa menggunakan init ramdisk (initramfs) saat boot Raspberry Pi?
Ingo
1
Ini memiliki sedikit bug yang baru saya temukan tetapi belum diperbaiki sejauh ini. Kernel mendukung dua model, misalnya 4.14.98+dan 4.14.98-v7+. Jika pembaruan-initramfs dipicu oleh pembaruan kernel, ia akan menghasilkan dua initrd.img *, satu untuk setiap model. Ini tidak cocok pada /bootpartisi (kesalahan - keluar dari ruang) dan generasi tidak selesai.
Ingo
1
Saya mempertimbangkan untuk menggunakan MODULES=list.
Ingo