initrd, lvm, ошибка активации lv с включенным cache [SOLVED]
Доброго времени суток.
У меня возникла проблема с активацией lvm в initrd.
Что было:
несколько hdd, разбивка следующая: 1 раздел - основные данные, 2 раздел - boot, 3 раздел - efi
raid: md1 - raid5 (первые разделы на всех дисках), md2 - raid1 (вторые разделы),
lvm: pv - md1, vg - vgmain (в которую входит только один pv - md1), lv - их несколько, в том числе и root.
в качестве загрузчика использовал grub2.
initrd - самописный, пользовался, кажется, руководством https://wiki.gentoo.org/wiki/Custom_Initramfs
все это благополучно настроил много лет назад, все работало, все устраивало.
сейчас захотел прикрутить к root lvm cache на ssd, т.к. полностью переносить систему на ssd нехочу из соображений надежности (да, возможно предрассудки, но это мои предрассудки).
столкнулся с несколькими проблемами.
1. текущий initrd содержит старую версию lvm:
LVM version: 2.02.97(2) (2012-08-07) Library version: 1.02.76 (2012-08-07) Driver version: 4.39.0
которая не понимает что такое lvm cache,
не беда, обновил до той, что сейчас установлена в системе (бинарник брал, естественно, статический):
LVM version: 2.02.184(2) (2019-03-22) Library version: 1.02.156 (2019-03-22) Driver version: 4.39.0
2. для работы lvm cache нужно утилита cache_check.
добавил её в initrd.
3. этого оказалось мало. изменилось поведение lvm.
старый init для активации lvm выполнял следущие действия:
activate_lvm(){ lvm vgscan --mknodes && lvm vgchange -ay }
их было достаточно, чтобы в /dev/mapper/ появились block device (имя формата vgname-lvname),
но с новой версии lvm такого не происходит, создаются только /dev/dm-[0-9]*, это не большая проблема, всего-то пройтись по uuid и найти нужный. это я решил.
4. не работает активация lv с включенным cache'ем (опцию --sysinit пробовал добавлять в качестве теста, что с ней, что без неё - результат одниковый):
/ # lvm vgchange -ay --sysinit WARNING: Failed to connect to lvmetad. Falling back to device scanning. modprobe: chdir(4.19.97-gentoo): No such file or directory /sbin/modprobe failed: 1 modprobe: chdir(4.19.97-gentoo): No such file or directory /sbin/modprobe failed: 1 /dev/mapper/vgtest-lvt--cache_cmeta: open failed: No such file or directory 0 logical volume(s) is volume group "vgtest" now active [ 81.111886] lvm (1140) used greatest stack depth: 13952 bytes left
как побороть ошибку *_cmeta я так и не нашел.
это вывод из тестового стенда, конфиг lvm, которого повторяет мою проблему (а именно включение lvm cache ломает активацию lv на этапе initrd):
# pvdisplay -m --- Physical volume --- PV Name /dev/vdb1 VG Name vgtest PV Size <5,00 GiB / not usable 3,00 MiB Allocatable yes (but full) PE Size 4,00 MiB Total PE 1279 Free PE 0 Allocated PE 1279 PV UUID zvOsLX-em4a-tqck-ZYSv-OjW4-Fjio-rzQDok --- Physical Segments --- Physical extent 0 to 1278: Logical volume /dev/vgtest/lvt-test_corig Logical extents 0 to 1278 --- Physical volume --- PV Name /dev/vde VG Name vgtest PV Size 1,00 GiB / not usable 4,00 MiB Allocatable NO PE Size 4,00 MiB Total PE 255 Free PE 0 Allocated PE 255 PV UUID avPvww-1DKk-IySB-iA5F-N5B0-aeSL-1BSoQk --- Physical Segments --- Physical extent 0 to 1: Logical volume /dev/vgtest/lvol0_pmspare Logical extents 0 to 1 Physical extent 2 to 3: Logical volume /dev/vgtest/lvt-cache_cmeta Logical extents 0 to 1 Physical extent 4 to 254: Logical volume /dev/vgtest/lvt-cache_cdata Logical extents 0 to 250 # vgdisplay --- Volume group --- VG Name vgtest System ID Format lvm2 Metadata Areas 2 Metadata Sequence No 52 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 0 Max PV 0 Cur PV 2 Act PV 2 VG Size 5,99 GiB PE Size 4,00 MiB Total PE 1534 Alloc PE / Size 1534 / 5,99 GiB Free PE / Size 0 / 0 VG UUID 4sYlbf-HZAZ-BhYs-D9AK-bQnr-p7mh-cUCmYe # lvdisplay --- Logical volume --- LV Path /dev/vgtest/lvt-test LV Name lvt-test VG Name vgtest LV UUID 620xp0-coGe-fykI-nQGV-I79l-KMG6-OIViQe LV Write Access read/write LV Creation host, time localhost, 2020-03-07 09:26:43 +0200 LV Cache pool name lvt-cache LV Cache origin name lvt-test_corig LV Status available # open 0 LV Size <5,00 GiB Cache used blocks 0,11% Cache metadata blocks 2,83% Cache dirty blocks 0,00% Cache read hits/misses 328 / 136 Cache wrt hits/misses 0 / 0 Cache demotions 0 Cache promotions 0 Current LE 1279 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:3
содержимое init из initrd:
#!/bin/busybox sh rescue_shell() { echo "Something went wrong. Dropping you to a shell." busybox --install -s exec /bin/sh } load_modules() { MOD_PATH="/lib/modules" MODULES=`ls ${MOD_PATH}` for MODULE in ${MODULES} ; do insmod -f ${MOD_PATH}/${MODULE} done } activate_lvm(){ lvm vgscan --mknodes && lvm vgchange -ay } uuidlabel_root() { for cmd in $(cat /proc/cmdline) ; do case $cmd in root=*) dev=${cmd#root=} type=${dev%%=*} if [ $type = "LABEL" ] || [ $type = "UUID" ] ; then mount -o ro $(findfs "$dev") /mnt/root || rescue_shell else mount -o ro ${dev} /mnt/root || rescue_shell fi ;; esac done } mount -t proc none /proc || exit mount -t sysfs none /sys mount -t devtmpfs none /dev load_modules || rescue_shell rescue_shell # Mount the root filesystem. mdadm --assemble --scan /dev/md1 || rescue_shell activate_lvm || rescue_shell uuidlabel_root || rescue_shell # Clean up. umount /proc umount /sys umount /dev # Boot the real thing. exec switch_root /mnt/root /sbin/init
конфиг ядра (опции lvm находятся в device drivers -> Multiple devices driver support (RAID and LVM), в сами названия начинаются на CONFIG_DM):
# CONFIG_DM_MQ_DEFAULT is not set # CONFIG_DM_DEBUG is not set CONFIG_DM_BUFIO=y # CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set CONFIG_DM_BIO_PRISON=y CONFIG_DM_PERSISTENT_DATA=y # CONFIG_DM_UNSTRIPED is not set CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_THIN_PROVISIONING=m CONFIG_DM_CACHE=y CONFIG_DM_CACHE_SMQ=y CONFIG_DM_WRITECACHE=y # CONFIG_DM_ERA is not set CONFIG_DM_MIRROR=m CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_RAID=m CONFIG_DM_ZERO=y CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_DELAY=m # CONFIG_DM_UEVENT is not set CONFIG_DM_FLAKEY=m CONFIG_DM_VERITY=m # CONFIG_DM_VERITY_FEC is not set # CONFIG_DM_SWITCH is not set # CONFIG_DM_LOG_WRITES is not set # CONFIG_DM_INTEGRITY is not set
т.е. то, что мне нужно собрано в ядре (а не модулем), и в должно работать. на загруженной системе (стенд), lv с cache подхватывается и его можно использовать (тестовый lv, root не на нем), а вот на этапе initrd ошибка.
я уже попробовал подсмотреть что делает initrd который собирает genkernel, если убрать лишнее, то вот команды:
lvm vgscan 2>&1 lvm vgchange -ay --sysinit 2>&1 lvm vgmknodes --ignorelockingfailure
но она тоже результата не дают - vgchange возвращает ту же ошибку.
буду благодарен за свежие идеи, ибо мои уже закончились.
единственная догадка - это изменилось поведение lvm и те команды, которыми я пользовался ранее, уже не создают нужные мне /dev/mapper/vgname-lvname либо /dev/vgname/lvname block device (либо symlink'и на /dev/dm-[0-9]*), а на этапе инициализации lv с включенным cache выполняется запуск check_cache, которому в качестве аргумента передается путь к lv:
# strace -f -s 1024 lvm vgchange -ay 2>&1|grep execve [pid 3422] execve("/sbin/modprobe", ["/sbin/modprobe", "dm-cache-smq"], 0x7ffeee8ebef8 /* 30 vars */) = 0 [pid 3439] execve("/sbin/cache_check", ["/sbin/cache_check", "-q", "--clear-needs-check-flag", "/dev/mapper/vgtest-lvt--cache_cmeta"], 0x7ffeee8ebef8 /* 30 vars */) = 0
к слову тут же видно и с какими параметрами выполняется modprobe (но я не понимаю на кой он нужен, если ядро собрано с CONFIG_DM_CACHE_SMQ=y).
ради интереса попробовал (для теста разумеется) заменить /sbin/cache_check на /bin/true дабы пропустить его проверку, но вывод ошибки, которая возникает на этапе initrd не меняется, значит до его запуска даже не доходит.
lvm cache не сама цель. в конечном итоге хочу получить кеширование нескольких lv на ssd и в моей текущей конфигурации его внедрение было вроде самой легкой задачей.
bcache попросит переформатировать разделы, и как поведет себя после смерти ssd я не знаю.
переводить lvm на zfs нет возможности.
- Для комментирования войдите или зарегистрируйтесь
Что-то ты не так делаешь!
Может доки недочитал?
Вот тут ещё пару сайтов, где для домохозяек на пальцах объясняют, как надо делать:
https://lukas.zapletalovi.com/2019/05/lvm-cache-in-six-easy-steps.html
https://ahelpme.com/linux/lvm/ssd-cache-device-to-a-hard-disk-drive-using-lvm/
в целов да, arch доки не
в целов да, arch доки не читал, нашел другую.
но ведь не в этом проблема - создание lvm cache прошло у меня успешно.
проблема в том, что не работает его активация на этапе initrd, тогда как в загруженной системе все ок.
cache примерно так и создавал:
он создается и работает, но перезагрузку система не пережила.
тут нашел упоминание об
тут нашел упоминание об genkernel-next
попробовал, он генерирует те же команды активации lvm что и genkernel, которые не работает с lvm cache.
нашел способ воспроизвести на
нашел способ воспроизвести на загруженной системе:
но только где же я в initrd возьму udev то(
в initrd можно включить все,
в initrd можно включить все, что угодно! Читай теорию...
та да, уже тоже нашел
та да, уже тоже нашел упоминание, что в arch он по-умолчанию включен в initrd,
и более того в initrd сгенерированном genkernel/genkernel-next он есть, что объясняет почему там работают команды активации.
вангую что через 20 лет в initrd будет полноценный stage3, только для того чтобы примонтировать root(.
такого подвоха от lvm я не ожидал... Поттеринг их покусал чтоли)
А что тут не так? Разберись
А что тут не так? Разберись как работает система, и все станет понятно и логично!
Очевидно же, что при запуске системы нужно при себе иметь все, что использует при этом.
Для того и придумали
initrd
(а это и есть статическая минисистема!), чтобы не подключать все нужные ресурсы статически в ядро и/или утилиты, как это сделал ты! ;)И, в отличие от твоего костыля, при правильном использовании
initrd
нет ненужного разбазаривания ресурсов - ведь твойlvm
будет жрать больше памяти всегда - и при нормальной работе системы тоже! А то чтоinitrd
стал больше - кого это волнует, ибо он используется только при запуске, а с флоппиков давно уже никто не грузится... :)эм, а чем костыль?и почему
эм, а чем костыль?
и почему "ведь твой lvm будет жрать больше памяти всегда"?
я в ядро запихнул все что нужно для работы моей системы (raid, lvm, еще там по мелочи), что позволило не пересобирать initrd после каждого обновления ядра.
lvm с нужными флагами собрал единожды чтобы получить бинарник, который положил в initrd, затем пересобрал с предидущими use-флагами.
что не учел?
[SOLVED]
полностью решает мою проблему. на выходе получается бинарник, который активирует lvm cache в initrd без udev.