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

Linux shutdown/reboot hangs: systemd debug, umount busy и зависшие процессы

Если Linux зависает на shutdown или reboot, чаще всего виноваты stop jobs в systemd, busy-размонтирование, NFS-таймауты, Docker или процессы в D-state. Ниже — пошаговая диагностика через journalctl/systemctl и варианты фикса без угадываний.
Linux shutdown/reboot hangs: systemd debug, umount busy и зависшие процессы

Что именно «зависает» при shutdown/reboot

Ситуации вида linux reboot hangs или shutdown hangs обычно выглядят одинаково: вы запускаете shutdown/reboot, консоль показывает «Stopping…», «A stop job is running…», «Unmounting…», а дальше тишина. Важно понимать: в systemd выключение — это такой же набор юнитов и зависимостей, как и запуск. Если какой-то шаг не завершился, менеджер будет ждать до таймаута (или бесконечно, если зависло ядро/драйвер).

Типовые точки «залипания»:

  • Остановка сервисов: демон не завершает воркеры, завис на I/O, держит сокеты/файлы.
  • Размонтирование ФС: umount target is busy, открытые дескрипторы, cwd процесса внутри mountpoint, nested/bind-mount.
  • Сетевые ФС: nfs umount timeout — клиент ждёт сервер, а сеть уже «уехала».
  • Контейнеры: docker shutdown hang — долгий stop контейнеров, зависшие overlay-mount, тома.
  • Процессы в D state: tasks in D state (uninterruptible sleep) — такие процессы сигналами не убиваются и могут держать выключение.

Ниже — практический чеклист: быстро понять, где зависло; найти конкретного виновника; исправить причину; и только в самом конце применять аварийные меры.

Быстро понять, на каком шаге остановка

1) Смотрим предыдущую загрузку: journalctl -b -1

Если машина «не выключилась» и вы перезапустили её аппаратно (или через панель), самый полезный артефакт — журнал предыдущей загрузки. Он часто содержит строку, где зависли stop jobs и на каком юните.

journalctl -b -1 -e

Ищите по словам: A stop job is running, Unmounting, umount, nfs, docker, timed out, failed, killed.

Полезно точечно фильтровать:

journalctl -b -1 -g "A stop job is running" -e
journalctl -b -1 -g "Unmounting" -e

2) Во время зависания: что показывает systemd прямо сейчас

Когда система ещё жива (есть SSH/консоль) и «висит» на stop job, сначала посмотрите текущие задания systemd и выясните, какой юнит блокирует остановку.

systemctl list-jobs
systemctl status --no-pager

Если видно конкретный юнит со статусом «Stopping…» — сразу переходите к диагностике этого сервиса и его ресурсов (файлы, сокеты, примонтированные ФС, сеть).

3) Контекст зависимостей: что от чего зависит

systemd-analyze critical-chain формально показывает критическую цепочку для загрузки, но в реальной жизни помогает понять «архитектуру» зависимостей: какие сервисы сцеплены, и где можно получить неправильный порядок остановки (например, сеть падает раньше NFS).

systemd-analyze critical-chain

Пример диагностики зависания выключения через journalctl -b -1 и сообщения stop job

Разбираем «umount target is busy» и почему это стопорит shutdown

Классика: systemd пытается размонтировать файловую систему, но получает umount target is busy. Это означает, что внутри mountpoint кто-то держит:

  • открытые файлы (лог, база, PID-файл, сокет);
  • текущую рабочую директорию процесса (cwd);
  • nested/bind-mount внутри;
  • активный loop device, overlay, fuse.

1) Находим, кто держит mountpoint

Самые практичные инструменты — lsof и fuser.

lsof +f -- /mnt/data
fuser -vm /mnt/data

Если lsof слишком тяжёлый (большие системы, тысячи файлов), можно быстро проверить, чья cwd находится внутри каталога:

find /proc -maxdepth 2 -type l -name cwd -exec readlink -f {} \; 2>/dev/null | grep -F "/mnt/data"

Если система уже частично «развалила» ФС, часть /proc/*/cwd может читаться с ошибками — это ожидаемо.

2) Что делать с найденными процессами

Если это штатный сервис — останавливайте его корректно через systemd, чтобы он сам закрыл файлы и отпустил рабочие каталоги:

systemctl stop your-service

Дальше — быстро понять, где он завис:

systemctl status your-service --no-pager
journalctl -u your-service -e

Если нужно добить руками (осознанно понимая последствия для данных):

kill -TERM 1234
kill -KILL 1234

Если даже SIGKILL не помогает — это сильный сигнал, что процесс в D state (ниже) или ядро ждёт I/O.

3) «Лечебные» варианты размонтирования

Иногда, чтобы закончить обслуживание, помогает «ленивое» размонтирование: точка монтирования исчезает из дерева, а реальное освобождение произойдёт, когда процессы отпустят ссылки.

umount -l /mnt/data

Для некоторых сетевых ФС применяют форс-размонтирование:

umount -f /mnt/nfs

umount -f и umount -l — это аварийный выход, а не лечение причины. После таких действий проверьте приложения на консистентность и корректную остановку.

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

Процессы в D state: почему не убиваются и ломают выключение

tasks in D state — частая причина «магических» зависаний. Процесс находится в uninterruptible sleep, обычно ожидая завершения I/O (диск, сеть, NFS, iSCSI, зависший device-mapper, проблемы со сториджем/драйвером). В этом состоянии SIGKILL не действует: процесс не исполняется, он «заморожен» в ожидании ядра.

1) Быстро найти D-state и понять, чего он ждёт

ps axo pid,stat,comm,wchan:32 | awk '$2 ~ /D/ {print}'

Колонка wchan подсказывает, на чём именно ждёт процесс (часто можно увидеть намёки на блоковый слой, ФС или NFS). Если нужно углубиться:

cat /proc/1234/stack

Если стек/ожидание указывает на NFS или блоковые операции, проблема почти всегда «ниже» приложения: сеть, диск, драйвер, хранилище, деградация RAID, timeouts.

2) Что смотреть по диску и ядру

Первым делом — сообщения ядра: они часто прямо говорят про таймауты, reset устройства, I/O error или «hung task».

dmesg -T | tail -n 200

Если доступны утилиты мониторинга I/O, посмотрите, не упёрся ли диск в ожидания:

iostat -xz 1

При постоянных таймаутах сториджа выключение может «никогда» не завершиться корректно: systemd ждёт остановки демонов, демоны ждут fsync, fsync ждёт диск.

NFS и сетевые файловые системы: типичная причина nfs umount timeout

При выключении порядок критичен: если сеть/маршрутизация падают раньше, чем NFS успевает размонтироваться, вы получаете nfs umount timeout, stop jobs и зависание. Это особенно заметно на серверах, где NFS используется для бэкапов, медиа или общих каталогов приложений.

1) Диагностика NFS

Посмотрите, что примонтировано и с какими опциями:

findmnt -t nfs,nfs4

И проверьте журнал (включая предыдущую загрузку, если выключение закончилось аппаратным ребутом):

journalctl -b -1 -g "nfs" -e

2) Практические меры, чтобы выключение не висло

  • Сеть должна жить до конца: убедитесь, что NFS размонтируется до остановки сетевых сервисов. На «чистом» systemd это обычно учтено, но кастомные юниты и ручные mount-скрипты часто ломают зависимости.
  • Используйте automount там, где возможно: меньше активных зависимостей на момент shutdown.
  • Планируйте недоступность NFS: приложения должны переживать ситуацию «сервер NFS недоступен», иначе даже обычный ребут после обновления ядра может превратиться в аварийный.

Если у вас много контейнеров и сетевых томов, дополнительно посмотрите практику из статьи про изоляцию контейнеров и окружения: про gVisor/Firecracker и границы изоляции контейнеров.

Docker shutdown hang: почему контейнеры держат reboot

Docker/containerd добавляют несколько слоёв: контейнерные процессы, сеть/неймспейсы, overlay-mount, тома. На shutdown systemd останавливает docker.service, а docker пытается корректно остановить контейнеры, ожидая graceful shutdown по таймауту. Если контейнеры зависли (или внутри D-state из-за storage/NFS), выключение тянется.

1) Найти «упёртый» контейнер и остановить его

docker ps

Попробуйте дать контейнеру адекватный таймаут на завершение:

docker stop --time 10 container_name

Если не помогло:

docker kill container_name

Если контейнер «умер», но монтирования остаются, проверьте D-state у процессов на хосте и активные overlay-mount:

findmnt | grep -E "overlay|docker"

2) На будущее: снизить риск зависаний

  • Давайте приложениям корректно завершаться: правильные сигналы (PID 1), корректные stop-timeout, graceful shutdown.
  • Не храните критичные данные контейнеров на нестабильных сетевых ФС без продуманной деградации.
  • Следите за диском, inode и ошибками ФС: overlay довольно быстро упирается в проблемы сториджа.

Если на хосте есть сложности с правилами фильтрации трафика и после ребута сеть поднимается «не так», это тоже может влиять на сетевые ФС и остановку сервисов. По теме — как Docker взаимодействует с iptables/nftables.

Команды поиска umount busy и процессов в D-state: lsof, fuser, ps wchan и findmnt

systemd: как включить более подробный debug shutdown

Если проблема воспроизводится, лучший подход — собрать подробный лог выключения, а не гадать. Начать можно с увеличения уровня логирования systemd-менеджера, чтобы в журнале было больше деталей.

1) Временное повышение логирования systemd

На работающей системе можно поднять уровень логирования (до следующей перезагрузки или до изменения обратно):

systemd-analyze log-level debug

После попытки обычного reboot анализируйте журнал предыдущей загрузки:

journalctl -b -1 -e

2) Журналы юнитов, которые чаще всего «держат» shutdown

Соберите хвосты логов по подозрительным сервисам:

journalctl -b -1 -u docker -e
journalctl -b -1 -u nfs-client.target -e

И посмотрите список mount-юнитов (часто именно они висят на размонтировании):

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

Когда нужно быстро восстановить управление: безопасные и аварийные варианты

Иногда задача не «идеально завершить», а вернуть сервер в строй. Важно различать меры, которые обычно безопасны, и меры, после которых нужна проверка ФС/приложений.

Относительно безопасно

  • Остановить зависший сервис через systemctl stop, затем проверить логи и перезапустить.
  • Найти процессы, держащие mount, и корректно завершить именно их (а не «рубить» всё подряд).
  • Осознанно снизить таймаут graceful stop для конкретного сервиса, чтобы он не держал shutdown бесконечно.

Аварийно (использовать осознанно)

  • umount -l или umount -f для размонтирования проблемного mountpoint.
  • Принудительная перезагрузка, если система не реагирует, и вы принимаете риск потери данных в кеше.

Если причина — D-state из-за диска или сетевого хранилища, «жёсткая» перезагрузка может быстрее вернуть сервис, но повышает риск повреждения данных. По возможности сначала выясните источник I/O-зависания.

Профилактика: чтобы shutdown/reboot не превращались в лотерею

  • Порядок остановки: проверьте, что сетевые сервисы не убивают сеть раньше размонтирования NFS.
  • Мониторинг D-state и hung tasks: если периодически появляются D-процессы — это почти всегда проблема storage/сети/драйвера.
  • Разделяйте роли: когда на одной машине и база, и NFS-клиент, и Docker с десятками контейнеров — шанс сложного зависания выше.
  • Привычка смотреть журналы: journalctl -b -1 после нештатной перезагрузки часто находит причину до того, как она станет постоянной.

Если вы планируете перенос сервисов на отдельную виртуализацию, удобный практический вариант — вынести «шумные» роли (Docker, сборки, мониторинг) на VDS, а сайты с типовой нагрузкой держать на виртуальном хостинге, чтобы уменьшить число сложных зависимостей на одном сервере.

Мини-чеклист диагностики (сохраните в заметки)

  1. После нештатного ребута: journalctl -b -1 -e и поиск stop job/umount/nfs/docker.
  2. Если зависание сейчас: systemctl list-jobs, затем systemctl status --no-pager.
  3. Если umount busy: lsof +f -- /mount или fuser -vm /mount.
  4. Если процессы не убиваются: ищите D-state через ps ... wchan и смотрите /proc/PID/stack, dmesg.
  5. Если NFS: findmnt -t nfs,nfs4, проверяйте порядок остановки сети и поведение при недоступности сервера.
  6. Если Docker: остановите проблемные контейнеры, проверьте overlay-mount и D-state на хосте.

Если захотите, можно расширить этот материал готовыми systemd drop-in примерами: как ограничить время остановки сервиса (через TimeoutStopSec), и как аккуратно выстроить Before/After для mount-юнитов и сетевых целей под Debian/Ubuntu и Alma/Rocky.

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

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

IO wait и steal time на VDS: как диагностировать задержки vmstat, iostat, pidstat OpenAI Статья написана AI (GPT 5)

IO wait и steal time на VDS: как диагностировать задержки vmstat, iostat, pidstat

Когда VDS начинает «тормозить», чаще всего причина в iowait, steal time или очередях диска. Ниже — практичная схема диагностики на ...
TLS trust store и ERR_CERT_AUTHORITY_INVALID: как починить цепочку сертификатов и verify error OpenAI Статья написана AI (GPT 5)

TLS trust store и ERR_CERT_AUTHORITY_INVALID: как починить цепочку сертификатов и verify error

ERR_CERT_AUTHORITY_INVALID и openssl verify error обычно сводятся к двум причинам: сервер отдает неполную цепочку (intermediate mi ...
Nginx proxy_cache: cache_key, Vary и как поднять hit ratio без утечек приватных данных OpenAI Статья написана AI (GPT 5)

Nginx proxy_cache: cache_key, Vary и как поднять hit ratio без утечек приватных данных

Низкий hit ratio в Nginx proxy_cache чаще связан не с размером кеша, а с неправильным proxy_cache_key и игнорированием Vary. Разбе ...