Failed to get D-Bus connection: No connection to service manager

systemctl start foo.service でサービスを起動しようとしたら何故か上記のエラーで失敗。

しかも、以下のオプションについても同じエラーで、systemctl コマンド自体が全く機能しなくなりました。

  • systemctl start foo.service
  • systemctl stop foo.service
  • systemctl status foo.service
  • systemctl list-unit

ちなみに、D-Bus は、アプリケーション間でメッセージをやり取りするために実装された IPC (Interprocess Communication) 技法の一つとして、メッセージバスと呼ばれます。 (メッセージは、dbus-daemon によって管理される)

systemctl エラーメッセージRaw (S)Raw (T)
# systemctl start foo.service
Failed to get D-Bus connection: No connection to service manager.

# systemctl status foo.service
Failed to get D-Bus connection: No connection to service manager.

# systemctl list-units
Failed to get D-Bus connection: No connection to service manager.

メッセージを見る限り、D-Bus 接続取得に失敗しました って言ってるので、一応確認して見ると特に問題は無さそうです。

dbus 確認Raw (S)Raw (T)
# dpkg -l | grep "dbus"
ii  dbus                      1.8.8-1ubuntu2     amd64    simple interprocess messaging system (daemon and utilities)
ii  libdbus-1-3:amd64         1.8.8-1ubuntu2     amd64    simple interprocess messaging system (library)
ii  libdbus-glib-1-2:amd64    0.102-1            amd64    simple interprocess messaging system (GLib-based shared library)
ii  libnih-dbus1:amd64        1.0.3-4ubuntu26    amd64    NIH D-Bus Bindings Library
ii  python3-dbus              1.2.0-2build2      amd64    simple interprocess messaging system (Python 3 interface)

# ps -ef | grep "dbus-daemon" | grep -v "grep"
message+   426     1  0 15:45 ?        00:00:00 dbus-daemon --system --fork

検索してみると同じエラーで失敗した人たちの記事が色々出てくるのですが、ほとんどが Dockersystemctl が使えなくて、--privileged オプションを付けて、最後に起動コマンド /sbin/init でコンテナを起動したら直りましたという内容でした。

  • $ docker run --privileged -d --name httpd centos:centos7 /sbin/init
    --privileged は、SELinux 有効状態の環境で指定するオプション

しかし、Docker を使ってない環境で発生してるので、原因は他にあるかもしれません。

Linux 上で動くプロセスは、init (PID 1) から実行されるので、init プロセスの CMD を確認してみたら Systemd を使ってるはずなのに、systemd ではなく、init になっています

しかも、/sbin/init のシンボリック・リンクが何故か upstart を指しているので、これはおかしいですね。

PID 1 の CMD、及び init のリンク先確認Raw (S)Raw (T)
# ps -p 1 -o comm=
init

# file /sbin/init
/sbin/init: symbolic link to `upstart'

Upstart とは

Upstart は、いくつかの Unix系コンピュータオペレーティングシステムで起動時にタスクを実行する手法として古くから備わる init デーモンの代わりとなるもので、イベント駆動型である点に特徴がある。

Wikipedia : Upstart

それで、色々調べた結果、ヒントになったのがこちらの記事。

この URL に書いてあるように systemd-sysv をインストールし、再起動を実施します。

systemd-sysv インストール、及び 再起動Raw (S)Raw (T)
# apt-get install systemd-sysv

# shutdown -r now

そうすると /sbin/init → /lib/systemd/systemd になり、systemctl コマンドも今まで通りに使えるようになります。

PID 1 の CMD、及び init のリンク先確認 (systemd-sysv インストール後)Raw (S)Raw (T)
# ps -p 1 -o comm=
systemd

# file /sbin/init
/sbin/init: symbolic link to `/lib/systemd/systemd'

# systemctl status sshd.service
ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled)
   Active: active (running) since 水 2018-02-18 15:56:09 JST; 2min 14s ago
 Main PID: 695 (sshd)
   CGroup: /system.slice/ssh.service
           mq695 /usr/sbin/sshd -D

終わりに

色々弄くったので、火元が誰なのか詳細は不明ですが。

どうもパッケージインストール時に、そのパッケージが SysVinit を必要とし、依存関係によって、systemd 関連パッケージの一部が削除されたようです。

長年サーバやってきて、こんなこともあるんだなぁと思いました。

ご参考までに。

以上、systemctl が Failed to get D-Bus connection エラーで失敗する でした。