Ubuntu 24.04: «Failed to get D-Bus connection» — виправте зламані сесії й служби (випадок №48)

Було корисно?

Ви запускаєте systemctl, і воно викидає: «Failed to get D-Bus connection». Раптом ваше «просте перезапускання» перетворюється на місце події: служби не спілкуються, входи виглядають привидами, і будь-яка автоматизація, що очікує чистої сесії, починає падати.

Ця помилка рідко означає «просто D-Bus». Зазвичай це зламаний контракт між systemd, вашою сесією/логіном та сокетами шини під /run. Рішення банальне — але тільки коли ви припините гадати й почнете доводити.

Що насправді означає ця помилка (і чого вона не означає)

Коли інструмент каже «Failed to get D-Bus connection», він скаржиться, що не може дістатися до сокета шини повідомлень, який очікує знайти. На Ubuntu 24.04 типовими ініціаторами є systemctl, loginctl, компоненти GNOME, підказки policykit, помічники snapd або будь-який процес, що очікує одне з наступного:

  • Системна шина за адресою /run/dbus/system_bus_socket (використовується для системних служб), або
  • Сесійна шина користувача (на користувача) зазвичай у /run/user/UID/bus, якою керує systemd --user та dbus-daemon або dbus-broker залежно від конфігурації.

Фраза вводить в оману, бо корінь проблеми часто не в тому, що «D-Bus впав». Шина може бути в порядку; неправильно налаштоване середовище, відсутня runtime-папка, ви можете бути в контейнері/просторі імен або використовувати sudo так, що змінні шини відрізані.

Дві правила, які тримають вас у розумі:

  1. Визначте, чи потрібна вам системна шина чи шина користувача. Якщо ви керуєте службами через systemctl (системна область), вам важливі PID 1, dbus і системний сокет. Якщо ви виконуєте дії робочого столу/сесії, важливі systemd --user, XDG_RUNTIME_DIR і перукористувацький сокет.
  2. Завжди перевіряйте сокет, а не свої відчуття. Більшість відмов підписки «D-Bus connection» фактично викликані відсутніми шляхами в /run, померлими сесіями користувача або зламаним диспетчером вхідних сесій.

Одна перефразована ідея від Gene Kim (автор з DevOps/надійності): Покращення приходить від зменшення роботи в процесі і роблення проблем видимими якомога раніше. Це працює й тут: зробіть відмову видимою, перевіривши шляхи шини та стан сесії перш ніж перезапускати випадкові демони.

Швидка діагностика — покроковий план

Коли це трапляється в продакшені о 02:00, вам не потрібна теорія. Потрібен цикл тріажу, який сходиться.

Крок 1: Визначте, яка шина відмовляє

  • Якщо помилка з’являється під час виконання systemctl status foo від root — ймовірно це системна шина або зв’язок із PID 1.
  • Якщо помилка з’являється в десктопному додатку, налаштуваннях GNOME або systemctl --user — це шина сесії користувача (/run/user/UID/bus).
  • Якщо це трапляється лише через SSH або автоматизацію — підозрюйте змінні середовища і non-login shell-си.

Крок 2: Перевірте сокети і runtime-папки (найшвидший сигнал)

  • Чи існує і є сокетом /run/dbus/system_bus_socket?
  • Чи існує /run/user/UID і чи належить вона користувачу?
  • Чи існує і є сокетом /run/user/UID/bus?

Крок 3: Перевірте менеджер сесій і стан systemd

  • systemctl is-system-running покаже, чи PID 1 здоровий.
  • systemctl status dbus покаже, чи сервіс системної шини існує/запущений.
  • loginctl list-sessions покаже, чи бачить logind вашу сесію (критично для створення /run/user/UID).

Крок 4: Виправляйте правильний шар, а не найголосніший

  • Відсутня /run/user/UID? Виправляйте життєвий цикл logind/сесій.
  • Сокет існує, але доступ заборонено? Виправте права, політики SELinux/AppArmor або контекст користувача.
  • Працює локально, але не зі sudo? Налагодьте збереження оточення; не «перезапускайте dbus» із зла.

Цікавинки та контекст (допоможуть швидше дебажити)

  • D-Bus був створений на початку 2000-х, щоб замінити ad-hoc IPC механізми в Linux-десктопах; згодом він став стандартом і для системних служб.
  • systemd не створив D-Bus, але systemd зробив залежності D-Bus явнішими через порядок запуску юнітів, socket activation і користувацькі сервіси.
  • Runtime-папки користувачів у /run/user/UID зазвичай створює systemd-logind при старті сесії — і видаляє, коли остання сесія завершується.
  • Ubuntu постачав як dbus-daemon, так і альтернативи (наприклад dbus-broker); важливий контракт сокета, а не бренд реалізації.
  • XDG_RUNTIME_DIR — частина специфікації XDG; має бути персональною для користувача, безпечною та тимчасовою — не випадковою папкою в /tmp.
  • systemctl спілкується з systemd через D-Bus; якщо systemctl не дістається шини, воно не може нічого запитати в systemd навіть якщо systemd технічно живий.
  • SSH-сесії не завжди є «сесіями logind» залежно від PAM-конфігурації; якщо ні, ви можете втратити автоматичне створення runtime-папки і доступність шини користувача.
  • У контейнерах часто немає повної системної шини, бо PID 1 не systemd або /run ізольовано. Ця помилка там нормальна, якщо ви не підключили її навмисно.
  • PolicyKit (polkit) залежить від D-Bus для запитів авторизації; зламаний доступ до шини може виглядати як «вікна авторизації не з’являються» або «доступ заборонено» без UI.

Жарт №1: D-Bus як офісна пошта — коли вона паде, всі раптом дізнаються, скільки речей вони ніколи не розуміли, що на неї покладались.

Польовий посібник: ізолюйте, до якої «шини» неможливо підключитися

Існує кілька типових форм відмов:

  • Root на сервері: systemctl не працює. Зазвичай відсутній системний сокет, юніт dbus впав, або PID 1 у деградованому/напівмертвому стані.
  • Сесія десктопного користувача: не працюють налаштування GNOME, ламається gsettings, systemctl --user відмовляє. Зазвичай XDG_RUNTIME_DIR не встановлено, /run/user/UID відсутня, або systemd --user не працює.
  • Автоматизація через sudo: працює як ваш користувач, не працює як root, або навпаки. Зазвичай змінні середовища і контекст сесії неправильні.
  • Всередині контейнерів/CI: systemctl і busctl відмовляють за дизайном, бо немає systemd PID 1 або системної шини.

Ключове: шина — це Unix-сокетний файл. Якщо сокета немає, не допоможе “більше ретраїв”. Якщо він є, але ваш процес не може до нього дістатися — це права, простори імен або проблеми ідентичності. Якщо він є і доступний, але відповіді відсутні — це вже проблема демона.

Практичні завдання: команди, очікуваний вивід і рішення

Це ті завдання, які я реально виконую. Кожне включає, що означає вивід і яке рішення приймати далі. Виконуйте їх по порядку, поки режим відмови не стане очевидним. Ви не збираєте логи заради забави; ви звужуєте простір пошуку.

Task 1: Confirm the exact failing command and context

cr0x@server:~$ whoami
cr0x
cr0x@server:~$ systemctl status ssh
Failed to get D-Bus connection: No such file or directory

Значення: Клієнт не може дістатися свого сокета шини. «No such file or directory» натякає на відсутній шлях сокета, а не на проблему з правами.

Рішення: Визначте, чи це відмова системної шини (root/система) або шини користувача (користувацька область). Далі: перевірте, чи ви root і який саме systemctl запущено.

Task 2: Check whether PID 1 is systemd (containers and chroots)

cr0x@server:~$ ps -p 1 -o pid,comm,args
  PID COMMAND         COMMAND
    1 systemd         /sbin/init

Значення: PID 1 — systemd; systemctl має працювати, якщо шлях системної шини присутній.

Рішення: Якщо PID 1 не systemd (поширено в контейнерах), «вирішення» — уникати systemctl або запустити нормальний init. Якщо systemd — продовжуйте діагностику.

Task 3: Verify the system bus socket exists

cr0x@server:~$ ls -l /run/dbus/system_bus_socket
srwxrwxrwx 1 root root 0 Dec 30 10:12 /run/dbus/system_bus_socket

Значення: Файл сокета системної шини існує і є сокетом (позначка s на початку прав). Світовий запис тут нормальний для кінцевої точки сокета; доступ все одно контролюється політикою D-Bus.

Рішення: Якщо відсутній: зосередьтеся на сервісі dbus та ранніх етапах завантаження. Якщо присутній: перевірте, чи dbus відповідає.

Task 4: Check dbus service health (system bus)

cr0x@server:~$ systemctl status dbus --no-pager
● dbus.service - D-Bus System Message Bus
     Loaded: loaded (/usr/lib/systemd/system/dbus.service; static)
     Active: active (running) since Mon 2025-12-30 10:12:01 UTC; 2min ago
TriggeredBy: ● dbus.socket
       Docs: man:dbus-daemon(1)
   Main PID: 842 (dbus-daemon)
      Tasks: 1 (limit: 18939)
     Memory: 3.8M
        CPU: 52ms

Значення: Системна шина запущена; проблема може бути у здатності systemctl підключитися до systemd (не в dbus), або у просторі імен/правах.

Рішення: Якщо dbus неактивний/упав — перезапустіть його й читайте логи. Якщо активний — перевірте сам systemd і приватний сокет systemd.

Task 5: Confirm systemd is responsive

cr0x@server:~$ systemctl is-system-running
running

Значення: PID 1 звітує про нормальний стан. Якщо ви все ще бачите «Failed to get D-Bus connection», можливо ви запускаєте systemctl в середовищі, яке не бачить /run або не має правильного mount namespace.

Рішення: Якщо вивід degraded або maintenance, йдіть у journal за системними помилками. Якщо running, але клієнти падають — підозрюйте namespace, chroot або файлові проблеми під /run.

Task 6: Inspect /run mount and free space (yes, really)

cr0x@server:~$ findmnt /run
TARGET SOURCE FSTYPE OPTIONS
/run   tmpfs  tmpfs  rw,nosuid,nodev,relatime,size=394680k,mode=755,inode64
cr0x@server:~$ df -h /run
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           386M  2.1M  384M   1% /run

Значення: /run — tmpfs; має бути записуваною і мати простір/іноди. Якщо /run доступна лише для читання або заповнена — сокети не створяться і ви отримаєте помилки про відсутню шину.

Рішення: Якщо повна/ro: виправте це першочергово (часто через процес, що витрачає простір або неправильне розмірення tmpfs). Якщо в порядку — переходьте до перевірки сесій користувача, якщо помилка в області користувача.

Task 7: Determine if you’re dealing with the user bus

cr0x@server:~$ echo "$XDG_RUNTIME_DIR"
/run/user/1000
cr0x@server:~$ echo "$DBUS_SESSION_BUS_ADDRESS"
unix:path=/run/user/1000/bus

Значення: Змінні середовища вказують на перукористувацьку шину. Якщо одна з них пуста, ваша сесія неповна (поширено при sudo, cron або зламаному PAM).

Рішення: Якщо не встановлені: потрібно встановити правильний контекст сесії або явне налаштування користувацької шини (краще перше). Якщо встановлено: перевірте наявність сокета.

Task 8: Validate the user bus socket exists and has sane ownership

cr0x@server:~$ id -u
1000
cr0x@server:~$ ls -ld /run/user/1000
drwx------ 12 cr0x cr0x 320 Dec 30 10:12 /run/user/1000
cr0x@server:~$ ls -l /run/user/1000/bus
srw-rw-rw- 1 cr0x cr0x 0 Dec 30 10:12 /run/user/1000/bus

Значення: Runtime-папка існує, приватна (0700), і сокет шини існує. Добре. Якщо /run/user/1000 відсутня — сесія не була належним чином зареєстрована в logind.

Рішення: Якщо відсутня: переходьте до loginctl і налагодження PAM/logind. Якщо присутня, але з неправильним власником: виправте права і розберіться, чому вони зсунулися (часто через скрипт, що запускався від root).

Task 9: Prove the user systemd instance is alive

cr0x@server:~$ systemctl --user status --no-pager
● cr0x@server
    State: running
    Units: 221 loaded (incl. snap units)
     Jobs: 0 queued
   Failed: 0 units
    Since: Mon 2025-12-30 10:12:05 UTC; 2min ago
  

Значення: Ваш користувацький менеджер працює і доступний. Якщо ви отримуєте «Failed to connect to bus», контекст шини або середовище користувача зламані.

Рішення: Якщо це відмовляє, але сокет існує — можливо ваше середовище вводить в оману (неправильний XDG_RUNTIME_DIR) або ви в іншому просторі імен (поширено при sudo і деяких інструментах віддаленого доступу).

Task 10: Use loginctl to verify logind sees your session

cr0x@server:~$ loginctl list-sessions
SESSION  UID USER SEAT  TTY
     21 1000 cr0x seat0 tty2

1 sessions listed.
cr0x@server:~$ loginctl show-user cr0x -p RuntimePath -p State -p Linger
RuntimePath=/run/user/1000
State=active
Linger=no

Значення: logind має активну сесію для користувача і знає, де runtime-шлях. Якщо сесій немає, runtime-папка може не створюватися.

Рішення: Якщо сесія відсутня через SSH: перевірте PAM-конфігурацію і чи використовує ваш шлях входу systemd/logind. Якщо потрібні фонові сервіси користувача — розгляньте lingering (обережно).

Task 11: Diagnose “sudo broke my bus” (classic)

cr0x@server:~$ sudo -i
root@server:~# echo "$DBUS_SESSION_BUS_ADDRESS"

root@server:~# systemctl --user status
Failed to connect to bus: No medium found

Значення: У shell-а root немає контексту користувацької шини; systemctl --user під root — не ваша користувацька сесія. Ця помилка очікувана.

Рішення: Не «виправляйте» це експортом випадкових змінних у root. Використовуйте systemctl (системна область) як root, а systemctl --user як користувач у сесії. Якщо потрібно керувати юнітом користувача з root, використовуйте machinectl shell або runuser з правильними змінними середовища, або включіть lingering через loginctl enable-linger і керуйте systemctl --user під тим користувачем.

Task 12: Check journal for the first failure, not the last complaint

cr0x@server:~$ journalctl -b -u systemd-logind --no-pager | tail -n 20
Dec 30 10:11:58 server systemd-logind[701]: New session 21 of user cr0x.
Dec 30 10:11:58 server systemd-logind[701]: Watching system buttons on /dev/input/event3 (Power Button)
Dec 30 10:12:01 server systemd-logind[701]: Removed session 19.

Значення: logind створює сесії. Якщо ви бачите повторювані помилки про створення runtime-папок — це ваша головна підказка.

Рішення: Якщо logind показує помилки про runtime-папки або cgroups — виправляйте ці шари. Перезапуск dbus не виправить «не можу створити /run/user/UID».

Task 13: Confirm dbus packages and user-session support are installed

cr0x@server:~$ dpkg -l | egrep 'dbus|dbus-user-session|libpam-systemd' | awk '{print $1,$2,$3}'
ii dbus 1.14.10-4ubuntu4.1
ii dbus-user-session 1.14.10-4ubuntu4.1
ii libpam-systemd 255.4-1ubuntu8

Значення: Необхідні компоненти присутні. Відсутність dbus-user-session може призвести до відсутності поведінки сесійної шини в деяких конфігураціях (особливо мінімальні інсталяції).

Рішення: Якщо відсутні пакети — встановіть і повторно увійдіть. Якщо присутні — переходьте до PAM/logind і проблем зі середовищем.

Task 14: Check PAM session hooks for systemd/logind (SSH-focused)

cr0x@server:~$ grep -R "pam_systemd.so" -n /etc/pam.d/sshd /etc/pam.d/login
/etc/pam.d/sshd:15:session    required     pam_systemd.so
/etc/pam.d/login:14:session    required     pam_systemd.so

Значення: PAM налаштовано на реєстрацію сесій в systemd/logind для SSH і консолі. Якщо відсутнє — ви можете залишитися без runtime-папки і без шини користувача.

Рішення: Якщо відсутнє для шляху входу, яким ви користуєтесь — додайте його (обережно, під контролем змін) і протестуйте нову сесію. Якщо присутнє — зосередьтеся, чому logind досі не створює runtime-папки (часто пов’язано з lingering, проблемами cgroup або зламаним state systemd).

Task 15: Check if the user runtime dir is being removed unexpectedly

cr0x@server:~$ sudo ls -l /run/user
total 0
drwx------ 12 cr0x cr0x 320 Dec 30 10:12 1000
drwx------ 10 gdm  gdm  280 Dec 30 10:11 120

Значення: Runtime-папки існують для активних користувачів. Якщо ваша зникає при відключенні SSH — ймовірно у вас немає lingering і немає активної сесії.

Рішення: Для фонового запуску сервісів користувача — розгляньте loginctl enable-linger username. Для інтерактивної роботи — забезпечте реальну сесію і уникайте запуску сесійозалежних команд з не-сесійного контексту.

Task 16: Enable lingering (only if you truly need user services without a login)

cr0x@server:~$ sudo loginctl enable-linger cr0x
cr0x@server:~$ loginctl show-user cr0x -p Linger
Linger=yes

Значення: Користувацький менеджер може переживати вихід користувача, зберігаючи сервіси користувача й runtime-папку доступною.

Рішення: Використовуйте це для безголових сервісів у користувацькій області (іноді CI-агенти, per-user podman тощо). Не вмикайте це скрізь «про всяк випадок». Інакше ви отримаєте зомбі-менеджери користувачів, що з’їдають пам’ять на спільних хостах.

Task 17: If systemctl fails as root, test D-Bus directly

cr0x@server:~$ busctl --system list | head
NAME                      PID PROCESS         USER CONNECTION UNIT SESSION DESCRIPTION
:1.0                      842 dbus-daemon     root :1.0       -    -       -
org.freedesktop.DBus      842 dbus-daemon     root :1.0       -    -       -
org.freedesktop.login1    701 systemd-logind  root :1.2       -    -       -

Значення: Системна шина відповідає. Якщо systemctl все ще дає помилку, можливо є зламаний endpoint systemd D-Bus або невідповідність у середовищі/просторі імен.

Рішення: Якщо busctl теж відмовляє — системна шина дійсно зламана. Якщо busctl працює — зосередьтесь на зв’язку systemd і клієнтському середовищі.

Task 18: Check the systemd private socket (systemd’s IPC endpoint)

cr0x@server:~$ ls -l /run/systemd/private
srw------- 1 root root 0 Dec 30 10:11 /run/systemd/private

Значення: Приватний сокет systemd існує; systemctl використовує його в деяких шляхах коду. Якщо відсутній — щось глибоко неправильно з PID 1 або /run.

Рішення: Якщо відсутній: розглядайте це як проблему systemd/файлової системи runtime; подумайте про контрольований перезавантаження після вилучення логів. Якщо присутній — повертайтеся до області (system vs user) і проблем з просторами імен.

Task 19: Spot chroot/namespace issues (common in recovery shells)

cr0x@server:~$ readlink /proc/$$/ns/mnt
mnt:[4026532585]
cr0x@server:~$ sudo readlink /proc/1/ns/mnt
mnt:[4026531840]

Значення: Ваш shell у іншому mount namespace, ніж PID 1. Ви можете не бачити справжній /run, де живуть сокети.

Рішення: Якщо простори імен різні, проводьте діагностику з namespace хоста (або увійдіть у нього), замість того щоб «виправляти» фантомні шляхи у вашому ізольованому вигляді.

Task 20: Last resort, controlled restarts (in the right order)

cr0x@server:~$ sudo systemctl restart systemd-logind
cr0x@server:~$ sudo systemctl restart dbus
cr0x@server:~$ sudo systemctl daemon-reexec

Значення: Ці перезапуски можуть відновити завислий logind/dbus/systemd. daemon-reexec важка операція; вона переекзекує PID 1 без перезавантаження.

Рішення: Робіть це лише після того, як переконалися, що ви не в контейнері, і зібрали достатньо логів, щоб пояснити інцидент. Якщо сесії користувачів зламані через logind, перезапуск logind може обірвати сесії; плануйте його відповідально.

Поширені помилки: симптом → причина → виправлення

1) «systemctl працює локально як root, але падає по SSH»

Симптом: Через SSH systemctl повертає «Failed to get D-Bus connection», але на консолі працює.

Причина: Ви в обмеженому середовищі (forced command, chroot, toolbox), або ваша SSH-сесія не бачить /run хоста (різниця в mount namespace).

Виправлення: Підтвердіть PID 1 і mount namespace; переконайтеся, що ваш SSH-путь не chroot-ований і має доступ до /run. Використайте Task 2 і Task 19.

2) «systemctl –user падає після sudo -i»

Симптом: Ви стаєте root і намагаєтесь керувати юнітами користувача; воно падає з помилками шини.

Причина: Root не має контексту вашої користувацької шини. Крім того, у root-у свій користувацький менеджер, не ваш.

Виправлення: Запускайте systemctl --user як користувач у сесії. Якщо потрібно з root, використовуйте runuser -l username -c 'systemctl --user …' і переконайтесь, що сесія існує (або ввімкніть lingering).

3) «GNOME Settings не відкриваються; підказки polkit не з’являються»

Симптом: GUI-дії безшумно відмовляють або скаржаться на D-Bus.

Причина: Сесійна шина користувача зламана: відсутній XDG_RUNTIME_DIR, застаріла DBUS_SESSION_BUS_ADDRESS або відсутній /run/user/UID/bus.

Виправлення: Перевірте Task 7/8. Вийдіть і зайдіть знову, щоб відновити чисту сесію. Якщо проблема не зникає — перевірте logind і інтеграцію PAM.

4) «Cron job падає з помилками D-Bus»

Симптом: Скрипт, що використовує gsettings, notify-send або systemctl --user, падає в cron.

Причина: Cron працює без користувацької сесії і без XDG_RUNTIME_DIR.

Виправлення: Не запускайте десктопні/сесійні команди в cron, якщо не створили контекст сесії. Використовуйте системні сервіси або ввімкніть lingering і запускайте користувацький сервіс, що не залежить від GUI.

5) «/run/user/UID існує, але належить root»

Симптом: Папка існує, але права неправильні; помилки шини користувача слідують.

Причина: Хтось запускав очистку як root і створив папки неправильно, або скрипт невірно писав у /run/user.

Виправлення: Вийдіть користувачу (завершіть сесії), видаліть неправильну runtime-папку і дайте logind її відтворити. Якщо потрібно виправити на живому хості, коректно змініть власника і перезапустіть користувацький менеджер обережно.

6) «системний сокет відсутній після завантаження»

Симптом: /run/dbus/system_bus_socket відсутній; systemctl широко відмовляє.

Причина: dbus.socket або dbus.service не стартували, або /run змонтовано некоректно.

Виправлення: Перевірте mount /run (Task 6), потім systemctl status dbus dbus.socket і ранні логи завантаження.

7) «Працює на хості, але падає в контейнері»

Симптом: systemctl і busctl відмовляють у контейнері або CI runner-і.

Причина: Немає systemd PID 1, немає системної шини або /run ізольовано.

Виправлення: Не використовуйте systemctl у такому контейнері. Запускайте сервіс в foreground або створіть спеціальний контейнер із підтримкою systemd і потрібними привілеями/маунтами.

Три корпоративні міні-історії з практики

Міні-історія №1: Інцидент через хибне припущення

У середній компанії інженера викликали через «хост деплою не перезапускає служби». Він зайшов по SSH, виконав sudo systemctl restart app і отримав «Failed to get D-Bus connection». Припущення було негайним і впевненим: «dbus впав; перезапущу його».

Він перезапустив dbus, потім logind, потім зробив daemon-reexec. Хост стало важче доступним, кілька інтерактивних сесій відвалилися. Додаток усе ще не перезапускався. Інцидент розрісся.

Насправді проблема була прозаїчною: інженер був не на хості, а в chroot для обслуговування дисків. Це середовище мало інший mount namespace і інший /run. Звісно /run/dbus/system_bus_socket там не було; сокет жив у namespace хоста.

Коли він вийшов із chroot і виконав ту саму команду на справжньому хості, systemctl одразу запрацював. «Аварія D-Bus» виявилась маячнею через контекст. Виправлення — додати чіткий банер для rescue-середовищ і навчити команду запускати Task 2 і Task 19 перед втручанням у демони.

Міні-історія №2: Оптимізація, що зіграла проти

Ще одна команда хотіла пришвидшити час логіну і зменшити кількість фон-процесів на робочих станціях розробників. Хтось вирішив «спростити» образ, прибравши пакети, що здавалися «десктопним мотлохом».

Образ працював швидко. Протягом приблизно тижня. Потім почалися тікети: інтеграція IDE фейлила, запити пароля не з’являлись, перемикачі в налаштуваннях не діяли, а ще—сервіси користувача падали тільки після підключення через віддалений робочий стіл.

Вони видалили компоненти, що опосередковано гарантували стабільну користувацьку шину. Системна шина була, але інфраструктура на користувача була непослідовною залежно від способу входу. Деякі логіни створювали /run/user/UID правильно; інші — ні, бо PAM-hooks були неповними і пакети для сесій відсутні.

Оптимізація не «була неправильною», бо зекономила CPU. Вона була неправильною, бо прибрала каркас, що робить користувацьку шину передбачуваною. Відкат відновив пакети і стандартизував шляхи логіну. Час входу трохи зріс, але кількість інцидентів різко впала. Іноді «швидко» — це просто «крихке із гарним маркетингом».

Міні-історія №3: Нудна, але правильна практика, що врятувала день

У регульованому середовищі команда мала Ubuntu-сервери, які іноді потребували екстреної консолі. Була політика, що здавалася старомодною: кожна реакція на інцидент починається зі зйомки стану, включно з уривками journalctl -b і знімком шляхів сокетів у /run, перед будь-яким перезапуском.

Це здавалося бюрократією, поки на продакшн-хості не почалися помилки D-Bus після оновлення ядра. On-call дотримався політики. Вони зняли findmnt /run, перевірили вільне місце, підтвердили наявність /run/systemd/private і помітили, що /run/dbus/system_bus_socket відсутній. Також зняли ранні логи завантаження з попередженнями щодо tmpfs.

Завдяки наявності доказів вони не слідували паніці. З’ясувалося, що /run змонтовано лише для читання через тонку помилку initramfs/mount. Після виправлення і контрольованого перезавантаження сокет з’явився, systemctl відновився і інцидент закінчився чисто.

Нудна практика не лише виправила машину; вона зберегла наратив. У корпоративних середовищах наратив — половина відновлення: потрібно пояснити, що трапилось, без звинувачень у космічних променях.

Чек-листи / покроковий план

Чек-лист A: Ви бачите «Failed to get D-Bus connection» при запуску systemctl (системна область)

  1. Підтвердіть, що ви на хості і PID 1 — systemd (Task 2).
  2. Перевірте mount /run та його місткість (Task 6).
  3. Переконайтесь, що існує /run/dbus/system_bus_socket (Task 3).
  4. Перевірте systemctl status dbus dbus.socket (Task 4).
  5. Перевірте приватний сокет systemd /run/systemd/private (Task 18).
  6. Перевірте відповіді шини через busctl --system list (Task 17).
  7. Зберіть логи: journalctl -b і релевантні юніти (Task 12).
  8. Якщо потрібно перезапустити — робіть це свідомо: logind → dbus → daemon-reexec (Task 20).

Чек-лист B: Ви бачите помилку при systemctl --user або в інструментах робочого столу (сесійна область)

  1. Перевірте XDG_RUNTIME_DIR і DBUS_SESSION_BUS_ADDRESS (Task 7).
  2. Переконайтесь, що /run/user/UID і /run/user/UID/bus існують і належать користувачу (Task 8).
  3. Перевірте systemctl --user status (Task 9).
  4. Використайте loginctl list-sessions і loginctl show-user (Task 10).
  5. Якщо це SSH/cron: вирішіть, чи потрібна вам реальна сесія або замість цього системна служба.
  6. Якщо потрібні фонові сервіси користувача — увімкніть lingering для цього користувача (Task 16), потім повторіть тест.
  7. Якщо runtime-папка постійно зникає — виправте життєвий цикл сесій і PAM (Task 14/15).

Чек-лист C: Ви в автоматизації/CI і все падає

  1. Підтвердіть, чи ви в контейнері і PID 1 не systemd (Task 2).
  2. Перестаньте намагатися використовувати systemctl у цьому середовищі. Запускайте сервіс напряму або переробіть задачу.
  3. Якщо вам дійсно потрібен systemd — запускайте середовище із підтримкою systemd навмисно, а не випадково.

Жарт №2: Перезапускати dbus без перевірки сокетів — як перезавантажувати принтер через нестачу паперу: катарсично, неефективно і дивно популярно.

FAQ

1) Чому systemctl взагалі використовує D-Bus?

systemctl — клієнт. Воно розмовляє з API менеджера systemd, зазвичай доступним через D-Bus і приватний сокет systemd. Немає шини — немає діалогу.

2) Я бачу dbus-daemon в процесах. Чому я все ще отримую помилку?

Бо наявність процесу — не те ж саме, що досяжність сокета в вашому просторі/контексті. Перевірте шляхи сокетів під /run і впевніться, що ви в mount namespace хоста (Task 3, 6, 19).

3) Що змінює «No such file or directory» проти «Permission denied»?

No such file зазвичай означає, що шлях сокета відсутній у вашому уявленні (відсутній mount /run, відсутня runtime-папка, питання namespace). Permission denied означає, що сокет існує, але контролі доступу вам перешкоджають (не той користувач, політика або confinement).

4) Чому це ламається лише через SSH?

Або ваша SSH-сесія не реєструється в logind (несправна PAM-конфігурація), або ви виконуєте команду в обгортці/chroot. Перевірте pam_systemd.so і чи створюється /run/user/UID для цієї сесії (Task 10, 14).

5) Чи безпечно увімкнути lingering?

Це безпечно, коли ви знаєте, навіщо воно потрібно: запускати користувацькі сервіси без активних логінів. Небезпечно як універсальний хід, бо ви будете тримати менеджери користувачів живими, що може приховувати баги виходу і витрачати ресурси. Вмикайте вибірково (Task 16).

6) Чи можна просто експортувати DBUS_SESSION_BUS_ADDRESS і рухатися далі?

Можна, але не варто. Експорт застарілих адрес створює «працює в моєму шеллі» привиди, що ламають пізніше. Краще встановити реальний контекст сесії і дати logind/systemd задати XDG_RUNTIME_DIR та адресу шини.

7) Який найшвидший спосіб відрізнити системну шину від сесійної?

Якщо ви використовуєте systemctl без --user, то це системна область. Якщо релевантний сокет — /run/dbus/system_bus_socket, це системна шина. Якщо /run/user/UID/bus — це шина сесії користувача.

8) Я на мінімальному сервері — чи потрібен мені dbus-user-session?

Якщо ви запускаєте сервіси в користувацькій області або очікуєте, що сесії користувачів матимуть повноцінну сесійну шину — так, часто потрібен. Якщо ви лише керуєте системними службами, іноді можна й обійтись. Симптомно: якщо бракує шини користувача — перевірте пакети (Task 13).

9) Чому systemctl --user падає під root, навіть коли користувач залогінений?

Бо середовище root — не середовище користувача, і root не «приєднаний» до тієї користувацької шини. Запускайте команду як користувач у сесії або використовуйте інструменти, що адресують той менеджер користувача.

10) Коли варто перезавантажитись замість дебагу?

Якщо PID 1 у нездоровому стані, /run пошкоджено/лише для читання, або systemd-сокети відсутні і ви не можете їх відновити чисто — контрольований перезапуск часто найнадійніший вихід. Обов’язково збережіть логи перед цим.

Висновок: наступні кроки, які можна впровадити сьогодні

«Failed to get D-Bus connection» — не привід перезапускати випадкові служби. Це заклик перевірити контракт: /run змонтовано і записувано, потрібний сокет існує, ваша сесія реальна, і середовище вказує на правильну шину.

Зробіть наступне:

  1. Пройдiть швидкий план: сокети, runtime-папки, сесії logind. Не стрибайте одразу до перезапусків.
  2. Визначте, чи ваш робочий процес залежить від шини користувача. Якщо так — стандартизуйте шляхи входу (PAM + logind) і уникайте cron для сесійної роботи.
  3. Якщо це питання масштабу флоту — додайте легку перевірку здоров’я: перевіряйте наявність /run/dbus/system_bus_socket і /run/systemd/private, та аларміть при відсутності runtime-папок для активних сесій.
  4. Запишіть правило контексту: chroot/контейнери можуть і матимуть право на падіння systemctl. Ваші рукописи на випадок інцидентів мають це явно вказувати.
← Попередня
RAID — не резервна копія: фраза, яку люди усвідомлюють запізно
Наступна →
Docker Desktop Networking Weirdness: LAN Access, Ports, and DNS Fixes That Actually Work

Залишити коментар