- PVSM.RU - https://www.pvsm.ru -
Обновлял ядро на EndeavourOS (Arch-based). Обычная рутина: pacman -Syu, перезагрузка. Но в этот раз в терминале вылезло:
find: '/usr/lib/modules/6.12.3-arch1-1/': No such file or directory
nvidia/565.57.01: broken
Error! nvidia/565.57.01: Missing the module source directory or the symbolic link pointing to it.
Manual intervention is required!
Прочитал. Понял, что дело в nvidia-драйвере. Понял, что требуется вмешательство. Понял, что чего-то не хватает — то ли директории, то ли симлинка. Куда именно идти руками — не понял.
Да, я в курсе, что где-то сейчас недовольно щурится true-админ и думает «а что тут непонятного, читай исходники dkms.in». Согласен, можно. Но если каждый раз для диагностики нужно читать чужой bash-скрипт — это и есть тот самый повод сообщение переписать.
Пошёл гуглить. Нашёл десяток одинаковых тредов на форумах EndeavourOS, Manjaro, Arch — люди в такой же ситуации, и дальше каждый гадает сам: кто-то сносит весь /var/lib/dkms, кто-то переустанавливает nvidia-dkms, кто-то чистит всё подряд.
Свою систему я в итоге починил. Но осталось раздражение от того, как это устроено: одно и то же сообщение без единой зацепки печатается каждому, кто столкнётся с той же ситуацией. И чинится это довольно легко — в этом, собственно, и есть смысл открытого кода: вместо того чтобы ждать, пока кто-нибудь когда-нибудь это исправит, можно пойти и исправить самому.
DKMS (Dynamic Kernel Module Support) — инфраструктурная штука. Пересобирает сторонние модули ядра (nvidia, VirtualBox, ZFS, WireGuard) при обновлении ядра, избавляя от ручной пересборки и подключения модуля обратно в загрузку. Крутится на Arch, Fedora, Debian — практически везде, где есть проприетарные или внешние модули. Живёт на GitHub под dkms-project, патчи принимают медленно, но принимают.
Поискал по репозиторию все места с фразой «Manual intervention is required!». Оказалось, DKMS путь на самом деле знает — он проверяется в is_module_broken():
is_module_broken() {
[[ $1 && $2 ]] || return 1
[[ -d $dkms_tree/$1/$2 ]] || return 2
[[ -L $dkms_tree/$1/$2/source && ! -d $dkms_tree/$1/$2/source ]] && return
[[ ! -L $dkms_tree/$1/$2/source && -d $source_tree/$1-$2/ ]] && return
}
Проблема в том, что этот путь никогда не попадает в текст ошибки. В четырёх независимых местах кода (module_is_broken_and_die, ветка status, run_match, autoinstall) печатается одна и та же фраза без конкретики:
Missing the source directory or the symbolic link pointing to it.
Manual intervention is required!
После патча то же место выглядит так:
nvidia/565.57.01: broken
Error! nvidia/565.57.01: Missing the module source directory or the symbolic link pointing to it:
/var/lib/dkms/nvidia/565.57.01/source
Manual intervention is required!
If this module version is no longer needed, you can remove the stale directory.
Otherwise, reinstall the package that provides its source.
Именно это я сам подумал, вернувшись к своему логу. Путь же вот он, прямо в первой строке. Зачем ещё один?
Потому что это два разных пути в двух разных местах. /usr/lib/modules/6.12.3-arch1-1/ — это директория ядра. find сканирует её, пока чистит устаревшие модули, и жалуется, что её больше нет — это побочный шум от find, не сообщение самого DKMS. А /var/lib/dkms/nvidia/565.57.01/source - это путь к исходникам модуля, и именно его проверяет is_module_broken(). Именно его в сообщении и не хватало.
Пересечения между ними нет. Если модуль сломан, чистить /usr/lib/modules/6.12.3-arch1-1/ бессмысленно - её там уже нет, и к модулю она отношения не имеет.
Плюс контекст: find: печатается один раз, погребённый где-то в стене вывода pacman, ничем не выделен. А Manual intervention is required! вылезает при каждой команде, где DKMS натыкается на сломанный модуль — status, build, install, autoinstall. Именно на него и реагируешь, набирая запрос в поиске.
У меня самого путь к разгадке был такой: погуглил «dkms broken manual intervention», попробовал dkms remove nvidia/565.57.01 --all - не сработало, посмотрел dkms status, не смог понять, что чистить - /var/lib/dkms/nvidia/565.57.01/ или /usr/lib/modules/6.12.3-arch1-1/ - и в итоге нашёл ответ в треде трёхлетней давности на форуме EndeavourOS, где кто-то объяснил смотреть именно в /var/lib/dkms.
Прежде чем писать код, прошёлся по issues и PR проекта. PR #357 в своё время добавил сам статус broken, но без пути в сообщении. Issue #94 — про улучшение диагностики, но на другом этапе работы DKMS. Issue #463 — про коды возврата, помечен help wanted. Ни один открытый PR не делал именно то, что нужно было мне.
Три независимых, послойных коммита.
Первый — добавил путь во все четыре места вывода сообщения, заодно обновил 10 тестовых блоков в run_test.sh, где ожидаемый вывод сверяется построчно. Второй — одна строка, добавил endeavouros в case определения дистрибутива в тестовом скрипте, потому что тесты про мой дистрибутив просто не знали. Третий — двухстрочная подсказка:
If this module version is no longer needed, you can remove the stale directory.
Otherwise, reinstall the package that provides its source.
Третий коммит самый спорный — мейнтейнеры вполне могли посчитать его лишним многословием. Оставил его отдельным коммитом, который можно откатить одной командой, написал в PR, что не привязан к этой части и готов убрать, и специально избегал формулировок вроде «просто почисти эту папку» — это прямая дорога к rm -rf в системной директории без понимания последствий. «Удали, если не нужно, или переустанови, если нужно» — не инструкция, а развилка, которую пользователь проходит сам.
На это ушло больше времени, чем на сам патч. run_test.sh требует root, заголовки ядра под текущий uname -r, чистый /var/lib/dkms (у меня там висел рабочий nvidia/580.178.04, пришлось временно вынести) и реальную компиляцию модулей через make.
По пути вылезло: unknown Linux distribution ID endeavouros - тесты не знали дистрибутива, отсюда и второй коммит. Дальше расхождение /lib/modules и /usr/lib/modules — на Arch-подобных /lib это симлинк на /usr/lib, DKMS печатает канонический путь, а тесты писались с оглядкой на Fedora и Debian, где ожидался /lib. Апстримная сборка через make install использует MODDIR=/lib/modules, а Arch-пакет патчит это на /usr/lib/modules — первый прогон упал именно на этом. Отдельно пришлось разобраться с конфликтом с системным /usr/bin/dkms, который тестовый скрипт дёргает напрямую — временно снёс его через pacman -Rdd dkms.
Рабочий пайплайн в итоге:
sudo pacman -Rdd dkms
sudo mv /var/lib/dkms/nvidia /root/nvidia.dkms.bak
cd dkms
sudo make install
sudo ./run_test.sh
sudo make uninstall
sudo mv /root/nvidia.dkms.bak /var/lib/dkms/nvidia
sudo pacman -S dkms
Финальный прогон - All tests successful, на EndeavourOS, ядро 7.2.7-zen1-1-zen, на живой системе с работающим в параллель nvidia-драйвером.
В CI проекта при этом одна джоба всё же упала — контейнер с Fedora 44. В логе оказалось предупреждение о несовпадении версии pahole с той, которой было собрано ядро в образе — это связано с ожиданиями make и моей правки вообще никак не касается. К моим изменениям отношения не имеет, и мейнтейнер смержил PR несмотря на этот красный чек. Возможно, issue про pahole-баг в тестах на Fedora я тоже заведу — если такого обсуждения еще не было или кто-то не сделает это вперёд меня.
Issue #606 описывает проблему с конкретным примером и ссылками на #357 и #94. PR #607 — три коммита, полный диф, смержен в main. От публикации issue до мержа прошли примерно сутки, хотя изучая репозиторий я подумал о 1-2 неделях ожидания. Теперь вместо голого “Manual intervention is required!” видно, куда смотреть и что делать дальше.
Плохой UX — это не только про графические интерфейсы, у CLI та же болезнь: сообщение об ошибке полезно ровно настолько, насколько оно информативно, даже если технически оно верное. Обоснование патча в опенсорсе важно не меньше самого кода — issue со ссылками на смежные обсуждения и результатами тестов ревьюер читает совсем иначе, чем голый диф без контекста. А ещё окружение съедает времени куда больше, чем код — сам патч это 28 строк в dkms.in и 12 в тестах, а вот с заголовками, симлинками и определением дистрибутива я провозился отдельный день.
Если тоже думаете сделать свой первый PR куда-нибудь — ищите не опечатку, а реальную шероховатость, из-за которой люди гуглят одно и то же годами. Проверьте issues и PR, чтобы не задваивать работу. Держите патч маленьким и разбивайте на атомарные коммиты, даже если правка простая — мейнтейнеру так проще принять только нужную часть, не редактируя чужой диф руками. И будьте готовы откатить любую спорную часть без сопротивления.
PR #607 (смержен): dkms-project/dkms#607
Issue #606: dkms-project/dkms#606
Автор: pavop02
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/459272
Ссылки в тексте:
[1] Источник: https://habr.com/ru/articles/1089500/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1089500
Нажмите здесь для печати.