Fedora на ZFS.

Установка, настройка, эксплуатация.
Ответить
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

Fedora на ZFS.

Сообщение root »

Оглавление
Темы
Подготовка системы к клонированию
Настраиваем систему на целевом диске
Обновляем образ initramfs
Установка Grub2 на целевой диск
Замена Grub 2 на systemd-boot
Добавляем в bash_completion zfs
Автоматизация инсталляции Fedora на ZFS
Переход на ZFSBootMenu: практическое руководство
Отказываемся от GRUB полностью
Дополнительные материалы
Монтирование файловых систем
XFS: Файловая система
Перенос системы на другой диск (xfs_copy)
Перенос системы на другой диск (rsync)
Convert MBR to GPT
Исправляем нумерацию разделов на диске
Гибернация — режим сна
LUKS: Шифруем данные
Fedora_Root_On_ZFS.md статья на github
Reliably boot Fedora with root on ZFS статья с csparks.com
ZFS на Linux Debian 9.9 Видео на youtube

Нерешенные вопросы
  1. Не устраивает сборка при помощи dkms (требуется выполнение некоторых операций руками). Желательно мигрировать на akmods

Основные команды
Действия с пулом
  • zpool create tank /dev/disk/by-id/… — Создание пула с именем tank на блочном устройстве (диск, раздел) /dev/disk/by-id/… Крайне желательно указывать именно ссылку на устройство из каталога /dev/disk/by-id/
  • zpool import — Выводит список пулов доступных для импорта
  • zpool list — Выводит список импортированных пулов
  • zpool import tank — Импортирует в систему пул с именем tank
  • zpool export tank — После выполнения этой команды пул tank больше не отображается в системе. Перед продолжением предпринимается попытка размонтирования всех смонтированных файловых систем в пуле. Если размонтировать какую-либо из файловых систем не удается, ее можно размонтировать принудительно с помощью параметра
  • zpool add — расширяет пространство пула объёмом добавляемого блочного устройства (stripe)
  • zpool attach — присоединяет блочного устройство к массиву (MIRROR и др)
  • zpool detach — отсоединяет блочное устройство от массива (MIRROR и др)
Действия с файловой системой
  • zfs create tank/ws — Создать dataset ws в пуле tank
  • zfs destroy -r tank/ws — Удаляет все вложенные dataset рекурсивно
  • zfs set … =on/off tank/ws — Установить/отключить параметр для указанного dataset
  • zfs mount — Монтирование определённого dataset
  • zfs unmount — Размонтирование отдельного dataset

[/align]
Поскольку в дистрибутиве Fedora изначально используется systemd, то для идентификатора машины применяется /etc/machine-id который генерируется командой systemd-machine-id-setup, а файл /etc/hostid не создаётся. Для работы файловой системы ZFS он нужен, и его необходимо создать не взирая на предупреждение об устаревшем методе идентификации. Если genhostid отсутвует, то нужно пустановить пакет initscripts, в который он входит
ZFS использует свой собственный механизм для хранения идентификатора хоста, который называется hostid. hostid хранится в метаданных пула ZFS и используется для идентификации узла, на котором находится пул.

Код: Выделить всё

genhostid
Проверить существование файла hostid можно примерно так

Код: Выделить всё

[ -f /etc/hostid ] && echo true
Устанавливаем репозиторий zfsonlinux для Fedora в систему

Код: Выделить всё

dnf install -y https://zfsonlinux.org/fedora/zfs-release-2-5$(rpm --eval "%{dist}").noarch.rpm
Инсталлируем необходимое программное обеспечение

Код: Выделить всё

dnf install  gcc make kernel-devel kernel-headers dkms zfs-dracut zfs-dkms zfs grub2-efi-x64-modules
  • dkms - Этот пакет содержит платформу для динамической сборки модулей ядра (DKMS)
  • zfs-dracut - zfs-dracut позволяет dracut создавать образы initramfs с поддержкой ZFS
  • zfs-dkms - Пакет содержит модули ZFS для dkms
  • zfs - Пакет содержит основные утилиты командной строки ZFS.
  • grub2-efi-x64-modules - Этот пакет предоставляет дополнительные модули для сборки вашего собственного grub.efi.
Fedora предоставила пакет zfs-fuse, он уже установлен в системе. Затем следует использовать команду dnf swap для замены существующих пакетов fuse на пакеты ZFS.

Код: Выделить всё

dnf swap zfs-fuse zfs
Грузим zfs модули

Код: Выделить всё

modprobe zfs
Проверяем загрузились ли модули ядра zfs

Код: Выделить всё

lsmod |grep zfs
Пересобираем образ initramfs для загруженного ядра

Код: Выделить всё

dracut -f
Теперь можно перезапустить систему и снова проверить загрузились ли модули ядра для zfs

Код: Выделить всё

reboot
lsmod |grep zfs
При успешном запуске zfs можно переходить к разметке диска для новой файловой системы.
Подготовка дискового пространства на новом диске
Теперь подготовим разделы на свободном диске и создаём следующие разделы
  • EFI System Partition - 512 MB
  • ZFS POOL - Всё остальное пространство

Код: Выделить всё

parted -a optimal -s /dev/sda 'mklabel gpt' 'mkpart primary fat32 1MiB 513MiB' \
   'name 1 "EFI System Partition"' 'set 1 esp on' \
   'mkpart primary 513MiB -1' 'name 2 "ZFS"'
Сделаем теперь на разделе EFI файловую систему FAT

Код: Выделить всё

mkfs.fat -F32 /dev/sda1

Создаём структуру пулов и набора данных ZFS
Предлагаемая структура улов и набора данных такова:
tank/
tank/boot
tank/home
Создадим пул ZFS и корневую файловую систему с оптимальными параметрами

Код: Выделить всё

zpool create -d -o feature@allocation_classes=enabled \
    -o feature@async_destroy=enabled \
    -o feature@bookmarks=enabled \
    -o feature@embedded_data=enabled \
    -o feature@empty_bpobj=enabled \
    -o feature@enabled_txg=enabled \
    -o feature@extensible_dataset=enabled \
    -o feature@filesystem_limits=enabled \
    -o feature@hole_birth=enabled \
    -o feature@large_blocks=enabled \
    -o feature@lz4_compress=enabled \
    -o feature@project_quota=enabled \
    -o feature@resilver_defer=enabled \
    -o feature@spacemap_histogram=enabled \
    -o feature@spacemap_v2=enabled \
    -o feature@userobj_accounting=enabled \
    -o feature@zpool_checkpoint=enabled \
    -o ashift=12 -o altroot=/sysroot \
    -O atime=off -O compression=lz4 \
    -O xattr=sa -O normalization=formD \
    -O mountpoint=/ -O acltype=posixacl \
    tank /dev/disk/by-id/ata-VBOX_HARDDISK_VB08f83824-88e6cb2e-part2
??? -o multihost=on
Указываем параметр altroot равным /sysroot чтобы не менять значение перед перезагрузкой.
При создании пула указываются два типа параметров:
  • -o — параметры пула
  • -O — параметры корневого dataset
Теперь разберём значения основных параметров
  • ashift - Размер физ. сектора (9,12) степень двойки 2^9=512 или 2^12=4048=4K
    Внимание: Если будете переносить эту схемуна реальное железо (современные HDD с Advanced Format или NVMe/SSD), обязательно ставьте -o ashift=12 (размер сектора 4К, 2¹²). Если оставить 9 на диске с физическими 4К-секторами, пул будет работать, но вы получите дичайшую просадку производительности на операциях записи (Write Amplification) из-за постоянной перезаписи соседних блоков.
  • altroot - Смещение относительно какого-то каталога точки монтирования
  • atime - Отключение обновления времени доступа к файлу при каждом обращении
  • canmount - Отключаем монтирование корневого dataset
  • compression - Метод сжатия данных для создаваемого dataset
  • xattr - Место хранения расширенных атрибутов, по умолчанию хранятся в виде скрытых файлов (только для Linux), что негативно влияет на производительность
  • -m none - Отключаем точку монтирования для корневого dataset
  • -f - Форсированное создание пула (подавляет предупреждения)
  • tank - Имя пула
  • /dev/... - Раздел или диск под создаваемый пул
  • multihost - осуществляется проверка, что пул уже кем-то импортирован
  • normalization -
Создаём dataset для файловой системы под домашние каталоги пользователей. Долее можно не указывать o mountpoint, точка монтирования значится автоматически исходя из названия dataset

Код: Выделить всё

zfs create \
    -o compression=on -o exec=off -o setuid=off \
    tank/home
setuid=off — запрещает выполнение программ от имени владельца файла в файловой системе для домашних каталогов пользователей.
-o exec=off — с файловой системы запрещаем выполнять программы.
Создаём dataset для файловой системы boot.

Код: Выделить всё

zfs create \
    -o compression=on -o atime=off \
    tank/boot

Теперь устанавливаем на параметр bootfs значение для dataset с загрузочной файловой системой

Код: Выделить всё

zpool set bootfs=tank/boot tank
Пример создания области подкачки swap
В данном случае создаём zfs volume, а не dataset. Том zfs является блочным устройством, а dataset - НЕТ

Код: Выделить всё

zfs create -V 4G -b $(getconf PAGESIZE) \
    -o logbias=throughput -o sync=always \
    -o primarycache=metadata -o secondarycache=none \
    -o com.sun:auto-snapshot=false -o compression=zle \
    tank/swap
Монтируем EFI раздел в соответствующий каталог вновь созданной структуры ZFS

Код: Выделить всё

mkdir -p /sysroot/boot/efi && mount /dev/sdb1 /sysroot/boot/efi
Переносим данные на диск с ZFS
Перед переносом данных на целевой диск нужно создать lvm snapshot либо остановить все основные сервисы и выполнить синхронизацию исходного диска с целевым

Код: Выделить всё

rsync -axHAWXS --numeric-ids --info=progress2  \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found/*","/sysroot"} \
/* /sysroot
Если возникла потребность в перезапуске или в поднятии существующего пула на иной системе, то нужно указывать ALTROOT параметром '-R /sysroot/tank' и тогда вся структура датасетов будет смонтирована по своим местам относительно значения ALTROOT

Код: Выделить всё

zpool import -R /sysroot tank
Последний раз редактировалось root 02 окт 2026 16:13, всего редактировалось 6 раз.
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

📝

Сообщение root »


Меняем корень файловой системы на каталог в который только что скопировали данные с исходного диска
  • Монтируем виртуальную файловую систему proc (необходима для работы ps, lsof и генерации initramfs)
  • Рекурсивно пробрасываем интерфейс ядра к устройствам (sysfs) и изолируем изменения в chroot
  • Рекурсивно пробрасываем файлы dev (необходимо для обнаружения ZFS-пулов и дисков через dracut)
  • Пробрасываем /run (необходимо для работы systemd, временных файлов блокировок, сокетов, LVM/LUKS и импорта пулов ZFS)
  • Обязательно монтируем переменные EFI (NVRAM). Без них утилиты grub2-mkconfig, efibootmgr и zfsbootmenu не смогут управлять порядком загрузки и записями в BIOS/материнской плате!
  • Монтируем изолированный tmpfs для временных файлов внутри chroot
  • Входим в изолированное окружение нашей системы Fedora

Код: Выделить всё

mount -t proc /proc /mnt/proc
mount --rbind /sys /mnt/sys
mount --make-rslave /mnt/sys
mount --rbind /dev /mnt/dev
mount --make-rslave /mnt/dev
mount --rbind /run /mnt/run
mount --make-rslave /mnt/run
mount --rbind /sys/firmware/efi/efivars /mnt/sys/firmware/efi/efivars
mount --make-rslave /mnt/sys/firmware/efi/efivars
mount -t tmpfs tmpfs /mnt/sys/tmp
chroot /mnt /bin/bash
После chroot может потребоваться загрузить локальную конфигурацию bash:

Код: Выделить всё

source /etc/profile &&  source ~/.bashrc
Совет: При желании создайте уникальное приглашение, чтобы иметь возможность различать вашу среду chroot:

Код: Выделить всё

export PS1="(chroot) $PS1"
Определяем UUID для загрузочного раздела на целевом диске и добавляем его отдельной строкой в fstab

Код: Выделить всё

blkid /dev/sda1 | cut -d " " -f2 >> /etc/fstab
Вносим изменения в файл fstab
Меняем UUID для EFI раздела и добавляем подключение ZFS-тома для swap
e /etc/fstab

Код: Выделить всё

UUID=69CB-015C           /boot/efi         vfat        umask=0077,shortname=winnt 0 2
/dev/zvol/swap           none              swap        sw                         0 0

Очередная подстава от systemd, при попытке включить сервис в chroot возникает ошибка:
System has not been booted with systemd as init system (PID 1). Can't operate

Код: Выделить всё

systemd-chroot --systemd-override
Эта команда запустит systemd-окружение внутри chroot-окружения. После этого можно пробовать активировать нужные нам сервисы

Код: Выделить всё

systemctl enable zfs-import-cache.service
systemctl enable zfs-import-scan.service
systemctl enable zfs-mount.service
systemctl enable zfs-share.service
systemctl enable zfs-zed.service
systemctl enable zfs.target
Последний раз редактировалось root 26 авг 2026 17:31, всего редактировалось 1 раз.
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

📝

Сообщение root »


Добавляем ZFS_MOUNT ZFS_UNMOUNT в /etc/default/zfs

Код: Выделить всё

grep -q "ZFS_MOUNT" /etc/default/zfs 2> /dev/null || echo "
ZFS_MOUNT=yes
ZFS_UNMOUNT=yes
" | tee -a /etc/default/zfs
обновляем строку add_dracutmodules+ конфигурации в /etc/dracut.conf

Код: Выделить всё

add_dracutmodules+=" zfs "
???
e /usr/lib/dracut/dracut-init.sh примерная строка 1073

Код: Выделить всё

После строк
     local _optional="-o"
     local _silent
     local _ret
добавить
	if (($# == 0)); then
		return 0
	fi
 перед строкой
     [[ $no_kernel = yes ]] && return
обновляем initramfs

Код: Выделить всё

dracut /boot/initramfs-$(uname -r).img $(uname -r) --force
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

📝

Сообщение root »


Показать
Изменяем параметры загрузчика GRUB в /etc/default/grub
исходные строки

Код: Выделить всё

GRUB_CMDLINE_LINUX="rd.lvm.lv=fedora_fs/root ...
GRUB_ENABLE_BLSCFG=true
И добавляем отсутствующие параметры или меняем значения у существующих

Код: Выделить всё

GRUB_CMDLINE_LINUX="boot=zfs rpool=tank bootfs=tank/boot ...
GRUB_PRELOADED_MODULES="zfs"
GRUB_ENABLE_BLSCFG=false
Устанавливаем Grub2 на клонируемый диск

Код: Выделить всё

ZPOOL_VDEV_NAME_PATH=YES grub2-install --target=x86_64-efi --efi-directory=/boot/efi --force
Выполняется установка для платформы x86_64-efi.
Установка завершена. Ошибок нет.
Обновление конфигурации Grub2

Код: Выделить всё

ZPOOL_VDEV_NAME_PATH=YES grub2-mkconfig -o /etc/grub2-efi.cfg
Теперь изменим расположение grub.cfg и пересоздадим символическую ссылку /etc/grub2-efi.cfg

Код: Выделить всё

mv /boot/efi/EFI/fedora/grub.cfg /boot/grub2/grub.cfg
rm /etc/grub2-efi.cfg
ln -s /boot/grub2/grub.cfg /etc/grub2-efi.cfg

При обновлении конфигурации grub2 может вылезать ошибка

Код: Выделить всё

grub2-mkconfig -o /etc/grub2-efi.cfg
/usr/sbin/grub2-probe: ошибка: не удалось получить канонический путь "/dev/ata-VBOX_HARDDISK_VBf6a8f669-2de5ab43-part2".
Исправление ошибки Grub2 связанной с именами путей устройств пула
Позже нам нужно будет запустить скрипт с именем grub2-mkconfig. Этот скрипт использует команду zpool status для вывода списка компонентов пула. Но когда эти компоненты не являются простыми именами устройств, скрипт завершается ошибкой. Самое простое решение - добавить системную переменную среды. Нужно определить переменную для тек сеанса и создать файл e /etc/profile.d/grub2_zpool_fix.sh с аналогичной строкой:

Код: Выделить всё

export ZPOOL_VDEV_NAME_PATH=YES

Подготовка системы к перезапуску.
Завершаем chroot, рекурсивно демонтируем файловые системы в каталоге /sysroot и и экспортируем pool zfs из системы

Код: Выделить всё

# 1. Мгновенно обрываем все shared-связи виртуальных ФС хоста (без этого пул не отпустит)
umount -fl /sysroot/dev /sysroot/sys /sysroot/proc /sysroot/run /sysroot/sys/firmware/efi/efivars
# 2. Если монтировали отдельный legacy-раздел /boot или /boot/efi с реального диска
umount -f /sysroot/boot/efi 2>/dev/null
# 3. Экспортируем пул (он сам всё размонтирует и чисто закроется)
zpool export tank
Последний раз редактировалось root 02 окт 2026 14:24, всего редактировалось 2 раза.
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

📝

Сообщение root »


Grub 2 имеет существенный недостаток применительно к ZFS. Пул собранный с некоторыми опциями довольно плохо воспринимается ZFS-модулем от Grub. Именно по данной причине и производится замена на systemd-boot
Шаг 1.
Удаляем Grub 2

Код: Выделить всё

dnf remove grubby grub2\* shim\* memtest86\*
rm -rf /boot/grub2 && rm -rf /boot/loader
Шаг 2.
Настройка точки монтирования. Откроем файл /etc/fstab в текстовом редакторе:
e /etc/fstab

Код: Выделить всё

UUID=69CB-015C  /boot/efi vfat umask=0077,shortname=winnt 0 2
Убедимся, что точка монтирования ESP раздела задана корректно и UUID совпадает с номером EFI-раздела диска-клона
Здесь 69CB-015C — это UUID, который можно определить при помощи blkid. Добавим параметр монтирования umask=0077 (при отсутствии), т.к. файловая система FAT32 не поддерживает права доступа и любой пользователь может вносить любые изменения, что для нас не приемлемо.
Сохраним изменения в файле.

Шаг 3.
Настройка параметров ядра
В данной конфигурации параметры ядра будут указаны в файле /etc/kernel/cmdline в формате обычной строки, разделённые пробелом:

Код: Выделить всё

cat /proc/cmdline | cut -d ' ' -f 2- | tee /etc/kernel/cmdline && chmod 644 /etc/kernel/cmdline
В данном примере будут автоматически использованы параметры текущего загруженного ядра из /proc/cmdline.
В результате должен получиться файл /etc/kernel/cmdline с подобным содержимым:

Код: Выделить всё

root=ZFS=tank ro boot=zfs rpool=tank bootfs=tank rhgb quiet
При необходимости внесём соответствующие правки:

Код: Выделить всё

e /etc/kernel/cmdline
Удаляем файл zpool.cache перед сборкой микроядра системы. В процессе сборки он (если есть) попадает в микроядро системы и препятствует нормальному запуску

Код: Выделить всё

rm /etc/zfs/zpool.cache
Шаг 4.
Установка systemd-boot на раздел ESP:

Код: Выделить всё

bootctl --path=/boot/efi install
Инициируем пересборку initrd ядра, а также сгенерируем новые файлы конфигурации:

Код: Выделить всё

kernel-install add $(uname -r) /lib/modules/$(uname -r)/vmlinuz
Шаг 5.
Перезагрузка системы. Проверим всё ли сделано верно и перезагрузим систему для применения изменений:
Завершаем chroot, рекурсивно демонтируем файловые системы в каталоге /sysroot и и экспортируем pool zfs из системы

Код: Выделить всё

exit
umount -R /sysroot (if you have a legacy boot partition)
zfs umount -a
zpool export tank
systemctl reboot
Если всё было сделано верно, Fedora успешно загрузится при помощи EFIStub под управлением systemd-boot. В противном случае следует восстановить резервную копию, либо воспользоваться chroot с LiveUSB для решения возникших проблем.
При обрыве запуска системы нужно единожды выполнить импорт пула, из режима восстановления, с параметром "-f" и перезапустить машину

Код: Выделить всё

zpool import -R /sysroot -f
reboot

Настройка параметров загрузки
Параметры загрузки допускается изменять в файлах

Код: Выделить всё

/boot/efi/loader/loader.conf
/boot/efi/loader/entries/*
cat /boot/efi/loader/entries/9ec751ae2d584182b2b2c596917bafea-5.4.13-201.fc31.x86_64.conf

Код: Выделить всё

title      Fedora 31 (Server Edition)
version    5.4.13-201.fc31.x86_64
machine-id 9ec751ae2d584182b2b2c596917bafea
options    root=ZFS=tank ro boot=zfs rpool=tank bootfs=tank rhgb quiet
linux      /9ec751ae2d584182b2b2c596917bafea/5.4.13-201.fc31.x86_64/linux
initrd     /9ec751ae2d584182b2b2c596917bafea/5.4.13-201.fc31.x86_64/initrd
cat /boot/efi/loader/loader.conf

Код: Выделить всё

timeout 5
#console-mode keep
default 9ec751ae2d584182b2b2c596917bafea-*

При обновлении ядра в системе может не правильно или несвоевременно собираться модули ядра. Данная проблема решается в одну команду, нужно только пересобрать модули ядра под конкретную версию:

Код: Выделить всё

dkms autoinstall -k 5.4.14-200.fc31.x86_64
подставив номер только что установленного ядра
А так же инициируем пересборку initrd ядра, и сгенерируем новые файлы конфигурации:

Код: Выделить всё

kernel-install add 5.4.14-200.fc31.x86_64 /lib/modules/5.4.14-200.fc31.x86_64/vmlinuz
Проверить генерацию минимального ядра можно по дате и времени создания файла

Код: Выделить всё

ll /boot/efi/9ec751ae2d584182b2b2c596917bafea/5.4.14-200.fc31.x86_64/
итого 38M
-rwx------ 1 root root  28M фев  1 18:19 initrd
-rwx------ 1 root root 9,9M фев  1 18:19 linux
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

Сообщение root »


Код: Выделить всё

wget -O /etc/bash_completion.d/zfs https://raw.githubusercontent.com/zfsonlinux/zfs/master/contrib/bash_completion.d/zfs
chmod -R  ugo+x /etc/bash_completion.d/zfs
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

📝

Сообщение root »


Посетите YouTube: OpenZFS Basics, если вы новичок в ZFS.
На github найден скрипт fedora-on-zfs автоматизирующий процесс установки Fedora на файловую систему ZFS. Для работы этого скрипта требуется как минимум два физических диска. Он создаст зеркальный пул файловых систем ZFS на предоставленных дисках, а затем установит Fedora Linux на новый пул (т.е. root на ZFS).
Можно использовать ZFS с одним диском. Однако при обнаружении ошибки ZFS приостановит все операции ввода-вывода на диск, и ваша система зависнет. При использовании нескольких дисков ZFS "самовосстанавливается", получая данные с других дисков, и продолжает работать нормально. Рассмотрите возможность использования Btrfs, если вам не нужна избыточность нескольких дисков или поддержка загрузки системы при отказе диска.
Скрипт получит свежую копию kickstart сценариев с Fedora с https://pagure.io/fedora-kickstarts/tree/main, если репозиторий fedora-kickstarts еще не был клонирован. Другие сценарии кикстартов fedora-disk-*.ks также должны работать, но их выполнение займет больше времени. Альтернативой использованию стандартного кикстарта Fedora Workstation/KDE/ и другие может быть сначала установка Fedora Linux с корнем на ZFS с помощью минимального кикстарта, а затем использование команды типа

Код: Выделить всё

dnf group install "KDE Plasma Workspaces" 
для обновления до одного из больших окружений рабочего стола. Этот сценарий не обязательно запускать из живого образа, но это может быть самым простым вариантом, поскольку типичный живой образ имеет необходимое программное обеспечение (curl, rpm2cpio, gpg, qemu и т. д.).
Этот скрипт настроит Fedora Linux с загрузчиком systemd-boot по умолчанию. Он также создаст раздел ESP в начале каждого физического диска и установит bootsync для их синхронизации. При такой конфигурации можно будет загрузить систему в случае отказа одного из дисков (независимо от того, какой именно диск вышел из строя).
Если вы выберете кикстарт fedora-disk-minimal.ks, вам будет предложено ответить на вопрос, хотите ли вы зашифровать свой домашний каталог и установить скрипт homelock для автоматизации блокировки и разблокировки домашнего каталога при входе и выходе из системы. Если вы ответите "y", скрипт homelock будет добавлен в стек PAM, и он будет использовать ваши учетные данные для входа в систему, чтобы разблокировать ваш домашний каталог. Когда/если вы измените пароль своей учетной записи, вам нужно будет вручную изменить пароль на файловой системе домашнего каталога ZFS, чтобы он соответствовал. Homelock работает только при входе в систему через консоль, поэтому возможность установки скрипта homelock появляется только при использовании кикстарта fedora-disk-minimal.ks. Если вам нужен скрипт homelock и графический интерфейс, вы можете запустить оконный менеджер Sway с консоли (TTY). Вас спросят, хотите ли вы добавить оконный менеджер Sway с дополнительными сценариями для его автозапуска после входа в систему на TTY1, если вы выберете кикстарт fedora-disk-minimal.ks.
Приведу лиши некоторые из доступных вариантов kickstart сценариев:
  • fedora-disk-kde.ks
  • fedora-disk-minimal.ks
  • fedora-disk-server.ks
  • fedora-disk-workstation.ks
  • fedora-kde-common.ks
  • fedora-minimal-common.ks
  • fedora-repo.ks
  • fedora-server-vm-full.ks
  • fedora-workstation-common.ks
Этот скрипт также настроит установленную систему так, чтобы исключить ZFS и ядро Linux из обычного процесса обновления командой dnf update. Это сделано потому, что нередко в Fedora обновления ZFS не работают, когда новые ядра Linux появляются раньше, чем ZFS становится совместимой с ними. Вместо этого пользователю следует использовать zfs-update для обновления ZFS и ядра Fedora Linux. Эти переопределения и скрипты установлены в каталоге /usr/local/bin. Вы можете удалить эти скрипты, чтобы вернуть поведение к прежнему, если захотите.
Примечание: Этот сценарий установки по умолчанию устанавливает предыдущий релиз Fedora Linux. Это сделано намеренно, поскольку может случиться так, что самый новый выпуск будет поставляться с ядром, которое еще не поддерживается ZFS. Все исправления безопасности перенесены в предыдущий релиз. Если вы хотите попробовать самый новый выпуск, вы можете указать номер версии Fedora Linux, которую вы хотите установить, в качестве первого параметра сценария установки. Однако я рекомендую установить предыдущий релиз, а затем выполнить

Код: Выделить всё

dnf upgrade --refresh
dnf install dnf-plugin-system-upgrade
dnf system-upgrade download --releasever=$(($(rpm -E %fedora) + 1))
dnf system-upgrade reboot
(И сделайте снимок root/0 перед обновлением, чтобы можно было откатить корневую файловую систему в случае, если это не заработает.
Примечание: В этом сценарии установки по умолчанию настроена загрузка UEFI. Если вам нужна традиционная загрузка BIOS, раскомментируйте строку BIOSBOOT='biosboot.ks' в config/evariables.conf.
Примечание: Из-за особенностей работы живых образов Fedora Linux, а также из-за того, что этот скрипт использует QEMU для запуска другого экземпляра ОС Fedora Linux, для его выполнения требуется большой объем оперативной памяти. Если в вашей системе недостаточно оперативной памяти для выполнения этого сценария, вы можете обойти эту проблему, подключив дополнительный USB-накопитель и используя его для создания дополнительной "виртуальной" памяти (swap). Используйте

Код: Выделить всё

mkswap --force --label swap /dev/sdZ,
чтобы отформатировать USB-устройство как память подкачки. Затем перезагрузите живой образ Fedora Linux и добавьте параметр ядра systemd.swap-extra=/dev/disk/by-label/swap, чтобы активировать его. (Возможно, вы захотите добавить параметр "3" в список параметров ядра, чтобы избежать загрузки полного графического окружения. Последние живые образы Fedora Linux позволят вам войти в систему с правами root и пустым паролем.) Дополнительная память должна быть видна в выводе команды free -m. (Внимание: Добавление памяти подкачки в качестве обходного пути для недостаточной оперативной памяти сделает установку очень медленной!)
Для работы скрипта требуются следующие пакеты:
  • git
  • edk2-ovmf
  • qemu
Тестирование скрипта fedora-on-zfs проводилось на виртуальной машине VirtualBox со следующими характеристиками
  • CPU — 4 core
  • RAM — 8 GB, было увеличено (с 4 GB) дабы избежать слишком медленной работы (если не полного зависания)
  • DISK — 32 GB X 3
С моей конфигурацией установка заняла чуть больше часа. Скрипт запускал не с LiveCD, как говориться в описании к скрипту, а с отдельного диска с установленной Fedora 40. Именно по этой причине в описанной мной конфигурации указано именно три диска. Я посчитал установка из рабочей системы будет менее проблемной чем с Live носителя.
Подготовка системы и запуск скрипта
Сначала установим недостающие пакеты в транзитную систему. У меня не хватало всего трёх пакетов. (при запуске с LiveCD недостающих пакетов быть не должно)

Код: Выделить всё

dnf install git edk2-ovmf qemu
Или менее затратный по объёму жёсткого диска вариант которого тоже хватает для обеспечения работоспособности скрипта.

Код: Выделить всё

dnf install git-core qemu-system-x86-core edk2-ovmf
Затем клонируем скрипт с git-репозитория и пробуем его запустить в надежде что он запустится и отработает как нужно.
Примечание: если вы знаете, что конкретное зеркало в вашем регионе лучше/быстрее, чем то, которое dnf может предложить при помощи автоопределения, вы можете попробовать установить переменную FREP в config/evariables.conf, чтобы она указывала на ВАШЕ зеркало.

Код: Выделить всё

git clone https://github.com/gregory-lee-bartholomew/fedora-on-zfs.git && cd fedora-on-zfs
./install fedora-disk-minimal.ks /dev/sdX /dev/sdY
Установка конкретной версии релиза (например 40)

Код: Выделить всё

./install 40 fedora-disk-minimal.ks /dev/sdX /dev/sdY
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

📝

Сообщение root »


Введение
Это практическое руководство родилось из реального опыта настройки Fedora на ZFS. Собраны реальные проблемы и решения при переходе к ZFSBootMenu на ZFS. Система устанавливалась скриптом fedora-on-zfs и все дополнительные сервисы по синхронизации разделов EFI взяты оттуда. Сервис монтирования отключен, а сервис синхронизации переписан практически полностью.
Материал ориентирован на администраторов, которым важна предсказуемость и контроль системы.
1. Базовая структура ZFS
Основные команды:

Код: Выделить всё

# Пулы
zpool list
zpool status -v
zpool status root

# Датасеты
zfs list
zfs list -t snapshot
zfs list -t filesystem

# Свойства
zfs get all
zfs get mountpoint root/0
zpool get bootfs root
Типовая структура:

Код: Выделить всё

root (pool)
├── root/0
│   ├── boot/
│   └── home/
└── root/0@13-03-2026
Важно:
Каталог /boot должен быть внутри root/0, не отдельным датасетом — иначе ZFSBootMenu не увидит ядра.
2. Структура ESP

Код: Выделить всё

sda
├── sda1 (ESP, boot@a)
└── sda2 (ZFS)

sdb
├── sdb1 (ESP, boot@b)
└── sdb2 (ZFS)
Монтирование:

Код: Выделить всё

/dev/sda1 → /boot@a
/dev/sdb1 → /boot@b
/boot@a/efi → /boot/efi (bind)

3. /etc/fstab

Код: Выделить всё

PARTLABEL=boot@a /boot@a vfat umask=0077,context=system_u:object_r:boot_t:s0,shortname=lower,flush,nofail 0 0
PARTLABEL=boot@b /boot@b vfat umask=0077,context=system_u:object_r:boot_t:s0,shortname=lower,flush,nofail 0 0

/boot@a/efi /boot/efi none bind,x-systemd.after=/boot@a 0 0
Ключевые моменты:
  • nofail — система загрузится без одного ESP
  • x-systemd.after — порядок монтирования
  • umask=0077 — безопасность

4. Синхронизация ESP
Исправленный скрипт bootsync.sh:

Код: Выделить всё

#!/usr/bin/bash
exec 1>&2

# Проверяем, смонтирован ли /boot/efi
if ! mountpoint -q "/boot/efi"; then
    echo "/boot/efi is not mounted"
    exit 1
fi

# Получаем устройство активного ESP (bind-монтирование /boot/efi)
SRC=$(findmnt -n -o SOURCE /boot/efi)
SRC=${SRC%%\[*}       # Убираем возможные скобки

# Собираем список всех ESP по каталогам /boot@*
mapfile -t ESPS < <(for d in /boot@*; do
    [[ -d "$d" ]] && echo "$d"
done)

# Проверяем, что ESP найдены
if [[ ${#ESPS[@]} -eq 0 ]]; then
    echo "No ESP mounts found (/boot@*)"
    exit 1
fi

# Определяем активный ESP
ACTIVE=""
for esp in "${ESPS[@]}"; do
    DEV=$(findmnt -n -o SOURCE "$esp")
    DEV=$(realpath "$DEV")
    if [[ "$DEV" == "$SRC" ]]; then
        ACTIVE="$esp"
        break
    fi
done

if [[ -z "$ACTIVE" ]]; then
    echo "Active ESP not found"
    exit 1
fi

# Синхронизация остальных ESP
for esp in "${ESPS[@]}"; do
    [[ "$esp" == "$ACTIVE" ]] && continue
    echo "Syncing $ACTIVE -> $esp"
    rsync -a --delete "$ACTIVE/efi/" "$esp/efi/"

    # Обновляем SELinux контексты для VFAT
    restorecon -R "$esp/efi"
done
systemd unit bootsync.service:

Код: Выделить всё

[Unit]
Description=Sync ESP
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/etc/bootsync/bootsync

[Install]
WantedBy=multi-user.target

5. ZFSBootMenu

Код: Выделить всё

mkdir -p /boot/efi/zbm /boot@b/zbm
curl -L https://get.zfsbootmenu.org/efi -o /boot/efi/zbm/zbm.efi
cp /boot/efi/zbm/zbm.efi /boot@b/efi/zbm/

Код: Выделить всё

zpool set bootfs=root/0 root
zfs set org.zfsbootmenu:commandline="ro rhgb quiet video=1600x900" root/0
UEFI записи:

Код: Выделить всё

efibootmgr -c -d /dev/sdb -p 1 -L "ZFSBootMenu (Backup)" -l \\EFI\\zbm\\zbm.efi
efibootmgr -c -d /dev/sda -p 1 -L "ZFSBootMenu" -l \\EFI\\zbm\\zbm.efi
Важно:
  • UEFI не чувствителен к регистру
  • вторая запись обязательна (failover)
  • основную запись создаём последней, чтобы не выставлять приоритеты запуска

6. Снапшоты

Код: Выделить всё

zfs snapshot root/0@work-system-$(date +%Y-%m-%d)
zfs list -t snapshot
zfs destroy root/0@work-system-13-03-2026
Различия:
  • Удаление — удаляется только точка
  • Rollback — откат с потерей изменений
  • Clone — безопасный эксперимент

7. Ядра
Важно:
ZFSBootMenu видит ядра только в /boot

Код: Выделить всё

/boot/vmlinuz-*
/boot/initramfs-*.img
Если Fedora положила ядра в machine-id:

Код: Выделить всё

cp /boot/.../linux /boot/vmlinuz-...
cp /boot/.../initrd /boot/initramfs-...
Если вы копировали ядра вручную, проверьте права. Установленные через dnf ядра имеют права 644,
а скопированные вручную могут остаться с 700. Это не влияет на загрузку через ZFSBootMenu,
но для порядка их можно унифицировать:

Код: Выделить всё

chmod 644 /boot/vmlinuz-*
chmod 644 /boot/initramfs-*.img
⚠️ Важное замечание по SELinux
После перевода системы на ZFSBootMenu у нового загрузчика возможны ошибки доступа к /boot и другим системным каталогам.
Чтобы исправить:

Код: Выделить всё

# Переводим SELinux в мониторинг (Permissive) для диагностики
setenforce 0
Либо при запуске системы указываем параметр ядра. Отключение SELinux параметром 'selinux=0' не помогает, должен быть включен и работать хотя бы в permissive режиме, для обновления контекстов SELinux.

Код: Выделить всё

enforcing=0
Есть ещё один параметр который заставляет произвести перемаркировку контекстов при запуске системы

Код: Выделить всё

autorelabel=1

# После успешной загрузки и проверки системы. Восстанавливаем правильные контексты SELinux

Код: Выделить всё

restorecon -R /
Совет: выполнять restorecon после монтирования всех ESP и bind-точек (/boot/efi), чтобы контексты применились корректно.
8. Диагностика

Код: Выделить всё

systemctl --failed
journalctl -b -1 -p err
systemd-analyze blame
systemd-analyze critical-chain

Код: Выделить всё

mount | grep boot
lsblk -f
Если загрузка длится дольше обычного, полезно посмотреть, какой этап занимает время:

Код: Выделить всё

systemd-analyze blame | head -10
Иногда задержка происходит после переключения корня (switch-root). В этом случае стоит заглянуть в логи:

Код: Выделить всё

journalctl -b -1 | grep -E "initrd|switch-root|timeout"
Задержки часто связаны не с ZFS, а с сетевыми сервисами (NetworkManager, firewalld, dnscrypt-proxy),
которые стартуют уже после передачи управления реальной корневой файловой системе.
9. Типовые проблемы
ZFSBootMenu не видит ядра
  • ядра не в /boot
/boot/efi не монтируется
  • Нет зависимости в fstab
Долгая загрузка
  • Проверить systemd и fstab
Нет загрузки при отказе диска
  • Нет второй UEFI записи
Plymouth зависает или прогресс-бар смещён вправо
При запуске системы из GRUB с высоким разрешением идет попытка запустить Plymouth на более низком, дефолтном разрешении. При переходе на пониженное разрешение ломается Plymouth. Так что VBOXSVGA тут не причём. Кстати, попытка перевести виртуалку на VMSVGA ни к чему хорошему не приведёт. Да, разрешение прыгать перестанет, но нормально грузиться модули ядра для видеоадаптера не будут
Выход один: При VBOXSVGA сообщить ядру разрешение параметром video примерно так:

Код: Выделить всё

video=1600x900
и тогда при наличии параметров

Код: Выделить всё

rhgb quiet
Plymouth будет работать корректно
Загрузка системы занимает много времени, а в логах сотни сообщений TIMEOUT от dnscrypt-proxy
  • Причина: DNSCrypt требует точного времени, а chronyd не может его получить без DNS.
  • Решение: прописать в /etc/chrony.conf IP-адреса NTP-серверов вместо доменных имён.
Например, для России: server 194.190.168.1 iburst
10. Чек-лист

Код: Выделить всё

zpool status
zpool get bootfs root
zfs list

mount | grep boot
efibootmgr

systemctl --failed
systemctl status bootsync

ls /boot/vmlinuz-*

Заключение
Конфигурация даёт:
  • отказоустойчивость
  • работу со снапшотами
  • безопасные эксперименты через clone
  • полный контроль загрузки
Последний раз редактировалось root 02 окт 2026 16:13, всего редактировалось 25 раз.
Аватара пользователя
root
Site Admin
Сообщения: 501
Зарегистрирован: 15 авг 2026 01:31

📝

Сообщение root »

В данном руководстве задокументирован процесс полной интеграции ZFSBootMenu в Fedora Linux 44 (Server Edition) с отказом от GRUB и BLS-структуры на ESP-разделе.
Key Requirements
  1. Минимализм: Исключение ненужных обращений к ESP/BLS.
  2. Чистота системы: Отказ от нештатных скриптов и хаков в пользу нативных плагинов `kernel-install`.
  3. Автоматизация: Полная поддержка DKMS (включая ZFS и MOK-подпись) при обновлениях DNF.
Архитектура загрузки

Код: Выделить всё

┌─────────────────┐      ┌─────────────────────────────┐      ┌────────────────────────────┐
│   UEFI / Shim   │ ───> │        ZFSBootMenu          │ ───> │        Kernel & ZFS        │
│  (Загрузчик)    │      │  (Читает ZFS-датасет /boot) │      │ (Загрузка прямо из pool)   │
└─────────────────┘      └─────────────────────────────┘      └────────────────────────────┘
1. UEFI запускает ZFSBootMenu напрямую из ESP-раздела (`/boot/efi`).
2. ZFSBootMenu импортирует ZFS-пул, находит корневой датасет и считывает `vmlinuz` и `initramfs` напрямую из `/boot`.
3. kernel-install настраивается так, чтобы убрать зависимость от структуры BLS (`/boot/efi/<machine-id>/`).

Шаг 1. Отключение взаимодействия с GRUB
Чтобы исключить попытки вызова утилит GRUB и изменения NVRAM при обновлении пакета `kernel-core`, замаскируйте штатные плагины:

Код: Выделить всё

ln -sf /dev/null /etc/kernel/install.d/20-grub.install
ln -sf /dev/null /etc/kernel/install.d/95-set-boot-entry.install
ln -sf /dev/null /etc/kernel/install.d/99-grub-mkconfig.install
Шаг 2. Отключение BLS-раскладки с Machine ID
По умолчанию Fedora пытается раскладывать ядра по пути `/boot/efi/<machine-id>/<version>/`. Для отмены этого поведения:

1. Замаскируйте плагины генерации путей BLS:

Код: Выделить всё

ln -sf /dev/null /etc/kernel/install.d/00-entry-directory.install
ln -sf /dev/null /etc/kernel/install.d/10-devicetree.install
2. Зафиксируйте базовую раскладку в `/etc/kernel/install.conf`:

Код: Выделить всё

layout=basic

Шаг 3. Создание плагина копирования ядра (`10-copy-kernel.install`)
Чтобы `kernel-install` переносил файлы ядра из `/lib/modules/` непосредственно в датасет `/boot` нужно создать файл `/etc/kernel/install.d/10-copy-kernel.install`:

Код: Выделить всё

#!/usr/bin/bash
COMMAND="$1"
KERNEL_VERSION="$2"
ENTRY_DIR_ABS="$3"
KERNEL_IMAGE="$4"

MODULES_DIR="/lib/modules/${KERNEL_VERSION}"

if [[ "$COMMAND" == "add" ]]; then
    # 1. Образ ядра (vmlinuz)
    if [[ -n "$KERNEL_IMAGE" && -f "$KERNEL_IMAGE" ]]; then
        cp -f "$KERNEL_IMAGE" "/boot/vmlinuz-${KERNEL_VERSION}"
    elif [[ -f "${MODULES_DIR}/vmlinuz" ]]; then
        cp -f "${MODULES_DIR}/vmlinuz" "/boot/vmlinuz-${KERNEL_VERSION}"
    fi

    # 2. Файлы конфигурации и карты символов
    [[ -f "${MODULES_DIR}/config" ]] && cp -f "${MODULES_DIR}/config" "/boot/config-${KERNEL_VERSION}"
    [[ -f "${MODULES_DIR}/System.map" ]] && cp -f "${MODULES_DIR}/System.map" "/boot/System.map-${KERNEL_VERSION}"

    # 3. Символическая ссылка symvers.xz
    if [[ -f "${MODULES_DIR}/symvers.xz" ]]; then
        ln -sf "${MODULES_DIR}/symvers.xz" "/boot/symvers-${KERNEL_VERSION}.xz"
    fi

elif [[ "$COMMAND" == "remove" ]]; then
    rm -f "/boot/vmlinuz-${KERNEL_VERSION}"
    rm -f "/boot/config-${KERNEL_VERSION}"
    rm -f "/boot/System.map-${KERNEL_VERSION}"
    rm -f "/boot/symvers-${KERNEL_VERSION}.xz"
fi

exit 0
Установите права на исполнение:

Код: Выделить всё

chmod +x /etc/kernel/install.d/10-copy-kernel.install

Шаг 4. Настройка генерации initramfs для ZFSBootMenu
Для исключения ошибок записи `dracut` на отмонтированный ESP-раздел переопределите вызов генерации образа:

Замаскируйте штатный плагин `dracut`:

Код: Выделить всё

ln -sf /dev/null /etc/kernel/install.d/50-dracut.install
Создайте специализированный плагин `/etc/kernel/install.d/50-zfsbootmenu.install`:

Код: Выделить всё

#!/usr/bin/bash
COMMAND="$1"
KERNEL_VERSION="$2"

if [[ "$COMMAND" == "add" ]]; then
    dracut --force "/boot/initramfs-${KERNEL_VERSION}.img" "${KERNEL_VERSION}"
elif [[ "$COMMAND" == "remove" ]]; then
    rm -f "/boot/initramfs-${KERNEL_VERSION}.img"
fi

exit 0
Установите права на исполнение:

Код: Выделить всё

chmod +x /etc/kernel/install.d/50-zfsbootmenu.install
3. Убедитесь, что конфигурация `/etc/dracut.conf.d/00-zfsbootmenu.conf` содержит модуль ZFS:

Код: Выделить всё

hostonly="yes"
add_dracutmodules+=" zfs "
uefi_stub="no"
### Шаг 5. Параметры ядра в ZFS-датасете
Командная строка ядра передается через свойства ZFS-датасета. Проверка и установка параметров:

Код: Выделить всё

# Просмотр текущих аргументов
zfs get org.zfsbootmenu:commandline root/0

# Установка штатных аргументов (при необходимости)
zfs set org.zfsbootmenu:commandline="ro rhgb quiet video=1600x900" root/0
Итоговая структура файлов и каталогов
Каталог конфигурации `/etc/kernel/install.d/`
Файл / Симлинк Назначение
`20-grub.install -> /dev/null` Отключение вызовов GRUB
`95-set-boot-entry.install -> /dev/null` Отключение изменения EFI BootOrder
`99-grub-mkconfig.install -> /dev/null` Отключение генерации `grub.cfg`
`00-entry-directory.install -> /dev/null` Отключение генерации BLS Machine-ID путей
`10-devicetree.install -> /dev/null` Отключение поиска DTB в ESP
`10-copy-kernel.install` Плагин копирования `vmlinuz`, `config`, `System.map` и создания симлинка `symvers.xz`
`50-dracut.install -> /dev/null` Маскировка штатного плагина dracut
`50-zfsbootmenu.install` Плагин генерации `initramfs-*.img` напрямую в `/boot`
Содержимое каталога `/boot` при корректной работе

Код: Выделить всё

/boot/
├── config-<kver>
├── initramfs-<kver>.img
├── System.map-<kver>
├── symvers-<kver>.xz -> /lib/modules/<kver>/symvers.xz
└── vmlinuz-<kver>
Проверка работы
Для валидации всей цепочки вызовов выполните переустановку текущего ядра:

Код: Выделить всё

dnf reinstall kernel-core-$(uname -r)
Ожидаемый вывод:
  1. DKMS автоматически собирает и подписывает модуль `zfs.ko` вашим ключом MOK.
  2. `kernel-install` раскладывает файлы ядра в `/boot`.
  3. `dracut` формирует `initramfs-*.img` без ошибок доступа к `/boot/efi`.
  4. Транзакция DNF завершается с кодом `0`.

Изолируем установку всех пакетов zfs из репозитория rpmsphere
Добавим в /etc/yum.repos.d/rpmsphere.repo строку:

Код: Выделить всё

exclude=zfs* kmod-zfs* libzfs* python3-zfs*
Последний раз редактировалось root 02 окт 2026 16:14, всего редактировалось 4 раза.
Ответить