Я подумал, что мог бы поэкспериментировать с btrfs в качестве корневого раздела, чтобы увидеть, как он справляется с повреждением файлов во время отключений питания. Но я не могу загрузить его.
Что я сделал:
на ПИ до переключения:
apt-get install btrfs-tools 2. С компьютера с Linux:
btrfs-convert / dev / sda2
В /etc/fstabзамен ext4наbtrfs
В /cmdline.txtзамен ext4наbtrfs
Я получаю панику ядра, если я пытаюсь сделать загрузку. Должен ли я сделать что-нибудь еще?
Если btrfs скомпилирован как модуль ядра, вам нужно создать initramfs для загрузки модуля при загрузке. На Raspian (и других производных Debian) update-initramfsэто самый простой способ сделать это.
Если initramfs-toolsустановлено, то каждый раз, когда apt-getустанавливается новое ядро, оно должно запускаться update-initramfsавтоматически.
Однако, если вы используете rpi-updateдля установки нового ядра, вам нужно будет запустить его update-initramfsвручную перед перезагрузкой в новом ядре:
sudo update-initramfs -u -k <kernel-version>
Это создаст или обновит initramfs в /boot/initrd.img-<kernel-version>.
Последний шаг - добавить его в конфигурацию загрузки: добавьте следующую строку в /boot/config.txt:
Мой быстрый тест показывает, что поддержка btrfs встроена в raspbian как внешний модуль, не связанный напрямую с ядром.
Это означает, что ядро должно иметь возможность загрузить этот модуль (который хранится в корневой файловой системе), прежде чем он сможет смонтировать корневую файловую систему. Очевидно, это не работает.
Подход 1:
Создайте свое собственное ядро и настройте его конфигурацию, чтобы предварительно связать btrfs. Настроить конфигурацию легко, если вы выяснили, как собрать и загрузить собственное ядро.
Подход 2:
Выполните перенастройку, чтобы ядро и модули находились в файловой системе ext4, а данные, которые вы хотите сжать, - в разделе btrfs.
Подход 2А:
Оставьте корневой раздел как ext4 и создайте новый раздел на основе btrfs, но это не поможет сократить установку ОС (если это ваша цель).
Подход 2В:
Создайте маленький загрузочный раздел, содержащий ядро и модули, оставив все остальное на btrfs. Я понятия не имею, как сделать это для загрузчика Пи, или каковы ограничения вокруг этого.
Как насчет копирования модулей btrfs в загрузочный раздел и загрузки их оттуда заранее?
GuySoft
3
Разве нельзя также начать с initrd.img?
Андерс
Да, и initrd.img выглядит как самый простой способ решить эту проблему! Я просто никогда не использовал это. Ищите документы на "mkinitrd".
ДонГар
Хмм, похоже, что 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. Например:
Ядро 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) - если вы обновляете существующую, вам нужно будет использовать update ( -u). Это создаст файл с именем вроде /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 и раскомментируйте INITRD=Yes
при необходимости загрузите 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
Во-первых, sudo apt upgradeесли он также обновит ядро, эта установка будет неудачной при загрузке, потому что новое ядро пытается загрузить старые initramfs, которые потерпят неудачу, и ядро не может загрузить драйверы btrfs. И это не простой способ исправить это, по крайней мере, с помощью chrootсистемы armhf.
Инго
Разве update-initramfs не будет вызываться при обновлении ядра?
Писквор покинул здание
1
Нет, Raspbian по умолчанию не может генерировать новые initramfs. Это не настроено для этого. apt upgradeПеред тем, как загружать новое ядро, вы всегда должны следить за своими действиями и генерировать initramfs вручную, если это необходимо. Не выполнимое задание для новичка, потому что провалить это драматично. Вы можете посмотреть, как я могу использовать ramdisk init (initramfs) при загрузке Raspberry Pi?
Инго
1
В ней есть небольшая ошибка, которую я только что обнаружил, но до сих пор не исправил. Ядро поддерживает две модели, например 4.14.98+и 4.14.98-v7+. Если update-initramfs запускается обновлением ядра, он сгенерирует два initrd.img *, по одному для каждой модели. Это не помещается на /bootраздел (ошибка - из-за нехватки места) и генерация не заканчивается.
Чтобы он нашел мой внешний корневой раздел BTRFS, мне нужно было явно указать UUID корневого раздела в загрузочном разделе
cmdline.txt
. Например:Вы можете определить UUID раздела BTRFS, используя
lsblk -f
.источник
Ядро Raspbian не включает поддержку
btrfs
по умолчанию; начальные этапы загрузки проходят нормально, но когда ядро загружается, оно не видит файловую систему, которую оно может смонтировать - и паникует. Решение существует: добавьте btrfs в качестве модуля ядра в initramfs. Во многом благодаря трем различным статьям я настроил это так: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
) новые initramfs для текущей версии ядра (uname -r) - если вы обновляете существующую, вам нужно будет использовать update (-u
). Это создаст файл с именем вроде /boot/initrd.img-*, где * - текущая версия ядра. Обратите внимание на сгенерированное имя (скрипт выведет его), мы будем использовать его на следующем шаге.update-initramfs -c -k $(uname -r)
/boot/config.txt
чтобы использовать этот initramfs, добавивinitramfs initrd.img-3.11.0+ followkernel
Имя файла без пути, это имя, созданное на предыдущем шаге; «followkernel» контролирует расположение в памяти ( документация config.txt ).Это решает текущее ядро, но, как указал @Ingo, обновление ядра сломало бы систему. Чтобы исправить это, я использовал его скрипты -обработчики ядра :
INITRD=Yes
/etc/kernel/postinst.d/initramfs-tools
chmod +x
этоНа данный момент у нас есть система, которая может использовать 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-карту)mkfs.btrfs /dev/mmcblk0p2
sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
sudo nano /mnt/etc/fstab
Должна быть строка, похожая на эту:
Измените это на это (новый тип FS - btrfs, и он использует параметры по умолчанию):
sudo umount /mnt
Найдите 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
sudo nano /mnt/cmdline.txt
Найдите эти два параметра
И заменить на
Обратите внимание, что UUID - это тот, который мы скопировали ранее, без кавычек.
sudo umount /mnt
На RPi убедитесь, что вы действительно работаете с корневого монтирования btrfs:
mount
/ dev / mmcblk0p2 on / type btrfs (rw, space_cache, subvol = /)
И вуаля! Не совсем по принципу «укажи и щелкни», но, стоя на плечах гигантов, я мог заставить это работать. (Сделал это в репо тоже.)
источник
sudo apt upgrade
если он также обновит ядро, эта установка будет неудачной при загрузке, потому что новое ядро пытается загрузить старые initramfs, которые потерпят неудачу, и ядро не может загрузить драйверы btrfs. И это не простой способ исправить это, по крайней мере, с помощьюchroot
системы armhf.apt upgrade
Перед тем, как загружать новое ядро, вы всегда должны следить за своими действиями и генерировать initramfs вручную, если это необходимо. Не выполнимое задание для новичка, потому что провалить это драматично. Вы можете посмотреть, как я могу использовать ramdisk init (initramfs) при загрузке Raspberry Pi?4.14.98+
и4.14.98-v7+
. Если update-initramfs запускается обновлением ядра, он сгенерирует два initrd.img *, по одному для каждой модели. Это не помещается на/boot
раздел (ошибка - из-за нехватки места) и генерация не заканчивается.MODULES=list
.