Выберите продукт

Linux: когда зависает PID 1 (systemd) — D-state, stop-jobs и hung_task

Если растёт load average, сервисы не останавливаются, а перезагрузка висит на stop jobs — часто виноваты D-state и блокировки I/O. Разберём быстрый план диагностики через journalctl, systemctl list-jobs и SysRq w, а также безопасные действия и профилактику.
Linux: когда зависает PID 1 (systemd) — D-state, stop-jobs и hung_task

Ситуация из практики: на 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

Вывод SysRq w с дампом заблокированных задач в логе ядра

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 завис» — потому что он ждёт завершения того, что застряло в ядре.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Почему 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) и готовить аккуратную перезагрузку.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Что можно сделать безопасно: тактика восстановления

Цель — вернуть управляемость и не ухудшить ситуацию. Двигайтесь от «мягких» действий к «жёстким».

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 и метрики дискового I/O в консоли Linux

После перезагрузки: как найти причину и не допустить повторения

После восстановления важно не останавливаться на «само прошло». Проверьте:

  • Логи предыдущей загрузки: 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.

Поделиться статьей

Вам будет интересно

Linux: /etc/fstab и emergency mode (rescue) — как быстро поднять систему после ошибки монтирования OpenAI Статья написана AI (GPT 5)

Linux: /etc/fstab и emergency mode (rescue) — как быстро поднять систему после ошибки монтирования

Если после перезагрузки Linux падает в emergency mode или rescue из‑за /etc/fstab, чаще всего виноваты неверный UUID, опции монтир ...
systemd hardening: DynamicUser, ProtectSystem и практичный sandboxing для сервисов OpenAI Статья написана AI (GPT 5)

systemd hardening: DynamicUser, ProtectSystem и практичный sandboxing для сервисов

Пошагово усиливаем безопасность systemd-сервисов без контейнеров: включаем DynamicUser, ограничиваем файловую систему через Protec ...
JWT security: JWKS, key rotation, clock skew и защита от alg=none OpenAI Статья написана AI (GPT 5)

JWT security: JWKS, key rotation, clock skew и защита от alg=none

JWT удобны в микросервисах, но ошибки валидации быстро превращают их в дыру. Разберём JWKS и kid, ротацию ключей без даунтайма, уч ...