Git

Находки по образу: загрузка, звук, порталы

Разбор проблем, которые находили на живых и чистых установках образа: что видно пользователю, в чём причина и как исправлено. Страница нужна, чтобы при похожем симптоме не искать причину заново.

Долгий старт на чистой установке#

Симптом. Чистая установка (не обновление со старой сборки) долго стартует: около 28 секунд заставка, потом почти две минуты чёрный экран с курсором, затем окно входа, а от входа до панели ещё около 35 секунд. На системах, обновлённых с stable, этого не было.

Причины. Воспроизведено на чистой установке образа latest в виртуальной машине. Их две:

  1. Мастер первой настройки мешал порталам. Юнит readyset-first-run.service (Type=oneshot, WantedBy=graphical-session.target) запускался и в сессии экрана входа (пользователь _greeter), и под целью graphical-session.target блокировал её. Порталы стартуют после этой цели, а они нужны и мастеру, и экрану входа. Результат: три таймаута по 25 секунд («Cannot get portal …»), окно входа появлялось на 112-й секунде. После входа тот же механизм добавлял ещё около 25 секунд.
  2. Бэкенд снимков экрана wlr. В niri-portals.conf стояло Screenshot=wlr. Портал xdg-desktop-portal-wlr на niri падает в цикле («нет screencopy»), а xdg-desktop-portal при старте ждёт его до таймаута D-Bus в 25 секунд. Замер: перезапуск портала занимает 25,2 с с wlr и 0,13 с с gnome. Это и была «известная гонка портала на 50 секунд», а не гонка с XDG_CURRENT_DESKTOP, как думали раньше.

Исправление. У юнита мастера ConditionUser=!_greeter и Type=exec, метка «мастер пройден» ставится в ExecStopPost только при успехе. В портальных настройках Screenshot=gnome, default=gtk;gnome;, убран отдельный wlr.portal, добавлена миграция пользовательских niri-portals.conf. Результат замера: окно входа через 12 секунд, панель через 2 секунды после входа.

Как воспроизводить такое. Установить образ в виртуальную машину на чистый диск (bootc install to-disk --generic-image --via-loopback), загрузить под QEMU и смотреть systemd-analyze и журнал journalctl -o short-monotonic.

Что осталось. В сессии экрана входа стартуют и другие пользовательские юниты (niti-portal и другие): лишняя работа. Document portal и gvfsd в этой сессии работают без /dev/fuse.

Скринкаст: окон нет в списке#

Симптом (issue #20). В Discord, Telegram и OBS при демонстрации экрана нельзя выбрать окно, только монитор.

Неверный первый диагноз. Решили, что Seni не выставляет XDG_CURRENT_DESKTOP, и потому портал не находит niri-portals.conf. Живая проверка показала, что сам niri выставляет XDG_CURRENT_DESKTOP=niri при запуске как systemd-сессия. Патч в Seni остался как резервный путь, но проблему не решал.

Второй диагноз тоже был неверным. Падения xdg-desktop-portal-wlr в журнале совпали по времени с ручными перезапусками PipeWire во время диагностики микрофона: их вызывали сами. Это не баг апстрима.

Настоящая причина. niri-portals.conf маршрутизировал ScreenCast=wlr, а wlr отдаёт только мониторы (AvailableSourceTypes=1). Документация niri требует для скринкаста xdg-desktop-portal-gnome: niri реализует интерфейс org.gnome.Mutter.ScreenCast. Портал gnome когда-то убрали из-за поломки диалога выбора файлов, но выбор файлов уже направлен на gtk, так что gnome можно вернуть только для скринкаста.

Исправление. Пакет xdg-desktop-portal-gnome в образе, ScreenCast=gnome во всех niri-portals.conf, FileChooser=gtk, миграция личного конфига пользователя. Проверка вживую: AvailableSourceTypes=7, OBS показывает диалог выбора с вкладками «Окно» и «Экран», диалог выбора файлов без регрессий.

Урок. Диагноз по чтению кода без живой проверки итогового окружения сессии оказался неверным. Перед правкой проверяйте то, что реально работает: systemctl --user show-environment, журнал портала, сам портал.

Звук: пропадает микрофон после загрузки#

Симптом. После загрузки USB-микрофон иногда недоступен: в журнале «Устройство или ресурс занято» при открытии ALSA-устройства, WirePlumber не может создать источник и приёмник.

Причина. PipeWire, WirePlumber и pipewire-pulse поднимались не только для вашего пользователя, но и для пользователя экрана входа _greeter. Обе сессии почти одновременно открывали одни и те же ALSA-устройства, и вторая получала «занято».

Исправление. Добавлены drop-in no-greeter.conf с ConditionUser=!_greeter для pipewire.socket, pipewire.service, pipewire-pulse.socket, pipewire-pulse.service и wireplumber.service. Звук в экране входа не нужен. Добавлен тест на упаковку (tests/unit/test_seni_greeter_packaging.py).

Вторично. Отвалы USB-хаба монитора дают «card removed» именно для звука монитора, не для микрофона на другой шине. Страховка: помощник atomic-niri-audio-reconnect и кнопка во вкладке «Звук».

Старый менеджер входа возвращается#

Симптом. После локальной пересборки образа (apm system image apply) запускался greetd, а не Seni.

Причина. Пакет greetd из образа убрали давно, но /etc переживает bootc switch (трёхстороннее слияние). Локальная пересборка на несвежем дереве рецептов подняла юнит заново.

Исправление. greetd.service маскируется в systemd.yml как страховка. Это не исправление причины: причина в локальной пересборке на устаревшем дереве. Перед такой пересборкой убедитесь, что дерево синхронизировано с основной веткой.

Экран блокировки при старте#

Раньше в config.kdl стоял запуск swaylock как «обложки» на долю секунды между стартом композитора и появлением панели. На чистых установках дважды не сработало автоматическое снятие по SIGUSR1, и сессия оставалась заблокированной навсегда: приходилось заходить по SSH и посылать сигнал вручную.

Обложку убрали: голый niri на долю секунды лучше, чем риск наглухо заблокированной сессии. Не возвращайте её без надёжного механизма принудительного снятия (таймаут и принудительное завершение, а не только сигнал от панели). Актуальный экран блокировки: seni-lockscreen (<kbd>Super</kbd>+<kbd>L</kbd>). Интеграционный тест проверяет, что в config.kdl нет слова swaylock, даже в комментариях.

NVIDIA: пакет драйвера есть не для каждого ядра#

Симптом. Сборка ветки nvidia падала: Package not found: kernel-modules-nvidia-7.1.

Причина. Пакеты kernel-modules-nvidia-<flavour> собираются не для всех веток ядра. В Sisyphus они есть для 6.12, 6.18 и talos, а для 7.1 нет. При этом плавающий базовый образ core/stable:latest в разное время приходил с разным ядром: сначала с 7.1 (сборка упала), через несколько минут уже с 6.18.

Исправление. В рецепте ветки nvidia перед подключением общего модуля NVIDIA добавлен модуль, закрепляющий ветку ядра:

- name: Pin kernel flavour for NVIDIA type: kernel if: Env.BUILD == "nvidia" body: kernel-info: flavour: "6.18"

Если 6.18 когда-нибудь пропадёт, проверьте наличие пакета командой apt-cache search kernel-modules-nvidia в контейнере registry.altlinux.org/alt/alt:sisyphus и поднимите ветку ядра.

Пакеты ReadySet и версия библиотеки#

В Sisyphus обновили ReadySet с 0.14 до 0.15. Все плагины мастера требуют libready-set-0.14, и их CI-сборка в контейнере с актуальным Sisyphus падает: Dependency "libready-set-0.14" not found. В образе при этом стоят плагины, собранные раньше против 0.14.

Следствие: пересобранный плагин (против 0.15) нельзя публиковать в репозиторий, из которого собирается образ на базе 0.14: сборка образа упадёт на неудовлетворённой зависимости libready-set-0.15.so. Решение: переходить на 0.15 сразу всеми плагинами и одновременно обновлять закреплённый базовый образ (CORE.lock). Когда базовый образ с ReadySet 0.15 закреплён, ограничение снимается.

См. также: ReadySet: что ломалось, сборка образа и DKMS, каналы образа.