btrfs коренева файлова система на raspbian


11

Я думав, що я міг би експлуатувати btrfs як кореневий розділ, щоб побачити, як він обробляє файл з пошкодженням під час відключення живлення. Але я не можу його завантажувати.

Що я зробив:

  1. на ПІ перед перемиканням:

    apt-get install btrfs-tools 2. З комп’ютера Linux:

    btrfs-convert / dev / sda2

  2. У /etc/fstabзміну ext4наbtrfs

  3. У /cmdline.txtзміну ext4наbtrfs

У мене виникає паніка ядра, якщо я спробую зробити завантаження. Чи варто робити щось інше?

Відповіді:


7

Якщо btrfs компілюється як модуль ядра, то вам потрібно створити initramfs для завантаження модуля під час завантаження. На Raspian (та інші похідні debian) update-initramfsце найпростіший метод зробити це.

Якщо initramfs-toolsвстановлено, то будь-коли apt-getінсталює нове ядро, воно повинно спрацьовувати update-initramfsавтоматично.

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

Однак якщо ви використовуєте rpi-updateдля встановлення нового ядра, вам потрібно буде запустити update-initramfsвручну перед перезавантаженням у нове ядро:

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

Це створить або оновить initramfs в /boot/initrd.img-<kernel-version>.

Останнім кроком є ​​додавання його до конфігурації завантаження: додайте наступний рядок до /boot/config.txt:

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>має точно відповідати імені файлу в /boot.

Вам потрібно буде повторювати ці дії щоразу, коли ви запустите rpi-update.


2

Мій швидкий тест показує, що підтримка btrfs побудована як зовнішній модуль у розп’яні, не пов'язана безпосередньо з ядром.

Це означає, що ядро ​​повинне мати можливість завантажувати цей модуль (який зберігається в кореневій файловій системі), перш ніж воно знатиме, як змонтувати кореневу файлову систему. Очевидно, це не працює.

Підхід 1:

Створіть власне ядро ​​та налаштуйте його конфігурацію збірки для попереднього посилання btrfs. Налаштування конфігурації легко, якщо ви зрозуміли, як створити та завантажити власне ядро.

Підхід 2:

Налаштуйте речі, щоб ядро ​​та модулі знаходилися у файловій системі ext4, а дані, які ви найбільше хочете стиснути, перебувають на розділі btrfs.

Підхід 2A:

Залиште кореневий розділ як ext4 та створіть новий розділ, на якому базується btrfs, але це не допоможе зменшити встановлення ОС (якщо це ваша мета).

Підхід 2B:

Створіть невеликий завантажувальний розділ, який містить ядро ​​та модулі, залишаючи все інше на btrfs. Я поняття не маю, як це зробити для завантажувача Pi, або які обмеження існують навколо цього.


Що з копією модулів btrfs до завантажувального розділу та завантаження їх звідти заздалегідь?
GuySoft

3
Чи не можна також почати з initrd.img?
Андерс

Так, і initrd.img виглядає як найпростіший спосіб вирішити це! Я ніколи його не використовував. Шукайте документи на "mkinitrd".
DonGar

Хм здається, CONFIG_BLK_DEV_INITRD не ввімкнено в останніх програмах Raspbian. Це означає, що вам потрібно перекомпілювати ядро, щоб увімкнути підтримку initd.
GuySoft

1
Див. Paxswill.com/blog/2013/11/04/encrypted-raspberry-pi - там initramfs використовується для дозволу зашифрованого кореня. Так само необхідна підтримка cryptsetup (тут btrfs) до появи root.
Rbjz

1

Щоб знайти його зовнішній кореневий розділ BTRFS, мені потрібно було чітко вказати UUID кореневого розділу у завантажувальному розділі cmdline.txt. Наприклад:

dwc_otg.lpm_enable = 0 консоль = tty1 корінь = PARTUUID = 123e4567-e89b-12d3-a456-426655440000 rootfstype = btrfs elevator = кінцевий термін rootwait тихий сплеск

Ви можете визначити UUID розділу BTRFS, використовуючи lsblk -f.


1

Raspbian ядро ​​не включає підтримку btrfsза замовчуванням; початкові етапи завантаження працюють нормально, але коли ядро ​​завантажується, воно не побачить жодної файлової системи, яку воно могло б встановити - і панікує. Рішення існує: додайте btrfs як модуль ядра, в initramfs. Завдяки трьом різним статтям я створив це таким чином:

  • Встановіть необхідні пакети - модуль ядра та інструменти для оновлення initramfs з ним: sudo apt install btrfs-tools initramfs-tools
  • Скажіть initramfs завантажувати модуль btrfs (це повинно відбуватися автоматично, чомусь не працював мій RPi1) - додайте рядок із "btrfs" до списку необхідних модулів: echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • Створіть гачок initramfs (для створення зображення) та скрипт (для завантаження) для btrfs - передбачені параметри за замовчуванням, але в моєму тестуванні вони не використовувалися автоматично, довелося копіювати їх у / 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
  • Створіть ( -c) нові initramfs для поточної версії ядра (uname -r) - якщо ви оновлюєте існуючу, -uзамість цього вам потрібно буде використовувати update ( ). Це створить файл з назвою /boot/initrd.img-*, де * - поточна версія ядра. Зверніть увагу на створене ім’я (сценарій виведе його), ми використаємо його на наступному кроці.update-initramfs -c -k $(uname -r)
  • Редагуйте, /boot/config.txtщоб використовувати цей initramfs, додавши initramfs initrd.img-3.11.0+ followkernelім'я файлу без шляху, це той, що генерується на попередньому кроці; "followkernel" керує розташуванням у пам'яті ( документація config.txt ).
  • Це вирішує поточне ядро, але, як зазначав @Ingo, оновлення ядра порушить систему. Щоб виправити це, я використав його скрипт для встановлення гачка ядра :

    • Редагувати / etc / default / raspberrypi-kernel та unment INITRD=Yes
    • видалити /etc/kernel/postinst.d/initramfs-tools
    • додайте rpi-initramfs-tools в /etc/kernel/postinst.d/ і chmod +xце
    • необов’язково, завантажуйте update-rpi-initramfs для більш простих вручну оновлень initramfs.
  • На даний момент у нас є система, яка може використовувати btrfs як кореневий пристрій. Перевірте, перезавантажившись: система все ще завантажиться з розділу ext4 (або все, що є у вашому /boot/cmdline.txt ), але dmesg | grep -i btrfsтепер має показати рядок, що містить "Btrfs завантажений". Тепер нам потрібно фактично зробити і використовувати розділ btrfs.

  • Зробіть резервну копію /(ext4) розділу - припустимо, що це / dev / mmcblk0p2 - як правило: вимкніть RPi, вийміть SD-карту, змонтуйте її де-небудь ще (у цьому прикладі sudo mount /dev/mmcblk0p2 /mntна комп’ютері Linux) та заархівуйте вміст; зауважте, що вам потрібно скористатися інструментом, який зберігає право власності та дозволи, наприклад tar: cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *(а потім знову від'єднайте SD-карту)

  • Створіть десь розділ btrfs - я повторно використав карту SD, замінивши розділ ext4 (/ dev / mmcblk0p2); якщо ви хочете створити масив btrfs-raid, настав час це зробити ( це один з аргументів mkfs.btrfs , що виходить за межі цієї відповіді):mkfs.btrfs /dev/mmcblk0p2
  • Встановіть розділ btrfs і відновіть у ньому резервну копію: sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • Редагувати fstab на розділі btrfs :sudo nano /mnt/etc/fstab

Повинно бути рядок, подібний до цього:

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

Змініть це на це (новий тип FS - це btrfs, і він використовує параметри за замовчуванням):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • Демонтуйте розділ, але SD-карту ще не виймайте! sudo umount /mnt
  • Нам потрібно сказати RPi, що він завантажиться з btrfs
  • Знайдіть UUID вашого нового розділу btrfs - знайдіть рядок з / dev / mmcblk0p2 та скопіюйте частину UUID = (не UUID_SUB, не PARTUUID! Це призведе до помилки у завантажувачі, і ядро ​​не завантажиться. .):sudo blkid

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

  • Встановіть розділ завантаження (FAT32): sudo mount /dev/mmcblk0p1 /mnt

  • Редагувати cmdline.txt: sudo nano /mnt/cmdline.txt

Знайдіть ці два параметри

 root=PARTUUID=1234-5678 rootfstype=ext4

І замінити на

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

Зауважте, що UUID - це той, який ми скопіювали раніше, лише без лапок.

  • Демонтуйте завантажувальний розділ RPi: sudo umount /mnt
  • Замініть SD-карту на RPi та завантажте її.
  • На RPi переконайтеся, що ви дійсно запущені з кореневого кріплення btrfs: mount

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

  • Et voilà! Не зовсім точковий і натискаючи, але, стоячи на плечах гігантів, я міг би змусити його працювати. (Зробили це також у репо , теж).


1
З першим, sudo apt upgradeякщо воно також оновить ядро, ця установка різко не вдасться під час завантаження, оскільки нове ядро ​​намагається завантажити старі initramfs, які не зможуть, і ядро ​​не може завантажити драйвери btrfs. І це не простий спосіб виправити, принаймні, chrootза допомогою системи armhf.
Інго

Не вдалося б оновлення-initramfs викликати при оновленні ядра?
Пісквор вийшов з будівлі

1
Ні, Raspbian за замовчуванням не вдається створити нові initramfs. Це не налаштовано для цього. Ви завжди повинні стежити за своїми очима, що apt upgradeробить, і, якщо потрібно, генерувати initramfs вручну - перед завантаженням нового ядра. Невикональне завдання для початківця, тому що його невдача є драматичним. Ви можете подивитись на те, як я можу використовувати init ramdisk (initramfs) для завантаження Raspberry Pi?
Інго

1
У ньому є невелика помилка, яку я щойно знайшов, але поки не виправлений. Ядро підтримує дві моделі, наприклад, 4.14.98+та 4.14.98-v7+. Якщо update-initramfs запускається оновленням ядра, воно генерує два initrd.img *, по одному для кожної моделі. Це не підходить до /bootрозділу (помилка - не вистачає місця) і генерація не закінчується.
Інго

1
Вважаю використовувати MODULES=list.
Інго
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.