Сразу к делу: если система зависает при загрузке, первым делом определи этап, на котором она застряла. Этапов четыре: прошивка, GRUB, ядро с initramfs и пользовательское окружение systemd. Каждому соответствует свой набор инструментов: systemd-analyze time делит загрузку на фазы, systemd-analyze blame и critical-chain находят медленный юнит, а journalctl -b -1 читает журнал прошлой загрузки, когда до логина добраться не удалось. Ниже каждый случай разобран по порядку.
Сначала определи, где именно всё останавливается. Это сужает поиск в разы. Смотри на экран с момента включения питания и запоминай последнее, что успело появиться: логотип, меню, строка ядра или сообщение systemd.
Симптомы: экран застревает на логотипе производителя, не появляется ни одной строки, клавиши входа в настройки прошивки не реагируют. Linux тут ни при чём: система ещё не начала загрузку. Чаще всего виновата периферия, которую прошивка пытается опросить. Отключи лишние USB-устройства, проверь диски, сбрось настройки прошивки. Если зависание повторяется и на голом железе, проверь память и процессор: тест memtest86+ из live-окружения покажет битые модули RAM.
Меню GRUB появляется, но после выбора пункта ничего не происходит: чёрный экран или мигающий курсор. Загрузчик не смог передать управление ядру. Причины: повреждённый grub.cfg, битые модули, проблема с initramfs. Заодно проверь порядок загрузки в прошивке: система могла начать грузиться с другого диска. Если GRUB вообще не стартует и падает в grub rescue>, смотри статью «grub rescue: что делать».
Вывод ядра начался, но замер на какой-то строке. Обычно это драйвер, который не может инициализировать устройство, или initramfs, который не находит корневой раздел. Строка, на которой всё замерло, это главная улика: имя драйвера или устройства в ней почти всегда есть.
Ядро загрузилось, но до логина дело не доходит: чёрный экран после fsck или висящее сообщение «A start job is running for…». Это уже systemd: какой-то юнит не может завершить старт и держит загрузку. В сообщении «A start job is running for…» почти всегда указано имя юнита, запиши его. Здесь и пригодится диагностика по таймингам.
Когда система всё-таки загружается, но медленно, начни с общей картины:
systemd-analyze time
Вывод выглядит так:
Startup finished in 4.312s (firmware) + 1.208s (loader) + 2.104s (kernel) + 18.442s (userspace) = 25.066s
graphical.target reached after 18.442s in userspace.
Четыре числа, четыре этапа:
firmware это время работы прошивки до передачи управления загрузчику;loader это время работы GRUB или systemd-boot;kernel это время от старта ядра до запуска первого процесса systemd;userspace это время запуска всех юнитов до достижения graphical.target.Если firmware занимает десятки секунд, проблема в прошивке и железе, а не в системе. Если раздут userspace, ищи медленный юнит. Наглядную картину по всем юнитам даёт systemd-analyze plot > boot.svg: открой файл в браузере и увидишь, какие сервисы работали параллельно, а какие выстроились в очередь.
systemd-analyze blame показывает, сколько времени занял старт каждого юнита:
systemd-analyze blame
Сверху окажутся самые долгие. Но blame учитывает параллельно работающие юниты, поэтому для понимания цепочки загрузки смотри critical-chain:
systemd-analyze critical-chain
Он выводит цепочку юнитов, которые выполнялись строго последовательно, с временем каждого шага. Юнит, который тормозит всю загрузку, будет в этой цепочке с большим значением +N.Ns.
Пример вывода blame:
$ systemd-analyze blame
18.442s NetworkManager-wait-online.service
2.104s systemd-journal-flush.service
1.208s ldconfig.service
Сразу видно, кто съел почти всё время загрузки.
Дальше разберись, почему юнит так долго стартует:
systemctl status <unit>
journalctl -b -u <unit>
systemctl status покажет текущее состояние и последние строки лога юнита, journalctl -b -u выведет весь его журнал за текущую загрузку. Про чтение журнала подробнее рассказано в статье «Как читать journalctl -b».
Если юнит не стартует вовсе, проверь список упавших:
systemctl list-units --failed
Для каждого упавшего юнита смотри причину через systemctl status <unit>. А конфигурацию юнита на ошибки можно проверить так:
systemd-analyze verify /etc/systemd/system/foo.service
Он покажет синтаксические ошибки и неверные зависимости.
Если загрузка зависает до появления логина, systemd-analyze не запустить: система не поднялась. Но журнал прошлой загрузки никуда не делся.
journalctl -b -1
Эта команда показывает журнал предыдущей загрузки. Она работает и из emergency-режима, и из chroot с live-USB. Последние строки перед зависанием это то, что случилось в момент остановки.
Добавь в конец строки ядра в меню GRUB (правка по e):
systemd.unit=emergency.target
Система загрузится в минимальное окружение с root-оболочкой. Оттуда можно посмотреть журнал, поправить fstab и перезагрузиться. Корень в emergency смонтирован в режиме чтения, поэтому перед правкой файлов перемонтируй его:
mount -o remount,rw /
Если emergency не поднялся, загружайся с live-USB, монтируй корень в /mnt, при необходимости ESP в /mnt/boot, затем делай arch-chroot /mnt. Внутри chroot журнал читается обычным journalctl -b -1.
Классический симптом: загрузка доходит до какого-то юнита и стоит ровно 90 секунд, потом продолжается или падает в emergency. 90 секунд это стандартный таймаут systemd для старта юнита. Подтвердить догадку легко: в журнале юнит получит сообщение о таймауте ровно через 90 секунд после начала старта. Чаще всего виноваты три вещи.
NetworkManager-wait-online.service или systemd-networkd-wait-online.service ждут, пока сеть поднимется. Если DHCP не отвечает, юнит висит весь таймаут. Отключи ожидание:
systemctl disable NetworkManager-wait-online.service
Если какой-то юнит тянет сеть через лишнюю зависимость Requires= на legacy-сервис, убери её из unit-файла. DNS-резолвер systemd-resolved тоже умеет держать загрузку, когда не получает ответа от upstream: проверь его статус через systemctl status systemd-resolved.
В fstab прописан UUID, а устройства нет: диск отключён, флешка вынута, раздел переименован. systemd ждёт устройство 90 секунд, потом падает в emergency. Решение, опция nofail в fstab:
UUID=xxxx-xxxx /mnt/data ext4 defaults,nofail 0 2
С nofail отсутствующее устройство не блокирует загрузку. Про поля fstab подробнее рассказано в статье «Поля fstab на практике».
Медленный USB-диск или устройство, которому нужна прошивка. Таймаут ожидания устройства настраивается параметром ядра device.timeout=:
device.timeout=30
Значение задаётся в секундах, подбирай под своё железо.
Здесь systemd-analyze не поможет: зависание происходит до запуска systemd.
Если в параметрах ядра есть quiet, вывод скрывается. Убери его в меню GRUB, и ты увидишь, на какой строке всё замерло. Последняя строка перед зависанием это имя драйвера или устройства.
Журнал ядра за текущую загрузку смотри так:
journalctl -k -b
За прошлую, journalctl -k -b -1. Строки с ERROR, BUG и WARNING ищи через grep.
Подозрение на конкретный драйвер, пробуй отключить его параметром ядра:
amd_iommu=off
pci=noacpi
Меняй по одному параметру за раз и перезагружайся. Так ты отделишь виновника от случайных совпадений. Когда параметр найден, пропиши его в постоянную строку ядра в /etc/default/grub и перегенерируй grub.cfg. Общая методика таких экспериментов описана в статье «Методика решения проблем в Arch Linux».
Если подозрение на initramfs, выбери в GRUB пункт с initramfs-linux-fallback.img. Он собран с универсальным набором модулей и часто обходит проблему. Проверить содержимое образа можно так:
lsinitcpio /boot/initramfs-linux-fallback.img
Если fallback загрузился, а обычный образ нет, пересобери initramfs: mkinitcpio -P. Возможно, в образ не попал нужный модуль.
Параметр ядра rd.break останавливает загрузку внутри initramfs и даёт оболочку до монтирования корня. Оттуда видно, какие модули загрузились и виден ли корневой раздел. После выхода из оболочки загрузка продолжится штатно.
Нет. До Linux дело ещё не дошло: прошивка не передала управление загрузчику. Отключай периферию, проверяй диски, обновляй прошивку.
Да. Время старта юнитов зависит от состояния диска, сети и температуры. Смотри не на отдельные цифры, а на critical-chain: именно последовательная цепочка определяет общее время загрузки.
rescue.target это однопользовательский режим с монтированием корня и базовых сервисов. emergency.target это минимальная оболочка без монтирования чего-либо, кроме корня в режиме чтения. Для диагностики зависаний чаще нужен именно emergency.
Да. Глобально через DefaultTimeoutStartSec в /etc/systemd/system.conf, например DefaultTimeoutStartSec=30s. Для конкретного юнита через TimeoutStartSec= в его unit-файле. Но сначала найди причину: таймаут это симптом, а не болезнь.
Проверь, что nofail стоит в правильной строке и что раздел не нужен на раннем этапе загрузки. Затем посмотри systemctl list-units --failed: возможно, виноват другой юнит, а не fstab.
nofail.Полная остановка при загрузке это не случайность, а подсказка, на каком этапе что-то пошло не так. Определи этап по симптомам, посмотри тайминги systemd-analyze time, найди виновный юнит через blame и critical-chain, а если система не поднялась, читай journalctl -b -1 из emergency или chroot. В большинстве случаев виноват сетевой сервис, отсутствующий раздел из fstab или драйвер, который не смог поднять устройство. Каждая из этих проблем лечится за пару минут.
Задай вопрос в чате — отвечаем быстро, по делу и без воды.
Комментарии