Ви перезавантажуєте сервер Debian 13 за рутинною причиною — оновлення ядра, прошивки або «швидкою» зміною сховища — і він повертається з оптимістичним повідомленням:
«Dependency failed». Запит на вхід ніколи не зʼявляється, або ви опиняєтеся в emergency mode, дивлячись на миготливий курсор і сумні роздуми про свої рішення.
Сутність у тому, що systemd рідко «ламає систему». Він руйнує один юніт, і одного юніта (або невеликого ланцюжка) достатньо, щоб зупинити завантаження. Ваше завдання — ідентифікувати
один сервіс, що блокує старт, а потім вирішити — виправити його, ізолювати або зробити завантаження стійким до його відсутності.
Що насправді означає «Dependency failed» у systemd
systemd — це планувальник залежностей. Він перетворює «запусти машину» на спрямований граф юнітів (сервіси, точки монтування, сокети, пристрої, таргети).
Коли ви бачите «Dependency failed», зазвичай ви бачите низхідний симптом, а не первинну причину.
Приклад: remote-fs.target може провалитися через один .mount-юніт, який провалився, що могло статись через відсутній пристрій,
що могло бути через те, що LUKS-контейнер не було розблоковано, що могло статися через відсутній keyfile. systemd ввічливо повідомить про
«dependency failed» на кожному кроці. Це як почути «зустріч скасовано» і намагатися налагодити весь корпоративний календар.
Три відносини юнітів, що мають значення під час завантаження
- Requires= — жорстка залежність. Якщо A
Requires=Bі B провалився, A провалюється. - Wants= — мʼяка залежність. Якщо B провалився, A може продовжити роботу.
- After=/Before= — лише порядок. Не означає залежність, але може створювати ланцюжки «очікування», які виглядають як зависання.
Більшість зависань при завантаженні, що демонструють «Dependency failed», зводяться до одного з цього: монтовання, яке не може змонтуватися, пристрій, який ніколи не зʼявляється,
очікування network-online або імпорт сховища, що таймаутиться. Знайдіть той один юніт — і ви знайдете нитку для розтягування.
Жарт №1: systemd не «повільний»; він просто надзвичайно відповідальний у чеканні тієї єдиної речі, яку ви пообіцяли, що вона буде.
Швидкий план діагностики (зробіть це спочатку)
Це послідовність із високим сигналом, коли у вас є консоль (фізична, IPMI або VM-консоль) і вам потрібно швидко знайти винуватця. Ви полюєте
за юнітом, який або завалився, або чекає вічно.
1) Отримайте шел без витрачання часу
Якщо ви застрягли в завантажувальному сплеші, переключіться на інший TTY (часто Ctrl+Alt+F2). Якщо ви в emergency mode, у вас вже є шел.
Якщо ви не можете залогінитися, використайте recovery mode у GRUB або додайте systemd.unit=emergency.target для цього завантаження.
2) Визначте, що провалилося під час попереднього завантаження
Виконайте journalctl -b -1 -p err (якщо ви перезавантажилися) або journalctl -b -p err (поточне завантаження). Вам потрібна перша помилка,
а не остання скарга.
3) Спробуйте systemd: хто блокував критичний шлях завантаження
systemd-analyze critical-chain вкаже юніт, який домінував у часі завантаження. Якщо ви бачите mount або network-online target, що стоїть по 1–2 хвилини,
це ваш блокатор. Якщо бачите сервіс «waiting», інспектуйте його залежності за допомогою systemctl list-dependencies.
4) Підтвердіть один юніт і його верхньопричину
Для цього юніта виконайте systemctl status UNIT і потім journalctl -u UNIT -b. Якщо це монт: перевірте /etc/fstab.
Якщо це сховище: перевірте наявність пристрою. Якщо це network-online: перевірте, чи стек мережі дійсно використовує очікуваний механізм.
5) Прийміть рішення: виправити зараз, обійти зараз або ізолювати
- Виправити зараз: виправити
fstab, розблокувати LUKS, імпортувати пул, виправити файл юніта. - Обійти зараз: тимчасово закоментувати рядок у
fstab, додатиnofailабо замаскувати неважливий юніт. - Ізолювати: завантажитися в
multi-user.targetбез проблемного таргету, або скористатися emergency mode, щоб відновити контроль.
Вашою метою є насамперед доступність, а вже потім досконалість. Систему не хвилює, що ваш NFS-монтування «важливе», якщо воно перешкоджає запуску SSH.
Цікаві факти та історичний контекст (для вашої ментальної моделі)
- systemd не просто замінив SysV init; він змінив філософію завантаження. Замість лінійних скриптів завантаження стало графом залежностей із задачами та таймаутами.
- Фраза «Dependency failed» — це повідомлення systemd про поширення помилки задачі, а не критична помилка ядра. Це рівень вище і зазвичай вирішується без перевстановлення.
- Debian прийняв systemd за замовчуванням у Debian 8 (Jessie), після років дискусій. Основний операційний вплив: менше «таємничих пауз» в init-скриптах, більше явного порядку.
-
Таргети на кшталт
network-online.targetіснують тому, що «мережа налаштована» і «мережа працездатна» — різні стани; багато сервісів помилково залежать від останнього. -
remote-fs.targetіlocal-fs.target— це координаційні точки, а не «реальні сервіси». Один поганий mount може взяти їх у заручники. -
Обробка mount у systemd тісно інтегрована з
/etc/fstab. Помилка в ньому може проявитися як провал юніта, а не дружнє повідомлення відmount. - LUKS і dm-crypt зазвичай оркеструються під час завантаження initramfs і systemd-юнітами; відсутній ключовий файл може стати «dependency failed» на два кроки від реальної проблеми.
- Стандартна конфігурація journald у Debian історично балансувала використання диска проти форензики. Якщо журнали є лише у памʼяті, ви можете втратити докази після жорсткого перезавантаження.
Одна надійна ідея, переказана від W. Edwards Deming: результати системи в основному визначає самa система, а не геройські зусилля.
Це стосується й завантаження — виправляйте систему залежностей, а не лише сьогоднішню помилку.
Метод «одного блокатора»: ізолюйте юніт, що зупиняє завантаження
«Dependency failed» голосно, але неінформативно. Корисне питання: який юніт найраніше у ланцюжку помилок і/або який юніт найдовше стоїть у critical chain?
Часто вони співпадають, але не завжди.
Два шаблони, які ви побачите
Шаблон A: юніт провалюється швидко, інші юніти падають як наслідок
Це чистий випадок. Приклад: mnt-data.mount провалюється через те, що UUID не існує. Тоді local-fs.target повідомляє про dependency failure,
і ви потрапляєте в emergency mode.
Шаблон B: юніт не провалюється; він чекає до таймауту
Це випадок «відчуття зависання». Приклад: systemd-networkd-wait-online.service чекає 2 хвилини на лінк, який ніколи не зʼявляється.
Система врешті-решт завантажується, але пізно, і ви отримаєте dependency failures, якщо інші сервіси вимагають «online», а не «configured».
Операційне правило: звинувачуйте перший upstream юніт, а не таргет
Коли таргет провалюється, це майже ніколи не вина самого таргету. Таргет — це поштова скринька. Лист всередині — це провалений mount, провалений імпорт,
застарілий шлях до пристрою або сервіс з жорсткою залежністю, якої він не повинен мати.
Найшвидший спосіб знайти «один сервіс»:
(1) перелічити провалені юніти,
(2) перевірити critical chain,
(3) прочитати журнал для того юніта,
(4) змоделювати граф залежностей настільки, щоб побачити, чого саме бракує.
Практичні завдання (команди, що означає вивід, рішення)
Це польові команди, які ви можете виконати на Debian 13. Кожне завдання показує, на що дивитися і яке рішення застосувати. По можливості виконувати їх у порядку.
Коли система напівзавантажена, віддавайте перевагу journalctl та systemctl замість гадань.
Завдання 1 — Перелічити провалені юніти (ваш перший шортлист)
cr0x@server:~$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● mnt-data.mount loaded failed failed /mnt/data
● systemd-networkd-wait-online.service loaded failed failed Wait for Network to be Configured
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit state, i.e. generalization of SUB.
SUB = The low-level unit state, values depend on unit type.
2 loaded units listed.
Що це означає: У вас є конкретні підозрювані. Ігноруйте «targets», якщо тільки вони не є єдиними у списку.
Рішення: оберіть юніт, що відповідає симптомам завантаження: emergency mode часто вказує на mount-и; тривалі завантаження часто повʼязані з wait-online.
Завдання 2 — Подивіться, що блокувало час завантаження (critical chain)
cr0x@server:~$ systemd-analyze critical-chain
graphical.target @2min 4.112s
└─multi-user.target @2min 4.112s
└─remote-fs.target @2min 3.900s
└─mnt-nfs.mount @2min 3.880s +2min
└─network-online.target @3.870s
└─systemd-networkd-wait-online.service @1.500s +2.360s
└─systemd-networkd.service @1.200s +250ms
└─systemd-udevd.service @900ms +280ms
└─systemd-tmpfiles-setup-dev.service @650ms +220ms
└─kmod-static-nodes.service @420ms +200ms
└─systemd-journald.socket @380ms
└─system.slice @370ms
Що це означає: mnt-nfs.mount витратив 2 хвилини. Це ваш вузький місце, навіть якщо «Dependency failed» вказує на інше.
Рішення: дослідіть це монт і чому воно вимагає network-online; вирішіть, чи має воно бути з nofail або автозамонтовуватися.
Завдання 3 — Показати точні рядки помилок з поточного завантаження
cr0x@server:~$ journalctl -b -p err --no-pager
Mar 12 08:41:02 server systemd[1]: mnt-data.mount: Mount process exited, code=exited, status=32/n/a
Mar 12 08:41:02 server systemd[1]: mnt-data.mount: Failed with result 'exit-code'.
Mar 12 08:41:02 server systemd[1]: Failed to mount /mnt/data.
Mar 12 08:41:02 server systemd[1]: local-fs.target: Dependency failed for Local File Systems.
Mar 12 08:41:10 server systemd-networkd-wait-online[412]: Timeout occurred while waiting for network connectivity.
Що це означає: Є принаймні дві незалежні проблеми: локальний mount, що впав, та таймаут wait-online.
Рішення: спочатку виправляйте локальні монти, якщо ви в emergency mode; потім розбирайтеся з wait-online, якщо завантаження просто повільне.
Завдання 4 — Інспектуйте статус підозрілого юніта (що systemd думає сталося)
cr0x@server:~$ systemctl status mnt-data.mount --no-pager
× mnt-data.mount - /mnt/data
Loaded: loaded (/etc/fstab; generated)
Active: failed (Result: exit-code) since Wed 2025-03-12 08:41:02 UTC; 2min 12s ago
Where: /mnt/data
What: UUID=2f2c3a5b-8d5e-4e1b-b4d2-2e1b1f4d2f20
Tasks: 0 (limit: 9250)
Memory: 0B
CPU: 8ms
Error: 32 (Mount failure)
Mar 12 08:41:02 server systemd[1]: Mounting /mnt/data...
Mar 12 08:41:02 server mount[771]: mount: /mnt/data: special device UUID=2f2c3a5b-8d5e-4e1b-b4d2-2e1b1f4d2f20 does not exist.
Mar 12 08:41:02 server systemd[1]: mnt-data.mount: Mount process exited, code=exited, status=32/n/a
Mar 12 08:41:02 server systemd[1]: mnt-data.mount: Failed with result 'exit-code'.
Що це означає: Це згенерований юніт монту з /etc/fstab, і зазначений UUID відсутній.
Рішення: підтвердіть, чи диск зник, перейменований, не розшифрований або UUID змінився; виправте fstab відповідно.
Завдання 5 — Підтвердьте, що пристрій існує (не довіряйте fstab)
cr0x@server:~$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1 vfat FAT32 9C2B-1A1B 504.7M 1% /boot/efi
├─sda2 ext4 1.0 6e6a86fb-4d93-4b8b-9b62-6a0c9b99afc2 712.4M 22% /boot
└─sda3 crypto 2 1f7c0a2c-3f9f-4e5a-9d3c-6d7f8e9a1b2c
└─cryptroot
ext4 1.0 2b1c4d9a-9d10-4d0a-ae91-5f8b21c4b1a1 38.9G 41% /
sdb
└─sdb1 ext4 1.0 DATA 9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
Що це означає: UUID у fstab не відповідає дійсній інформації на диску. Файлова система DATA існує, але має інший UUID.
Рішення: оновіть /etc/fstab до правильного UUID (або використовуйте LABEL=DATA, якщо маркування у вас дисципліноване).
Завдання 6 — Ретельно перегляньте /etc/fstab (песимістично)
cr0x@server:~$ sed -n '1,200p' /etc/fstab
# /etc/fstab: static file system information.
UUID=2b1c4d9a-9d10-4d0a-ae91-5f8b21c4b1a1 / ext4 errors=remount-ro 0 1
UUID=6e6a86fb-4d93-4b8b-9b62-6a0c9b99afc2 /boot ext4 defaults 0 2
UUID=9C2B-1A1B /boot/efi vfat umask=0077 0 1
UUID=2f2c3a5b-8d5e-4e1b-b4d2-2e1b1f4d2f20 /mnt/data ext4 defaults 0 2
Що це означає: Один рядок посилається на UUID, якого не існує.
Рішення: якщо /mnt/data є опційним для завантаження, додайте nofail,x-systemd.device-timeout=5s або переключіть на automount; якщо воно критичне, виправте UUID і перевірте весь ланцюжок пристроїв.
Завдання 7 — Тестуйте монти без перезавантаження (ловіть помилки безпечно)
cr0x@server:~$ mount -a
mount: /mnt/data: can't find UUID=2f2c3a5b-8d5e-4e1b-b4d2-2e1b1f4d2f20.
Що це означає: Проблема відтворюється поза завантаженням. Добре — налагодження під час завантаження нестерпне.
Рішення: виправте запис у fstab; повторюйте mount -a, поки вивід не стане чистим.
Завдання 8 — Для затримок network-online: подивіться, хто потребує цього
cr0x@server:~$ systemctl list-dependencies --reverse network-online.target
network-online.target
● ├─mnt-nfs.mount
● ├─remote-fs.target
● └─docker.service
Що це означає: Ваш NFS-монтування і Docker примушують «online». Це може бути непотрібним, якщо вони можуть працювати з «network configured».
Рішення: відʼєднайте некритичні сервіси від network-online.target, або виправте реальну мережеву проблему, якщо воно дійсно має бути «online».
Завдання 9 — Перевірте конфігурацію wait-online (таймаути — це політика)
cr0x@server:~$ systemctl cat systemd-networkd-wait-online.service
# /lib/systemd/system/systemd-networkd-wait-online.service
[Unit]
Description=Wait for Network to be Configured
Documentation=man:systemd-networkd-wait-online.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
Before=network-online.target shutdown.target
[Service]
Type=oneshot
ExecStart=/lib/systemd/systemd-networkd-wait-online --timeout=120
RemainAfterExit=yes
[Install]
WantedBy=network-online.target
Що це означає: Стандартний таймаут може бути довгим. 120 секунд відчуваються як зависання під час інциденту.
Рішення: якщо у вашому середовищі переривчастий лінк, встановіть коротший таймаут або не вимагайте network-online від сервісів, які можуть повторити спробу пізніше.
Завдання 10 — Подивіться, чи у вас справді networkd як стек мережі
cr0x@server:~$ systemctl is-enabled systemd-networkd NetworkManager
enabled
disabled
Що це означає: Ви використовуєте networkd, тому wait-online релевантний. Якби був увімкнений NetworkManager, вам потрібен був би відповідний NM wait юніт.
Рішення: впевніться, що ви не маєте невідповідного «wait-online» для стеку мережі, яким користуєтеся. Невідповідності призводять до марних таймаутів.
Завдання 11 — Побудуйте граф залежностей для підозрілого юніта (точково)
cr0x@server:~$ systemctl list-dependencies --all mnt-data.mount
mnt-data.mount
● ├─system.slice
● ├─-.mount
● ├─dev-disk-by\x2duuid-2f2c3a5b\x2d8d5e\x2d4e1b\x2db4d2\x2d2e1b1f4d2f20.device
● └─local-fs-pre.target
Що це означає: Це монт прямо чекає на device-юніт, який не існує.
Рішення: знайдіть, чому device-юніт не створюється (відсутній диск, неправильний UUID, шифрування не відкрите, відсутній драйвер).
Завдання 12 — Перевірте виявлення пристроїв (udev і повідомлення ядра)
cr0x@server:~$ dmesg -T | tail -n 30
[Wed Mar 12 08:40:41 2025] sd 1:0:0:0: [sda] 1000215216 512-byte logical blocks: (512 GB/477 GiB)
[Wed Mar 12 08:40:41 2025] sd 2:0:0:0: [sdb] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
[Wed Mar 12 08:40:42 2025] EXT4-fs (sdb1): mounted filesystem 9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d ro with ordered data mode
[Wed Mar 12 08:40:42 2025] EXT4-fs (sdb1): re-mounted 9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d rw
Що це означає: Диск існує і UUID файлової системи видимий. Проблема в конфігурації, а не в детекції апаратури.
Рішення: оновіть посилання (UUID/LABEL) і розгляньте додавання гарантій (automount, nofail) для некритичних монтувань.
Завдання 13 — Тимчасово обійдіть неважливий провальний mount (повернути систему онлайн)
cr0x@server:~$ cp -a /etc/fstab /etc/fstab.bak
cr0x@server:~$ sed -i 's|^UUID=2f2c3a5b-8d5e-4e1b-b4d2-2e1b1f4d2f20|# UUID=2f2c3a5b-8d5e-4e1b-b4d2-2e1b1f4d2f20|' /etc/fstab
cr0x@server:~$ systemctl daemon-reload
Що це означає: Ви тимчасово вимкнули цей mount. Це прагматичний крок, а не моральна поразка.
Рішення: перезавантажтеся, щоб відновити базові сервіси; потім виправте mount правильно під контрольованим вікном.
Завдання 14 — Зробіть mount стійким, замість того щоб він блокував завантаження
cr0x@server:~$ grep -n '/mnt/data' /etc/fstab
12:UUID=9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d /mnt/data ext4 nofail,x-systemd.device-timeout=5s,x-systemd.automount 0 2
Що це означає: Цей mount не блокуватиме завантаження; він змонтується при зверненні, а якщо диск відсутній, не викине вас в emergency mode.
Рішення: застосовуйте це лише до монтувань, що не потрібні для роботи ОС. Бази даних і root-файлові системи не підходять для nofail.
Завдання 15 — Для emergency mode через fstab: перевірте погляд systemd на local-fs
cr0x@server:~$ systemctl status local-fs.target --no-pager
× local-fs.target - Local File Systems
Loaded: loaded (/lib/systemd/system/local-fs.target; static)
Active: failed (Result: dependency) since Wed 2025-03-12 08:41:02 UTC; 3min ago
Docs: man:systemd.special(7)
Mar 12 08:41:02 server systemd[1]: local-fs.target: Dependency failed for Local File Systems.
Що це означає: Таргет — жертва. Реальна помилка — це mount-юніт під ним.
Рішення: припиніть дивитися на local-fs.target; повертайтеся до провалених .mount юнітів і виправляйте їх.
Завдання 16 — Якщо журнал відсутній: перевірте persistent journald
cr0x@server:~$ ls -ld /var/log/journal
ls: cannot access '/var/log/journal': No such file or directory
Що це означає: Журнали можуть бути у памʼяті. Після перезавантаження докази зникнуть.
Рішення: увімкніть persistent journaling на серверах, де форензика при завантаженні важлива (більшість серверів). Інакше ви діагностуєте «за відчуттями».
Завдання 17 — Увімкнути persistent journal (щоб наступного разу було простіше)
cr0x@server:~$ sudo mkdir -p /var/log/journal
cr0x@server:~$ sudo systemd-tmpfiles --create --prefix /var/log/journal
cr0x@server:~$ sudo systemctl restart systemd-journald
Що це означає: Journald почне писати постійні журнали (за умовами конфігурації і вільного місця).
Рішення: перевірте політику використання диска; на невеликих root FS встановіть ліміти, щоб уникнути заповнення /.
Випадок №29: типовий ланцюжок зависання завантаження Debian 13
Давайте конкретизуємо, як виглядає «знайти один сервіс, що блокує старт» на практиці. Випадок №29 — це шаблон, який я часто бачу на Debian-хостах,
що «трохи від усього»: локальний диск даних, кілька віддалених монтувань і сервіс, який вимагає ідеальної мережі, перш ніж запуститися.
Набір симптомів
- На консолі: «A start job is running for /mnt/data» або «Dependency failed for Local File Systems.»
- Іноді система падає в emergency mode, іноді завантажується через ~2 хвилини.
- Після завантаження:
systemctl --failedпоказує один провалений mount і опціонально помилку wait-online.
Ланцюг кореневих причин (як це відбувається)
Хтось підмінив диск, відновив з бекапу або перезбудував файлову систему. UUID змінився. Стара запис у /etc/fstab лишилась.
systemd згенерував mount-юніт для цього запису і спробував виконати його під час завантаження. Він не знайшов пристрій; mount провалився.
Оскільки mount вважався обовʼязковим (за замовчуванням), local-fs.target провалився і завантаження драматично перейшло в emergency mode.
Окремо було NFS-монтування, що використовувало _netdev, і systemd переклав це в потребу мережі. Один чи два юніти підхопили
network-online.target, що підключило systemd-networkd-wait-online.service. На хості без кабелю (або з неправильною VLAN)
wait-online таймаутиться на 120 секунд. Це не «помилка» в людському сенсі; це політика, яку ви забули.
Отже, який «один сервіс» блокує старт?
У цьому випадку це mnt-data.mount, коли ви потрапляєте в emergency mode. Рядок «Dependency failed» згадує local-fs.target,
але блокатор — це mount-юніт, згенерований з /etc/fstab.
Якщо ви не падаєте в emergency mode, але завантаження повільне, «один сервіс» часто є systemd-networkd-wait-online.service або віддалений mount,
що чекає за ним.
Ваша діагностика повинна відповідати операційному впливу:
жорстка зупинка при завантаженні → виправте жорстку залежність (зазвичай локальні mount-и);
повільне завантаження → приберіть непотрібні online-залежності, скоротіть таймаути або зробіть монти automount/nofail.
Жарт №2: нічого так не говорить «висока доступність», як сервер, що відмовляється завантажуватися, доки недоступна віддалена шара, якою ніхто ніколи не користувався.
Три корпоративні міні-історії (що насправді відбувається в компаніях)
1) Інцидент через хибне припущення: «UUIDи — назавжди»
Середня SaaS-компанія працювала на Debian на невеликому парку stateful worker-ів. Вони мали диск даних, змонтований у /srv/data, який згадувався по UUID у /etc/fstab.
Операційна команда любила UUID, бо імена пристроїв на кшталт /dev/sdb1 ненадійні — порядок підключення змінюється, контролери перекомпонують, хаос.
Під час оновлення апаратури технік клонував диски і «почистив» розділи. Файлова система була відтворена, а не клонована біт-в-біт.
Ніхто не помітив, бо точка монтовання існувала і директорія виглядала нормально на стенді. UUID змінився.
Перший продакшен-перезавантаження після оновлення ядра було жахливим. Кілька worker-ів опинилися в emergency mode з «Dependency failed for Local File Systems.»
Інженер на виклику спочатку гнався за неправильною річчю: бачив local-fs.target і думав, що systemd «зламався».
Вони намагалися перезапустити таргети, ніби то сервіси. Це як перезавантажити електронну таблицю, щоб виправити помилку в клітинці B7.
Виправлення було простим: оновити UUID у /etc/fstab. Урок не в тому, щоб відмовитися від UUID. Урок у тому, що ідентифікація сховища — це конфігурація,
яку треба перевірити після обслуговування. Вони додали перевірку перед перезавантаженням, яка порівнювала записи fstab з виводом lsblk -f і відмовляла у продовженні,
якщо згаданий UUID відсутній.
Ніхто не був звільнений. Але всі перестали казати «це просто перезавантаження».
2) Оптимізація, що відкотилася: «Запускай сервіси якнайшвидше»
Інша організація — корпоративна, з великими вимогами відповідності — хотіла швидше завантаження для Debian-аплаєнсу.
Хтось подивився на граф завантаження і вирішив, що wait-online — це «марно витрачений час». Вони вимкнули wait-online і прибрали залежності від network-online.target.
Завантаження стало швидшим. Бенчмарки були чудові. Слайд у презентації пройшов.
Потім реальність нагрянула. Аплаєнс запускав сервіс, який потребував стабільної IP і DNS перед реєстрацією в центральному контролері.
Без очікування мережі сервіс стартував одразу, спробував резолвити імʼя, провалився і завершився. systemd сумлінно перезапускав його.
Коробка не була „померла“, але вона опинилася в циклі перезапусків кілька хвилин — іноді довше у завантаженій мережі.
Найгірше: це було нестабільно. Якщо DHCP був швидким — все добре. Якщо ні — ні. Команда насолоджувалася класичним корпоративним досвідом:
проблема, яка зʼявляється після того, як ви оголосили перемогу.
Вони відкотили зміни, але не просто увімкнули 120-секундне чекання. Вони зробили залежність точнішою:
сервіси, які справді потребують онлайн, використовували підлаштований wait із коротшим таймаутом і кращим вибором інтерфейсу;
сервіси, які могли повторити спробу пізніше, перестали тягнути за собою network-online.
Оптимізація — це податок. Якщо не платити його на етапі проєктування, доведеться платити в інцидентах.
3) Нудна, але правильна практика, що врятувала день: постійні логи + нотатки змін
Команда фінансових сервісів працювала на bare metal з зашифрованим root і кількома допоміжними монтами. У них була стара вимога:
persistent journaling увімкнено скрізь, і кожна зміна, повʼязана зі сховищем, вимагала однорядкової нотатки в внутрішньому логу змін: «що змінили, як відкотити».
Нудно. Трохи дратує. Ідеально.
Одного понеділка хост завантажився в emergency mode після обслуговування у вихідні. На консолі було «Dependency failed», але інженеру не довелося гадати.
Попередні журнали були на місці. Журнал вказував на один провалений mount-юніт, і рядок помилки містив точний шлях до пристрою, якого не знайдено.
У журналі змін було написано, що додано новий iSCSI LUN і створено запис у fstab. Особа, яка це зробила, також написала відкат: «закоментувати рядок у fstab і перезавантажити».
За кілька хвилин хост знову працював, а команда розбиралася з проблемою відкриття iSCSI вдень.
Практика не була гламурною. Вона не «масштабувала AI-операції». Вона робила простіше наступне відновлення.
Типові помилки: симптом → корінь проблеми → виправлення
1) Симптом: «Dependency failed for Local File Systems» і emergency mode
Корінь: Обовʼязковий mount з /etc/fstab провалився (неправильний UUID/LABEL, відсутній диск, збій fsck, відсутнє розшифрування).
Виправлення: Ідентифікуйте провалений .mount у systemctl --failed. Виправте fstab. Якщо некритично — додайте nofail і короткий таймаут пристрою.
2) Симптом: 90–120 секунд затримки завантаження, потім система піднімається
Корінь: *-wait-online.service таймаутиться — зазвичай через відсутність носія, неправильну VLAN або очікування інтерфейсу, який не має рахуватися.
Виправлення: Перевірте, який wait-online юніт активний (networkd vs NetworkManager). Скоротіть таймаут, налаштуйте потрібні інтерфейси або приберіть непотрібну залежність від network-online.target.
3) Симптом: «Dependency failed for Remote File Systems»
Корінь: Один віддалений mount (NFS/SMB/iSCSI) провалився. Можливі причини: DNS, мережа, креденшіали або сервер недоступний.
Виправлення: Робіть віддалені монти з nofail + x-systemd.automount, де це доречно; використовуйте _netdev; перевіряйте резолюцію імен під час раннього завантаження.
4) Симптом: «A start job is running for dev-disk-by…» потім таймаут
Корінь: systemd чекає device-юніт, який не зʼявляється. Часто застарілий UUID, відсутній multipath mapping або драйвер, який не входить в initramfs.
Виправлення: Підтвердіть за допомогою lsblk -f та dmesg. Оновіть ідентифікатори. Для раннього-boot сховища переконайтеся, що initramfs містить потрібні модулі та конфігурації.
5) Симптом: Завантаження падає після додавання нового запису файлової системи; ручний mount працює пізніше
Корінь: Питання порядку: пристрій стає доступним після того, як mount було спробовано (наприклад, iSCSI або відкладена udev). Або вам потрібен x-systemd.requires= на конкретному сервісі.
Виправлення: Використайте x-systemd.automount або додайте правильні залежності; уникайте хаків на зразок «sleep 10» в юнітах.
6) Симптом: Ви «виправили», але після наступного перезавантаження проблема зʼявляється знову
Корінь: Ви редагували runtime-стан або згенерований юніт, а не джерело (наприклад, редагували в /run), або забули daemon-reload, або initramfs все ще містить стару конфігурацію.
Виправлення: Редагуйте /etc/fstab та drop-in під /etc/systemd/system. Запустіть systemctl daemon-reload. Якщо є шифрування/initramfs — перебудуйте initramfs.
7) Симптом: Повідомлення «Dependency failed», але все здається в порядку
Корінь: Провалюються опціональні юніти (наприклад, mount, що за замовчуванням вважається обовʼязковим), або one-shot сервіс неправильно налаштований, але не критичний.
Виправлення: Прийміть рішення, чи має юніт бути обовʼязковим. Замініть Requires= на Wants=, де безпечно. Додайте nofail до опціональних монтувань. Приберіть провалені юніти, щоб зменшити шум.
Контрольні списки / покроковий план
Контрольний список A — Відновити систему зараз (хвилини важливі)
- Отримайте шел (emergency mode, recovery mode або консольний TTY).
- Виконайте
systemctl --failedі зафіксуйте провалені.mount/.service. - Виконайте
journalctl -b -p err --no-pagerі знайдіть найранішу релевантну помилку. - Якщо монтування провалюється і не критичне: закоментуйте його в
/etc/fstab, виконайтеsystemctl daemon-reload, перезавантажтеся. - Якщо монтування критичне: підтвердіть наявність пристрою за допомогою
lsblk -f, виправте UUID/LABEL, виконайтеmount -a, потім продовжуйте завантаження.
Контрольний список B — Ідентифікувати «один юніт», що блокує завантаження (точно)
- Запустіть
systemd-analyze critical-chainі відзначте юніт із найбільшим часом. - Підтвердіть, що він реально блокує: перевірте, чи він на шляху до
multi-user.targetабо вашого дефолтного таргету. - Інспектуйте його:
systemctl status UNIT. - Подивіться журнал:
journalctl -u UNIT -b --no-pager. - Побудуйте прямі залежності:
systemctl list-dependencies --all UNITі--reverseдля таргету, який він уповільнює. - Зупиніться, коли знайдете відсутній ресурс (пристрій, мережа, креденшіали, конфігурація). Це істинна коренева причина.
Контрольний список C — Виправити правильно (щоб наступне перезавантаження не повторилось)
- Для монтувань: використовуйте стабільні ідентифікатори (UUID/LABEL) і підтвердіть через
lsblk -f. - Для віддалених монтувань: віддавайте перевагу
x-systemd.automountіnofail, якщо машина може працювати без них. - Для network-online: вимагайте його тільки тоді, коли сервіс дійсно потребує робочих маршрутів/DNS на старті.
- Встановіть розумні таймаути: короткі для опціональних залежностей, довші лише там, де це виправдано.
- Увімкніть persistent journaling на серверах; зберігайте докази завантаження.
- Тестуйте з
systemd-analyze blameі контрольованим перезавантаженням.
Контрольний список D — Запобігти повторенню (SRE-податок, який варто платити)
- Додайте pre-reboot валідаційний скрипт: підтвердьте, що всі UUID у
/etc/fstabіснують. - Стандартизувати опції монтування для опціональних дисків (automount + короткий таймаут).
- Використовуйте drop-in override файли замість редагування файлів постачальника.
- Документуйте кроки відкату для змін у сховищі та мережі.
- Після будь-якої міграції сховища проведіть репетицію перезавантаження у вікні обслуговування.
Поширені питання
1) Чи є «Dependency failed» проблемою ядра?
Зазвичай ні. Це повідомлення systemd про те, що юніт не зміг запуститися через провал того, від чого він залежить. Проблеми ядра зазвичай проявляються як паніки, помилки драйверів або відсутній root-пристрій.
2) Чому згадується local-fs.target, а не реальна помилка?
Таргети агрегують інші юніти. Коли один обовʼязковий юніт провалюється, таргет повідомляє про dependency failure. Реальна помилка зазвичай — конкретний .mount або .service.
3) Який найшвидший спосіб знайти блокатор?
Комбінуйте systemctl --failed з systemd-analyze critical-chain, потім читайте журнал для головного підозрюваного. Не починайте з редагування випадкових файлів юнітів.
4) Чому система чекає 120 секунд на мережу?
Це стандартний таймаут у багатьох wait-online юнітах. Це політичний вибір, а не фізичний закон. Якщо вам не потрібне «online», не залежіть від нього; якщо потрібне — налаштуйте таймаут.
5) Чи варто використовувати nofail у /etc/fstab?
Для опціональних монтувань — так, особливо для змінних, віддалених або «приємних мати» томів. Для критичних монтувань (root, важливі дані додатків) — ні. Краще виправити залежність.
6) Що дає x-systemd.automount?
Воно відсуває монтування до першого звернення. Завантаження не блокується. Якщо ресурс тимчасово відсутній, система все одно підніметься, і ви зможете усунути проблему віддалено.
7) Мій mount працює після завантаження, але під час завантаження — ні. Чому?
Це порядок. Пристрій або мережевий шлях ще не готові, коли виконується спроба монтування. Automount часто є найчистішим виправленням. Інакше додайте правильні залежності — уникайте «sleep 10» у юнітах.
8) Як зрозуміти, чи я використовую NetworkManager чи networkd?
Перевірте, який сервіс увімкнений і активний. Якщо інтерфейси керуються NetworkManager, то wait-online від networkd може бути неактуальним і марно таймаутитися.
9) Я виправив /etc/fstab, але systemd все одно падає так само. Що я пропустив?
Виконайте systemctl daemon-reload і повторіть тест з mount -a. Якщо провадження стосується initramfs (шифрування або ранні пристрої) — перебудуйте initramfs також.
10) Чи можна просто замаскувати провальний юніт?
Можна, і іноді варто — тимчасово. Маскування — це обхід, а не лікування. Це прийнятно для неважливих юнітів, поки ви відновлюєте доступність і плануєте правильне виправлення.
Наступні кроки (що робити після відновлення завантаження)
Коли система запрацювала, не зупиняйтеся на «тепер воно завантажується». Задокументуйте корінь проблеми, поки все ще свіжо:
ідентифікуйте один юніт, що блокував завантаження, зафіксуйте, чому він блокував, і вирішіть, чи має він коли-небудь знову мати право блокувати.
- Запишіть винуватий юніт і провалену залежність (UUID, інтерфейс, віддалена кінцева точка).
- Зробіть опціональні залежності опціональними:
nofail, automount, короткі таймаути для пристроїв. - Зробіть обовʼязкові залежності надійними: правильні ідентифікатори, правильний порядок, правильний вміст initramfs.
- Увімкніть persistent journaling, якщо ще не зробили; наступний інцидент буде дешевшим у діагностиці.
- Перезавантажтеся раз в контрольованому вікні, щоб підтвердити виправлення. Довіра заробляється, а не передбачається.
Debian завантажується чудово. Ваша конфігурація робить із цього судовий процес. systemd лише службовець, що зачитує наслідки.