LINUX.ORG.RU

Не работает overlayfs внутри initrd

 , , ,


1

1

Внутри полностью загруженной системы такое работает нормально:

mkdir /tmp/ovl1 /tmp/ovl2 /tmp/merged
mount -t overlay none -o lowerdir=/tmp/ovl1:/tmp/ovl2 /tmp/merged

Это read-only вариант, без upperdir и workdir.

Причём в busybox sh это работает тоже - там внутренняя реализация mount.

Отдельных модулей для overlayfs не существует, оно вкомпилено в ядро.

Внутри initrd работать не хочет: каталоги успешно создались, mount выдаёт ошибку:

mount: mounting none on /tmp/merged failed: No such device

-o ro и -t overlayfs не помогают, та же ошибка.

Ядро то же самое, разумеется.

Вот список уже смонтированных ФС в initrd:

rootfs on / type rootfs (...)
sysfs on /sys type sysfs (...)
proc on /proc type proc (...)
udev on /dev type devtmpfs (...)
devpts on /dev/pts type devpts (...)
tmpfs on /run type tmpfs (...)

Не пойму, куда дальше копать :(

P.S. Сейчас я использую AUFS, но его не приняли в mainline kernel, и советуют переходить на overlayfs.

★★★

Дистрибутив? Чем создан initrd?

По идее если модуль вкомпилен в ядро (Y а не M) особо разницы с M не должно быть кроме того чем передавать параметры модулю при загрузке.

init_6 ★★★★★ ()
Ответ на: комментарий от selivan

Я был почему-то 100% уверен, что оно вкомпилено статически.

Ну я всегда рад помочь. Особенно так. Просто дело смотри в чем:

Запихнул модуль внутрь initrd, взлетело.

Вот с этого самого момента поподробнее. Потому как у меня есть initramfs тупейший. Ну всмысле конфиг там это по сути указание что и где /bin, /sbin должно лежать. Дальше закидываешь в него свой init а в конце make при помощи Makefile собирает initramfs при помощи стандартного /usr/src/linux/scripts/gen_initramfs_list.sh. Это всё были плюсы а минусы этого поделия в том, что:

  • На старых компах с BIOS проблем не было никаких. Сейчас на UEFI пробовал всё аналогично старым подходам и/или вкомпиливать initramfs в само ядро и никаких успехов - ядро в UEFI с этим initramfs тупо не загружается и мрёт ещё до того как успевает хоть что-то вывести на екран.
  • Даже с BIOS, когда всё работало отлично, у меня так и не вышло модули ядра запихать в initramfs. Всмысле старые материалы читал и делал как там советовали. Но осталось ощущение что некая ерунда с тех пор изменилась и загрузка модулей ядра из initramfs делается как то не так.

В общем просвети как победил?

init_6 ★★★★★ ()
Ответ на: комментарий от init_6

Я так глубоко не копал, я использую обычный Debian-овский initramfs-tools, и к нему просто кастомный скрипт загрузки и кастомный хук. Скрипт определяет функцию mountroot(). Хук добавляет модули ядра и исполняемые файлы стандартыми функциями manual_add_modules и copy_exec. Остальная магия внутри Debian-овской обвязки. https://github.com/selivan/thinclient/tree/master/template/initramfs-tools

Грузится оно по PXE, насчёт работы с UEFI не знаю.

selivan ★★★ ()
Последнее исправление: selivan (всего исправлений: 1)
Ответ на: комментарий от kostik87

Я добавляя модули в initramfs копирую туда же и depmod от этого ядра. Не совсем корректно, но работает.

Со времен когда были написаны эти маны до сего дня сильно много всего поменялось. Главный мод подозреваемый это sys-apps/kmod. Да и самый простой пример из вики генты с initramfs которая просто делает fsck.ext4 у меня на UEFI и то не завелся. Я не знаю хоть бери и генкернелом, если он работает, собирай initramfs и ковыряй как он там делает.

init_6 ★★★★★ ()
Ответ на: комментарий от Nick_what_is_again

Скорее всего, в initrd не хватает модуля ядра для squashfs. Надо прописать его в hooks для initramfs-tools, посмотри как сделано тут: https://github.com/selivan/thinclient/blob/076c2d9c77d1011fa00b08914caa0d90a9...

selivan ★★★ ()
Последнее исправление: selivan (всего исправлений: 1)
Ответ на: комментарий от selivan

Его точно не хватает, это медицинский факт. За ссылочку спасибо :) (нагуглил много вариантов, выбрать рабочий сам не смог, так что особое спасибо).

Но, кроме него, ещё где-то я пингвину перьев недовесил и он тонет. Потому что после сборки тестового ядра, в котором жёстко (не модульно) вбиты aufs и overlay, жалоба изменилась:

/dev/sda1: recovering journal
/dev/sda1: clean (уже хорошо) блаблабла файлов…
overlayfs: failed to resolve '/usr_squash/upd': -2
mount: mounting overlay on /root/usr failed: No such file or directory
overlayfs: upper fs is r/o, try multi-lower layers mount

Ну, что тут явно видно: вкомпилённый overlay жив в достаточной степени, чтобы жаловаться. По сравнению с «нет такого [виртуального] устройства» действительно прогресс. Ещё видно, что не жалуется скваш. Вероятно, у него всё в порядке и .sfs он успешно нашёл и приладил в /usr_squash/sq. И оверлей тоже не жалуется на этот /usr_squash/sq (не успевает дойти до проблемы или с ним действительно всё в порядке)?

А вот каким образом оверлей может одновременно не найти /usr_squash/upd и пожаловаться, что верхняя директория (а это сам /usr_squash/upd и есть) доступна только как r/o — это меня просто в ступор ставит. Так не найден или доступен как r/o?

Вот выхлоп ls /usr_squash/:

sq
tmp
upd
usr.sfs

Вот /etc/fstab:

UUID=блабла /               ext4    errors=remount-ro 0       1

/usr_squash/usr.sfs                      /usr_squash/sq   squashfs        loop,ro        0    0
overlay                                  /usr        overlay         defaults,lowerdir=/usr_squash/sq,upperdir=/usr_squash/upd,workdir=/usr_squash/tmp   0   0

UUID=блабла    none            swap    sw              0       0

Может, какие-то опции (не defaults) для такого случая есть?

Nick_what_is_again ()
Ответ на: комментарий от Nick_what_is_again

При загрузке создаётся начальный ramdisk, примонтированный в /. Скрипты в initrd работают внутри него, сначала монтируют всё в каталог внутри него, а потом переключают его на реальный /(там есть какая-то специальная утилитка).

Поэтому опции монтирования, указывающие каталоги, могут не работать: корень-то ещё временный, а пути указаны относительно постоянного.

Посмотри как сделан https://github.com/selivan/thinclient/, я в документации описал что и как происходит. Скорее всего, тебе придётся создать свой скрипт загрузки(или поправить local, но его перезатрёт следующее обновление пакета) и при загрузке указывать initrd использовать именно его: boot=my_local

А зачем оно тебе вообще? Обычно весь корень целиком выносят в tmpfs over overlayfs, чтобы получить неизменяемую систему. Так работают все LiveCD, в том числе убунтовский инсталлятор.

selivan ★★★ ()
Последнее исправление: selivan (всего исправлений: 1)
Ответ на: комментарий от selivan

Ага, этот занимательный путь /root/что-то-там. Причём скваш ни на что не жалуется, а оверлею я даже специально пробовал указать не /usr_squash/upd, а /root/usr_squash/upd. Ощущение, что оно через раз работает, то жалуется на отсутствие, то жалуется только на r/o. Видимо, там что-то в обвязке очень сильно недописано, поэтому и не ввели оверлей окончательно в ядро.

Неизменяемую я как раз не хочу, потому что security updates доселе своей оперативностью только радовали. Просто в /usr уже три гига и явно будет больше, если активно работать многочисленными инструментами. А на балалайках типа gpd win каждый гиг SSD и каждый метр оперативки на счету (да и каждая перезапись, поскольку SSD там только паяльной станцией заменяется, но речь не о том). Ну, и не только на них, а на поднятых из мёртвых некроноутах тоже трудятся флэшки по 16G..32G.

А скваш с xz жмёт это всё не на проценты, а в разы. Поэтому соблазн проторить дорожку очень велик :)

Nick_what_is_again ()
Ответ на: комментарий от Nick_what_is_again

overlayfs как раз давно в ядре, это aufs туда не приняли.

У меня squashfs монтируется в каталог в /tmp начального ramdisk, в ${rootmnt} создаётся tmpfs каталог, потом mount --move переносит туда точки монтирования. В итоге работает. Смотри template/initramfs-tools/scripts/ram.

Security updates как раз затрагивают /usr, собственно большинство софта живёт в /usr/bin, /usr/lib и так далее.

selivan ★★★ ()
Ответ на: комментарий от selivan

Что-то у меня началась эпоха великого тормоза. Хотя кончалась ли она… :(

Хоть бы на архитектурном уровне понять.

Т. е. мне не нужно это делать на уровне fstab? Нужно монтировать через скрипт?

В /etc/initramfs-tools/hooks/compusr/ создать файл хука, который подтягивает модуль overlay. Принять-то его приняли, но он не вшитый, он модульный, в отличие от скваша.

В /etc/initramfs-tools/scripts/local-top/compusr/ создать файл бут-скрипта, который монтирует overlayfs из сжатой (неизменной) части и несжатого свежака, в который в будущем и ложатся security updates, и делает эту смесь новым /usr.

И при update-initramfs он сошьёт эти файлы со стандартным скриптом, и при обновлениях ядра/скрипта/чего-то ещё будет их туда упорно добавлять. Так или я что-то переврал?

Не вполне понятно, по какому принципу он это всё стыкует. Это как-то связано с PREREQ? Да и вообще, получается, что сначала стандартный скрипт должен разобрать fstab, а потом уже мой аппендикс должен что-то там поменять. Получается странно, так что более вероятно, что я чего-то недопонял :(

Nick_what_is_again ()
Ответ на: комментарий от Nick_what_is_again

Сначала работают скрипты из initrd, которй распаковывается в начальную rootfs. Потом они пытаются примонтировать настоящий корень(параметр ядра root=xxxxxxx) и передают управдение init(systemd, upstart, ...). А оно уже парсит fstab и окончательно всё монтирует.

Если нужно монтировать что-то, что не получится примонтировать из fstab - надо это делать в initrd, а в fstab упоминать не надо. Степень ужасности костылей напрямую зависит от нестандартности собираемой конструкции. Вот у меня например корень и ещё некоторые запчасти скачиваются в память и монтируются там же через overlayfs, я кидал выше ссылку на проект.

selivan ★★★ ()
Последнее исправление: selivan (всего исправлений: 1)