AW-INC. 研究開発室

with secure communication

systemd の WantedBy と After で輪を作ると、起動ジョブが黙って捨てられる

本記事にはアフィリエイト広告(Amazon アソシエイト)が含まれます。

実測日: Thu Aug 20 2026 09:00:00 GMT+0900 (Japan Standard Time)

自作の systemd unit を Ansible で配備し、systemctl start が通って検証も通ったのに、次の再起動で片方だけ起動していなかった。
原因は unit ファイルの 1 行で、しかも配備直後には露見しない種類のものだった。
本記事では、その 1 行が何を引き起こすのか、どう検査すればよいのかを示す。

輪ができる書き方

ファン制御の unit は 2 つある。
方針を決める fan-policy と、その方針に従って回転数のカーブを回す fan-curve で、fan-curve は fan-policy の後に起動する。
どちらも WantedBy=multi-user.target で有効化した。

ここで、fan-policy に「他のサービスが揃ってから動かしたい」というつもりで After=multi-user.target を足した。
依存関係はこうなる。

multi-user.target --(Wants)--> fan-curve
fan-curve         --(After)--> fan-policy
fan-policy        --(After)--> multi-user.target   <-- これが輪を作る

WantedBy=multi-user.target は「multi-user.target が fan-policy を Wants する」という意味で、target 側が fan-policy を引く。
そこに After=multi-user.target を足すと、fan-policy は target の後に起動したいのに、target は fan-policy を含んで完了する、という循環になる。

systemd は輪を見つけると起動ジョブを削除する

起動時のログにはこう出る。

multi-user.target: Found ordering cycle on fan-curve.service/start
multi-user.target: Job fan-curve.service/start deleted to break ordering cycle

systemd は輪を見つけると、どれかのジョブを削除して輪をほどく。
削除されたのは、輪を作った fan-policy ではなく、それに依存する fan-curve の起動ジョブだった。
fan-curve は enabled のまま、一度も起動しない。

質が悪いのは、配備直後は正常に見えることである。
Ansible が systemctl start を打つので unit は active になり、配備後の検証も通る。
露見するのは次の再起動で、そのとき誰も見ていない。

systemd-analyze verify では見つからない

systemd-analyze verify にこの unit を通しても、何も指摘されなかった。
verify は unit ファイルの構文と参照先の存在を見るもので、起動順の循環までは追わない。
代わりに、次の 2 つの検査を配備の役割に組み込んだ。

  • After に target が入っていないこと:systemctl show <unit> --property=After の出力に multi-user.target が含まれないことを確認する。
  • 起動ログに削除の記録が無いこと:journalctl -b _PID=1 に deleted to break ordering cycle が無いことを確認する。

2 つ目は _PID=1 で絞ることが要る。
絞らずに journal を grep すると、Ansible が実行したコマンドの監査ログ(grep の文字列そのもの)に一致して誤検知する。

同じ 1 行を持つ別の機械

別の SoC を載せた機械の同名の unit も After=multi-user.target を持っており、そちらでも fan-curve が enabled のまま一度も起動していなかった。
同じ理由と考えてよい。
「他が揃ってから」を表したいなら、target ではなく具体的な unit を After に書く。

この記事で扱った機材

Radxa Fogwise AirBox(SOPHON BM1684X)

BM1684X 搭載の小型 AI ボックス。Ubuntu 20.04 ベースの BSP で、glibc の古さが USB アクセラレータの制約になる。


投稿日

カテゴリー:

投稿者: