質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
systemd

systemdは、Linuxの起動処理及びシステム管理を行う技術です。他にも多くのサービス管理機能を備えており、ユーザープロセスを並列に起動しシステムの起動処理に要する時間を短縮できるなどの特徴があります。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

解決済

Systemd: 依存関係Requiresの挙動が認識と異なる(依存物起動失敗時の起動抑制が働かない)

FugahogeDS
FugahogeDS

総合スコア17

systemd

systemdは、Linuxの起動処理及びシステム管理を行う技術です。他にも多くのサービス管理機能を備えており、ユーザープロセスを並列に起動しシステムの起動処理に要する時間を短縮できるなどの特徴があります。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

1回答

0リアクション

0クリップ

877閲覧

投稿2020/05/31 21:16

前提・実現したいこと

Requiresの依存関係と成否があやふやになってます。はっきりさせたいので質問させてください。
各種資料を見ると、依存関係としてのRequires/Wantsについて

  • Requiresは依存ユニットが失敗すると起動できない
  • Wantsは依存ユニットが失敗しても起動する

という記述を見るのですが、Requires先で指定したユニットを敢えてエラー終了するようにしても起動しているように見えてしまいます。

下記のようにunitAとunitBが存在し、unitAがB側に依存という状況で、「unitBの起動に失敗したときにA側を起動させない」ための設定を教えていただければと思います…

現実例としては、 MariaDBが起動できない状況ならWordpress専用Apache(+PHP)の起動をキャンセルする でしょうか(中途半端に起動されるよりは失敗していた方が良い
派)。

発生している問題・エラーメッセージ

sl% sudo systemctl stop unitA unitB sl% sudo systemctl start unitA sl% sudo tail /var/log/syslog Jun 1 05:56:00 sl systemd[1]: Started Unit B. Jun 1 05:56:00 sl systemd[1]: Started Unit A. Jun 1 05:56:00 sl systemd[1]: unitB.service: Main process exited, code=exited, status=1/FAILURE Jun 1 05:56:00 sl systemd[1]: unitB.service: Failed with result 'exit-code'.

と、一度両方のユニットを止めた後A側を起動すると、Bはエラー停止してくれてますが、Aは起動を継続しています。
各ユニットの状態を取得すると、

sl% sudo systemctl status unitA unitB --no-pager ● unitA.service - Unit A Loaded: loaded (/usr/local/lib/systemd/system/unitA.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2020-06-01 05:56:00 JST; 1min 35s ago Main PID: 2657 (unitA) Tasks: 1 (limit: 1157) Memory: 632.0K CGroup: /system.slice/unitA.service └─2657 /bin/bash /usr/local/sbin/unitA 6月 01 05:56:00 sl systemd[1]: Started Unit A. ● unitB.service - Unit B Loaded: loaded (/usr/local/lib/systemd/system/unitB.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Mon 2020-06-01 05:56:00 JST; 1min 35s ago Process: 2656 ExecStart=/usr/local/sbin/unitB (code=exited, status=1/FAILURE) Main PID: 2656 (code=exited, status=1/FAILURE) 6月 01 05:56:00 sl systemd[1]: Started Unit B. 6月 01 05:56:00 sl systemd[1]: unitB.service: Main process exited, code=exited, status=1/FAILURE 6月 01 05:56:00 sl systemd[1]: unitB.service: Failed with result 'exit-code'.

と、やはりRequiresの意図と食い違っているように見えます。どこかで私が認識ミスを犯しているのでしょうか?

該当のソースコード

unitA.serviceとunitB.serviceの例です。

[Unit] Description = Unit A Requires = unitB.service After = unitB.service [Service] Type = simple ExecStart = /usr/local/sbin/unitA
[Unit] Description = Unit B [Service] Type = simple ExecStart = /usr/local/sbin/unitB

それぞれで起動するもの(unitA,unitB)は単純に無限ループするスクリプトにしていますが、B側は強制的にエラー終了扱いになるように手を入れてます。

#!/bin/bash # 注意: このスクリプトはひたすらにCPUを無駄遣いします # 強制エラー終了(Bのみ) exit 1 while true; do echo "" > /dev/null done

Aについてはexit行が無いだけです。

補足情報(FW/ツールのバージョンなど)

Ubuntu 20.04LTS上のsystemd環境です。

sl% dpkg -l systemd 要望=(U)不明/(I)インストール/(R)削除/(P)完全削除/(H)保持 | 状態=(N)無/(I)インストール済/(C)設定/(U)展開/(F)設定失敗/(H)半インストール/(W)トリガ待ち/(T)トリガ保留 |/ エラー?=(空欄)無/(R)要再インストール (状態,エラーの大文字=異常) ||/ 名前 バージョン アーキテクチ 説明 +++-==============-==============-============-================================= ii systemd 245.4-4ubuntu3 amd64 system and service manager

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

unoSSkR

2020/06/01 02:04

Suitable for you to write "Before = unitB.service" in unitA.service description?
FugahogeDS

2020/06/01 02:14

Thanks! ``` [Unit] Description = Unit A Requires = unitB.service Before = unitB.service # replaced [Service] Type = simple ExecStart = /usr/local/sbin/unitA ``` but, unitA is running. ``` sl% sudo systemctl stop unit{A,B} sl% sudo systemctl start unitA sl% sudo systemctl status unit{A,B} --no-pager ● unitA.service - Unit A Loaded: loaded (/usr/local/lib/systemd/system/unitA.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2020-06-01 11:07:11 JST; 8s ago Main PID: 12257 (unitA) Tasks: 1 (limit: 1157) Memory: 640.0K CGroup: /system.slice/unitA.service └─12257 /bin/bash /usr/local/sbin/unitA 6月 01 11:07:11 sl systemd[1]: Started Unit A. ● unitB.service - Unit B Loaded: loaded (/usr/local/lib/systemd/system/unitB.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Mon 2020-06-01 11:07:11 JST; 8s ago Process: 12258 ExecStart=/usr/local/sbin/unitB (code=exited, status=1/FAILURE) Main PID: 12258 (code=exited, status=1/FAILURE) 6月 01 11:07:11 sl systemd[1]: Started Unit B. 6月 01 11:07:11 sl systemd[1]: unitB.service: Main process exited, code=exited, status=1/FAILURE 6月 01 11:07:11 sl systemd[1]: unitB.service: Failed with result 'exit-code'. ``` I checked log(/var/log/syslog), running order is A -> B. I want running order; B -> A, and if B is failed, then don't start A.
unoSSkR

2020/06/01 02:30

We should see "Required" section in "man systemd.unit". May be both services are run simultaneously at boot, that's why your situation should be occured. Im not sure but when both services start normally without exit 1 in unitB shell, "systemctl stop unitB.service" would make unitA.servcie stop like you expect, right?
FugahogeDS

2020/06/01 02:55

"RequiredBy" in [Install]? I set "RequiredBy = unitA.service" in unitB.service, and install files. $ sudo systemctl enable unitB.service $ sudo systemctl start unitA But unitA is running. (unitA.service) [Unit] Description = Unit A Requires = unitB.service After = unitB.service [Service] Type = simple ExecStart = /usr/local/sbin/unitA [Install] WantedBy = multi-user.target --- (unitB.service) [Unit] Description = Unit B [Service] Type = simple ExecStart = /usr/local/sbin/unitB [Install] RequiredBy = unitA.service --- sl% ls -l /etc/systemd/system/unitA.service.requires total 0 lrwxrwxrwx 1 root root 43 6月 1 11:43 unitB.service -> /usr/local/lib/systemd/system/unitB.service stop unitB -> stop unitA is OK.

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

systemd

systemdは、Linuxの起動処理及びシステム管理を行う技術です。他にも多くのサービス管理機能を備えており、ユーザープロセスを並列に起動しシステムの起動処理に要する時間を短縮できるなどの特徴があります。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。