Ситуация из практики: на Linux «подвисает» systemd (он же PID 1), systemctl отвечает с задержками или «висит», перезагрузка застревает на «A stop job is running…», а в логах появляются сообщения про hung_task. Почти всегда рядом — высокий load average при не слишком занятом CPU и процессы в D-state (непрерываемое ожидание I/O).
Главная мысль: systemd редко является первопричиной. Обычно он корректно ждёт завершения юнитов, а те ждут ядро, диск, файловую систему или сетевое хранилище. Поэтому задача администратора — быстро понять, что именно «держит» остановку: зависший I/O, недоступный NFS, ошибки блочного устройства, деградация storage, неудачный ExecStop или слишком оптимистичные таймауты.
Как выглядит проблема: признаки и типовые симптомы
Чаще всего вы видите один или несколько симптомов:
systemctl statusработает очень медленно или не возвращает результат.Перезагрузка/выключение зависает на «stop job» (часто с именем конкретного юнита).
load averageвысокий, но CPU не обязательно загружен — в load входят задачи вD-state.В журнале ядра: «task ... blocked for more than ... seconds», упоминания
hung_task_timeout_secs.Процессы со статусом
Dвpsне убиваются дажеSIGKILL.
Процесс в
D-state не «плохой» сам по себе: он ждёт ответ от ядра. Но бесконечное ожидание почти всегда указывает на проблему ниже уровня systemd — I/O, файловая система, сеть/хранилище, драйвер, аппаратная деградация.
Быстрый план диагностики (когда «горит»)
Здесь порядок действий, который даёт максимум сигнала за минимум времени. Идеально — сохранить вывод команд в файл/консоль, чтобы после перезагрузки было с чем разбираться.
1) Оцените load average и долю D-state
Сначала отделяем «тяжело по CPU» от «тяжело по I/O»:
uptime
cat /proc/loadavg
Дальше — кто именно в D-state и на чём ждёт:
ps -eo pid,ppid,stat,wchan:32,comm --sort=stat | head -n 80
ps -eo pid,stat,comm | awk '$2 ~ /D/ {print}' | head
Поле wchan часто подсказывает источник блокировки (диск/ФС/сетевые RPC). Это не абсолютная истина, но хорошая отправная точка.
2) Поймите, на каком stop job зависает systemd
Если «экран стоп-джоба» уже на консоли — запомните имя юнита. В живой системе:
systemctl list-jobs
systemctl --failed
systemctl status --no-pager
Для конкретного сервиса полезно проверить таймауты и политику убийства процессов:
systemctl status SERVICE --no-pager
systemctl show SERVICE -p TimeoutStopUSec -p KillMode -p KillSignal -p SendSIGKILL -p FinalKillSignal
Если процесс в D-state, любые сигналы (включая SIGKILL) «не сработают» до выхода из ожидания. Тогда systemd будет ждать до таймаута, а иногда и дольше, если зависла ключевая часть user space (например, FS/логирование).
3) Посмотрите логи текущей и прошлой загрузки
Сравнение текущего boot и предыдущего часто сразу показывает источник: отвал сетевого хранилища, таймауты диска, reset контроллера, ошибки ext4/xfs.
journalctl -b -0 --no-pager | tail -n 200
journalctl -b -1 --no-pager | tail -n 200
journalctl -k -b -0 --no-pager | tail -n 200
Точечно по сервису:
journalctl -b -0 -u SERVICE --no-pager | tail -n 200

4) «Снимок зависания» через SysRq: дамп заблокированных задач
Когда user space «плывёт», самый ценный артефакт — стек заблокированных задач. SysRq просит ядро вывести информацию в лог почти независимо от состояния процессов.
Проверьте, включён ли SysRq:
cat /proc/sys/kernel/sysrq
Если там 0, временно включите (до перезагрузки):
sysctl -w kernel.sysrq=1
Запросите дамп заблокированных задач:
echo w > /proc/sysrq-trigger
Сразу после этого смотрите вывод:
dmesg | tail -n 200
journalctl -k -b -0 --no-pager | tail -n 200
В дампе обычно видно, где именно «висит» поток: ожидание I/O, блокировки в FS, RPC/NFS ожидания. Это часто самый быстрый ответ на вопрос «почему PID 1 завис» — потому что он ждёт завершения того, что застряло в ядре.
Почему D-state ломает остановку сервисов и «вешает» systemctl
Состояние D — это непрерываемый сон: задача ждёт завершения операции в ядре и не может быть принудительно прервана сигналами. Отсюда типовая картина:
kill -9«не работает»: сигнал будет доставлен, но применится только после выхода процесса изD.systemdдолго «стоит» на stop job: он отправляет сигналы и ждёт, но процесс физически не может завершиться.systemctlвыглядит зависшим, потому чтоsystemdзанят транзакциями остановки/зависимостями или сам упирается в I/O (например, чтение unit-файлов, запись статусов, логирование).
Частые источники D-state на боевых системах:
Диск/RAID/контроллер/NVMe: высокая латентность, timeouts, растущая очередь, «замерзание» потоков.
Сетевые ФС (NFS/CephFS/GlusterFS), иногда iSCSI: при сетевых сбоях монтирование может «держать» процессы намертво.
Запись логов/журнала/БД на переполненный или деградирующий storage.
Баги драйверов (в том числе в виртуализации и при специфических storage-драйверах).
Если сервисы крутятся на сервере без прямого доступа, полезно иметь консоль и стабильную инфраструктуру под нагрузкой. Для таких задач обычно выбирают VDS, где проще контролировать диски, ядро и отладку инцидентов.
hung_task и hung_task_timeout_secs: что это и как читать
Подсистема hung task в ядре проверяет, есть ли задачи, которые слишком долго не выходят из ожидания, и пишет предупреждения. Таймаут задаётся параметром hung_task_timeout_secs.
Проверить текущее значение:
cat /proc/sys/kernel/hung_task_timeout_secs
Временно увеличить (например, чтобы снизить «шум» в логе во время инцидента):
sysctl -w kernel.hung_task_timeout_secs=120
Или отключить предупреждения (только как временную меру):
sysctl -w kernel.hung_task_timeout_secs=0
Отключение hung task не лечит проблему. Это лишь отключает «сигнализацию». Делайте так только если вы уже собираете диагностику и понимаете, что именно происходит.
Проверяем I/O: когда load average растёт из-за диска
Если много задач в D-state, почти всегда виноваты очереди I/O и/или ошибки storage. Быстрые команды:
vmstat 1 10
iostat -xz 1 10
Если iostat недоступен, хотя бы посмотрите на счётчики дисков:
cat /proc/diskstats | head
И обязательно проверьте сообщения ядра по ошибкам устройств и файловых систем:
dmesg -T | egrep -i 'error|warn|fail|reset|timeout|nvme|blk|ext4|xfs|scsi' | tail -n 200
Если видите timeouts/reset/ошибки чтения — не пытайтесь «лечить systemd». Сначала стабилизируйте storage: проверьте состояние RAID, доступность томов, место на FS, поведение диска под нагрузкой.
Отдельный класс: зависший NFS/сетевое хранилище
При проблемах с NFS часто «умирают» любые процессы, которые трогают точку монтирования (даже ls может повиснуть). Проверьте, что смонтировано:
mount | egrep -i 'nfs|cifs|fuse|gluster|ceph'
Если у вас NFS в продакшене, полезно заранее понимать риски и отличия вариантов хранения. По теме можно почитать: NFS vs SSHFS: что выбрать для хранения на сервере.
Когда systemctl «висит»: отделяем проблемы systemd от D-Bus и общего деграда
Иногда ощущение «systemctl hang» связано с тем, что запрос завис на D-Bus или systemd перегружен транзакциями. Минимальная проверка:
ps -eo pid,stat,comm | egrep 'systemd|dbus'
Проверьте команды, которые обычно быстрее и проще:
systemctl is-system-running
systemctl list-units --type=service --state=running --no-pager | head
Если и они «встают колом», высока вероятность, что проблема системная (чаще всего I/O). В этом случае ценнее не «дожимать systemctl», а снять диагностику (логи, SysRq) и готовить аккуратную перезагрузку.
Что можно сделать безопасно: тактика восстановления
Цель — вернуть управляемость и не ухудшить ситуацию. Двигайтесь от «мягких» действий к «жёстким».
1) Соберите диагностику до резких шагов
Даже если вы планируете перезагрузку, постарайтесь снять минимум:
date; uptime
ps -eo pid,ppid,stat,wchan:32,comm --sort=stat | head -n 80
systemctl list-jobs
journalctl -k -b -0 --no-pager | tail -n 300
echo w > /proc/sysrq-trigger
dmesg | tail -n 300
Этот набор часто экономит часы, потому что после рестарта «симптомы» исчезают, а причина остаётся.
2) Если повторяется долгий stop конкретного сервиса — настройте таймауты
Когда вы убедились, что сервис тормозит остановку логически (например, стоп-скрипт ждёт внешний ресурс), задайте явный таймаут. Удобнее всего — drop-in:
systemctl edit SERVICE
Пример содержимого:
[Service]
TimeoutStopSec=30s
KillMode=mixed
SendSIGKILL=yes
Примените:
systemctl daemon-reload
Если же процессы в D-state, эти настройки не «убьют» зависший I/O, но помогут избежать вечных ожиданий в сценариях, где проблема именно в остановке юнита, а не в ядре.
3) Если shutdown часто висит — проверьте дефолтные таймауты systemd
Иногда стоит ограничить общие таймауты, чтобы перезагрузка была предсказуемой. Настройки — в /etc/systemd/system.conf (например, DefaultTimeoutStopSec).
Текущее значение можно посмотреть так:
systemctl show --property=DefaultTimeoutStopUSec
Слишком маленькие таймауты опасны: базы данных и очереди могут не успеть завершиться корректно.
4) Когда user space мёртв, но ядро живо: управляемая перезагрузка через SysRq
Если система не реагирует, но SysRq работает, можно попытаться перезагрузиться «мягче», чем жёсткий reset. Часто используют шаги sync/remount/reboot:
echo s > /proc/sysrq-trigger
echo u > /proc/sysrq-trigger
echo b > /proc/sysrq-trigger
Если проблема в зависшем storage или драйвере, даже echo s может не завершиться. Тогда остаётся только перезапуск на уровне гипервизора или железа.

После перезагрузки: как найти причину и не допустить повторения
После восстановления важно не останавливаться на «само прошло». Проверьте:
Логи предыдущей загрузки:
journalctl -b -1иjournalctl -k -b -1. Ищите I/O errors, timeouts, reset, сообщения файловой системы.Состояние дисков (SMART/NVMe health), ошибки контроллера на уровне ядра, заполненность FS и скорость записи.
Если было сетевое хранилище — стабильность сети и поведение клиента (таймауты, ретраи, зависания RPC).
Если зависание было на stop job конкретного юнита — изучите
ExecStop, зависимости и что именно он ждёт при остановке.
Если у вас PHP и сессии лежат на NFS, это отдельный частый источник «медленных» зависаний и стоп-джобов. См. разбор: как NFS влияет на PHP-сессии и GC.
Мини-справочник: команды, которые чаще всего помогают
# systemd / jobs
systemctl list-jobs
systemctl status --no-pager
systemctl show SERVICE -p TimeoutStopUSec -p KillMode
# logs / boot
journalctl -b -0 --no-pager | tail -n 200
journalctl -b -1 --no-pager | tail -n 200
journalctl -k -b -0 --no-pager | tail -n 200
# D-state and where it waits
ps -eo pid,ppid,stat,wchan:32,comm --sort=stat | head -n 80
# kernel snapshot of blocked tasks (sysrq w)
cat /proc/sys/kernel/sysrq
sysctl -w kernel.sysrq=1
echo w > /proc/sysrq-trigger
journalctl -k -b -0 --no-pager | tail -n 200
# hung_task timeout
cat /proc/sys/kernel/hung_task_timeout_secs
sysctl -w kernel.hung_task_timeout_secs=120
Итоги
Если вы видите «вечные» systemd stop job, высокий load average при низком CPU, процессы в D-state и предупреждения hung_task, думайте не «сломался systemd», а «ядро ждёт I/O/FS/сеть». Самые полезные действия: быстро зафиксировать состояние (особенно через sysrq w), посмотреть логи текущей и прошлой загрузки через journalctl, найти конкретный ресурс, который держит ожидание, и уже затем править таймауты/юниты или лечить storage.


