【2025年01月版】中年エンジニアのための systemd メモ 【systemctl, journalctl すぐ忘れてしまう人向け】

# はじめに

systemd に関する個人的メモ

突然 systemd でサービスを作ることになった時の参考にでもなれば。

:::note info
加筆修正しました（2024年01月版 → 2025年01月版）。
:::

古い記事はこちら

↓

- [【2023年7月版】systemd, journalctl メモ](https://qiita.com/nouernet/items/653ccb0172b1c96d052a)
- [【2023年1月版】 journalctl 覚えておきたい使い方メモ](https://qiita.com/nouernet/items/c60ff2621385f4d8f7b6)

# よくつかうコマンド

systemctl と journalctl を使う。

## systemctl　でよく使うコマンド

| コマンド                                 | 説明 |
|---------------------------------------|---------------------------------------------------------------------------------|
| `systemctl status サービス名`          | 指定されたサービスの現在の状態を表示する。起動状態、ログ、起動に関連するその他の情報が含まれる。 |
| `systemctl start サービス名`           | 指定されたサービスを起動する。サービスがまだ稼働していない場合に使用する。 |
| `systemctl stop サービス名`            | 指定されたサービスを停止する。サービスを一時的に停止させる場合に使用する。 |
| `systemctl restart サービス名`         | 指定されたサービスを再起動する。 |
| `systemctl is-active サービス名`      　 | 指定されたサービスが、起動しているか表示する。 |
| `systemctl cat サービス名`             | 指定されたサービスのユニットファイルの内容を表示する。設定の確認やデバッグで利用する。 |
| `systemctl enable サービス名`          | 指定されたサービスを有効化し、システム起動時に自動的に起動するように設定する。 |
| `systemctl disable サービス名`         | 指定されたサービスを無効化し、システム起動時に自動的に起動しないように設定する。 |
| `systemctl is-enabled サービス名`      | 指定されたサービスが、システム起動時に自動的に起動するか表示する。 |
| `systemctl list-units --type service`  | システム上で稼働中の全サービスユニットをリストアップする。 |
| `systemctl list-unit-files --type service` | システムにインストールされている全サービスユニットファイルをリストアップする。 |
| `systemctl list-dependencies サービス名 --after`  | 指定されたサービスの先に起動するユニットを表示する。 |
| `systemctl list-dependencies サービス名 --before`  | 指定されたサービスの後に起動するユニットを表示する。 |

## journalctl でよく使うコマンド

| コマンド                                 | 説明 |
|---------------------------------------|---------------------------------------------------------------------------------|
| `journalctl -r` | 降順でログを表示する。 |
| `journalctl --since="2023-12-24 22:15:00` | 2023-12-24 22:15:00 からのログを表示する。 |  
| `journalctl -f` | 最新のログをフォロー表示する。 |
| `journalctl -b` | 今回起動してからのログを表示する。 |
| `journalctl -b -1` | 前回起動してからのログを表示する。 |
| `journalctl -b -2` | 前前回起動してからのログを表示する。 |
| `journalctl --no-pager` | ページャーを使用しないでログを表示する。 |
| `journalctl -p err -xb` | エラーログのみ、前回起動してから詳細情報を含めて表示する。 |
| `journalctl --list-boots` | 起動毎の最初の更新時間と、最終の更新時間をリスト表示する。 |
| `journalctl --disk-usage` | すべてのジャーナルファイルの現在のディスク使用量を表示する。 |

---

# systemctl

## 主な systemctl のサブコマンド

| サブコマンド | 説明 |
|:-:|:-:|
| start  | サービスを起動  |
| stop  | サービスを停止  |
| restart  | サービスを再起動  |
| reload  | サービスの設定を再読み込み  |
| status  | サービスの稼働状況の表示  |
| is-active  | サービスが起動しているかどうか確認  |
| enable  | システム起動時にサービスを起動するように設定  |
| disable  | システム起動時にサービスを起動しないように設定  |
| is-enabled | システム起動時にサービスが起動されるかどうか確認、aliasの場合もある |
| mask  | Unitを起動できないように指定  |
| unmask  | Unitのmaskを解除  |
| kill  | Unitへシグナルを送る  |
| daemon-reload  | 設定を再読み込み  |
| cat  | Unitファイルの内容表示  |
| list-units  | 起動しているUnitの表示  |
| list-unit-files  | すべてのUnitの表示  |
| list-dependencies  | Unitの依存関係の表示  |
| reboot  | システムの再起動  |
| poweroff  | システムの停止  |
| rescue  | シングルユーザモード  |
| emergency | 緊急モード   |

## 主なサブコマンドのオプション

| オプション | 説明 |
|:-:|:-:|
| -t, --type=  | 種類を指定  |
| --state=  | 状態を指定  |
| -l, --full  | 省略せずに表示  |
| -a, --all  | Unitすべてを表示  |
| -s, --signal=  | シグナルの指定  |
| --no-pager  | ページャ無しの表示  |

# journalctl

## 主なオプション
| オプション | 説明 |
| --- | --- |
| `-b`, `--boot` | 現在のブートまたは特定のブートのジャーナルメッセージを表示 |
| `-f`, `--follow` | ログがリアルタイムで更新されると、その更新を表示 |
| `-u`, `--unit=, _SYSTEMD_UNIT` | 特定のシステムユニットのジャーナルメッセージを表示 |
| `-k`, `--dmesg` | カーネルメッセージのみを表示 |
| `-p`, `--priority=` | 指定された優先度またはそれより重要なメッセージを表示 |
| `_PID=` | 指定されたPIDのメッセージを表示 |
| `_UID=` | 指定されたUIDのメッセージを表示 |
| `-r`, `--reverse` | ジャーナルエントリを最新から最初へと逆順に表示 |
| `-S`, `--since=` | 指定した日時以降のジャーナルメッセージを表示 |
| `-U`, `--until=` | 指定した日時までのジャーナルメッセージを表示 |
| `--no-pager` | ページングを無効にし、すべてのログを一度に表示 |
| `--no-hostname` | ログエントリからホスト名を除外 |
| `-x`, `--catalog` | 可能な場合、メッセージカタログから追加情報を取得して表示 |
| `-o`, `--output=` | 指定されたフォーマットでジャーナルメッセージを表示 |
| `-n`, `--lines=` | 末尾から指定された行数を表示、デフォルトは10行 |
| `-e`, `--pager-end` | 末尾から1000行をページャーで表示 |
| `--list-boots` | ブートに関連する最初と最後のメッセージのタイムスタンプを表形式で表示する。200から。 |
| `--disk-usage` | すべてのジャーナルファイルの現在のディスク使用量を表示する。190から。 |

## ログのプライオリティ

| プライオリティ | 値             | 説明                         |
|----------------|----------------|------------------------------|
| 0              | emerg          | システムが使用不可能         |
| 1              | alert          | 直ちに行動を要する           |
| 2              | crit           | 致命的な状態                 |
| 3              | err            | エラー                       |
| 4              | warning        | 警告                         |
| 5              | notice         | 通常だが重要な状態           |
| 6              | info           | 情報メッセージ               |
| 7              | debug          | デバッグレベルのメッセージ   |

## よくつかうパターン

### から

```terminal
$ journalctl --since="2023-08-12 22:15:00"
```

### まで

```terminal
$ journalctl --until="2023-08-13 22:15:00"
```

### 日付範囲

```terminal
$ journalctl --since="2023-08-13 22:15:00" --until="2023-08-14 23:15:00"
```

### 現在日付からの差分を指定

```terminal
$ journalctl --since="$(date -d '12 hour ago' '+%Y-%m-%d %H:%M:%S')" --until="$(date -d '11 hour ago' '+%Y-%m-%d %H:%M:%S')"
```

### 降順

```terminal
$ journalctl -r
```

### 最新のログをフォロー表示

```terminal
$ journalctl -f
```

### 今回起動してから

```terminal
$ journalctl -b
```

### 今回起動してから、エラーのみ

```terminal
$ journalctl -b -p err
```

### 前回起動してから

```terminal
$ journalctl -b -1
```

### 前前回起動してから

```terminal
$ journalctl -b -2
```

### カーネルログのみ

```terminal
$ journalctl -k
```

### ページャーを使用しない

```terminal
$ journalctl --no-pager
```

```terminal
$ journalctl -xn | less
```

### エラーログのみ、今回起動してから、追加情報込みで

```terminal
$ journalctl -p 4 -xb
```

### カレントでないjournalログフォルダから読み込んで使う、フォルダごといける

```terminal
$ journalctl -D /var/log/journal/xxxxxxxxx
```

### 古いログファイルから読み込んで使う

```terminal
$ journalctl --file=/var/log/journal/old.log
```

### ブート時間を確認する

```terminal
$ journalctl --list-boots
```

### すべてのジャーナルファイルの現在のディスク使用量を表示する

```terminal
$ journalctl --disk-usage 
```

# 主なユニット

systemd では、システムの起動処理は Unit と呼ばれる処理単位に分割される
| Unitの拡張子 | 説明 |
|:-:|:-:|
| service  | 各種サービスの起動  |
| device  | 各種デバイス、udevのデバイス認識で自動作成  |
| mount  | ファイルシステムのマウント、/etc/fstabから自動作成  |
| swap  | スワップ領域、/etc/fstabから自動作成  |
| target  | Unitのグループ  |
| socket  | ソケットの監視〜接続時にサービスの起動  |
| timer  | サービスの起動の予約  |

# おぼえておきたいこと

## ユニットファイル

要は設定ファイル。
ユニットファイルは、サービス、マウントポイント、デバイス、およびその他のリソースを管理するための仕組み。
systemd はユニットファイルを読み込んで、メモリ上に `unit` を作成する。
実行時に生成されるユニットファイルは `/run/systemd` に配置される。
ユニットファイルのない `unit` も存在する。

### 作り方

作成中

### 基本概念

ユニットファイルは、systemdが管理するリソースを定義する。
種類があって、サービス（デーモン）、ソケット、デバイス、マウントポイント、自動起動タスク（タイマー）などが含まれる。
まずは、サービス（デーモン）だけを扱うと理解しやすい。

### ファイルの位置

ユニットファイルは通常、以下のディレクトリに配置される。

#### `/etc/systemd/system/`
システム管理者によって作成されたカスタムユニットファイル。

#### `/usr/lib/systemd/system/` または `/lib/systemd/system/`
パッケージマネージャによってインストールされたユニットファイル。

#### 確認方法

`systemd-analyze unit-paths` - システム全体用のユニットファイルの位置
`systemd-analyze --user unit-paths` - ユーザー用のユニットファイルの位置

### ファイル形式

ユニットファイルは、INI形式（セクションとキー/値のペアで構成される）で書かれている。
各ユニットファイルは特定のタイプのリソースに対応している。
拡張子で識別される。

例: .service, .socket, .mount

### サービスユニット

サービスユニット（.serviceファイル）は最も一般的なユニットタイプ。
バックグラウンドで実行されるプロセス（デーモン）を定義する。
この定義には、サービスの開始方法、依存関係、リソース制限などが含まれる。

### その他のユニットタイプ

- .socket： ソケットベースの通信を待ち受けるユニット
- .device： 特定のハードウェアデバイスを表すユニット
- .mount： ファイルシステムのマウントポイントを制御するユニット
- .timer： cronジョブに似た、時間ベースのタスクスケジューリング

### 有効化と無効化

ユニットはsystemctlコマンドを使用して有効化（自動起動）または無効化（自動起動しない）される。

### ユニットの管理

`systemctl` コマンドを使用して、ユニットの状態を確認し、開始、停止、再起動、リロードすることができる。

### ユニットファイルの編集

vim などで編集してもいいが、専用コマンドもある。以下はドロップインを編集するためのコマンド。

`systemctl edit サービス名`

`/etc/systemd/system/サービス名.d/override.conf` に保存される。
操作には `root` 権限が必要。

ドロップインではなく、システテム全体用のユニットファイルを編集すうには以下のコマンドを利用する。

`systemctl edit --full サービス名`

どちらの場合も、編集後、自動的に `systemctl daemon-reload` される。

### 検証

ユニットファイルの内容で間違いがあると、systemd は無視する。その際に、ログにエラーが出力される。
ユニットファイルの編集時に検証を行うには、以下のコマンドを利用する。

`systemd-analyze verify サービス名`

### 内容確認

ユニットファイルの内容を直接確認する方法の他に、ドロップインによる変更などを含めて、現在の読み込まれているユニットファイルを表示するには、以下のコマンドを利用する。

`systemctl cat サービス名`

### 差分確認

システムのデフォルトから変更されている内容を確認するには `systemd-delta` コマンドを利用する。
`ssytemd-delta サービス名` でフィルタできる場合もあるが、そうでない場合は、grep などでフィルタする。

| オプション | 説明 |
| --- | --- |
| `-t`, `--type=` | 差分の種類を指定。可能な値は `extended`, `masked`, `equivalent`, `redirected`, `overridden` |
| `--no-pager` | 出力のページングを無効 |
| `--no-legend` | 凡例を非表示|
| `--system` | システムユニットの差分を表示|
| `--user` | ユーザユニットの差分を表示|
| `--runtime` | ランタイム設定の差分を表示|
| `--global` | グローバル設定の差分を表示|

### 主なセクション

| セクション名 | 説明 |
|:-:|:-:|
| Unit  | ユニットの説明、ドキュメンテーションへのリンク、他のユニットに対する依存関係を定義  |
| Service  | サービスユニットに特有で、実行するプロセスの動作を定義  |
| Socket  | ソケットユニットで使用され、ソケットの設定を定義  |
| Install  | ユニットがどのように "enabled" (有効化) や "disabled" (無効化) されるかを定義 |
| Timer  | タイマーユニットで使用され、定期的にまたは特定の時間にユニットを起動するためのタイマーを定義 |
| Mount  | マウントユニットで使用され、特定のファイルシステムのマウントポイントを定義 |
| Path  | パスユニットで使用され、特定のファイルやディレクトリの存在や変更を監視し、それに応じたユニットを定義 |
| Network | ネットワークユニットで使用され、ネットワーク接続を定義 |
| Automount | 自動マウントユニットで使用され、アクセス時に自動マウントを定義 |

### 主なパラメータ

| セクション | パラメータ | 説明 |
| --- | --- | --- |
| `Unit` | `Description` | ユニットの概要を提供するフリーテキストフィールド |
|  | `Documentation` | ユニットに関するドキュメンテーションのURLを指定 |
|  | `After`, `Before` | 他のユニットに対する順序依存性を指定 |
| `Service` | `ExecStart` | サービスを開始するためのコマンド |
|  | `ExecStop` | サービスを停止するためのコマンド |
|  | `Restart` | サービスが失敗したときの再起動ポリシー |
| `Socket` | `ListenStream`, `ListenDatagram` | ソケットが待ち受けるアドレスとポート |
|  | `Accept` | サービスが接続ごとに新しいプロセスを生成するかどうか |
| `Install` | `WantedBy` | ユニットがインストールされたときに起動するターゲット |
|  | `Alias` | ユニットの別名 |
| `Timer` | `OnBootSec` | システム起動後にタイマーが起動するまでの時間 |
|  | `OnUnitActiveSec` | 指定したユニットが最後にアクティブになってからタイマーが起動するまでの時間 |
| `Mount` | `What` | マウントするリソースのパス |
|  | `Where` | マウントポイントのパス |
|  | `Type` | ファイルシステムの種類 |
| `Path` | `PathExists` | 指定したパスが存在する場合にユニットを起動 |
|  | `PathChanged` | 指定したパスが変更された場合にユニットを起動 |
| `Network` | `DHCP` | DHCPを使用するかどうか |
|  | `Address` | 静的IPアドレスの設定 |
| `Automount` | `Where` | マウントポイントのパス |
|  | `TimeoutIdleSec` | アクセスがない場合の自動アンマウントまでの時間 |
---

## ドロップイン

サービスのカスタマイズ設定機能。
書いた覚えがないのに、設定とは違う動作をしている。。。というときにはこの機能を疑う。
違うファイルで設定が上書きされていますよ、という話。
自分の設定ファイルと、systemctl cat サービス名 で出力される内容が違うなら、ドロップインで上書きされている。


### ドロップインの概念

systemd では、サービス設定は `.service` ファイルで定義される。
ドロップインは、既存のサービス設定を変更したり、追加の設定を提供するために使用される小さな設定ファイル群を指す。

### 利点

ドロップインを使用することで、パッケージによって提供される元の `.service` ファイルを直接編集する必要がなくなる。
これにより、アップデート時にカスタマイズが上書きされるリスクを避けたりできる。

### 配置方法

ドロップインファイルは通常、以下のディレクトリに配置される。ファイル名は任意だが、`.conf` で終わる必要がある。

`/etc/systemd/system/サービス名.service.d/`

例: sshdサービスのタイムアウトを変更したい場合は、
`/etc/systemd/system/sshd.service.d/override.conf` というファイルを作成し、必要な設定を追加する。

### 有効化

ドロップインファイルを追加または編集した後、`systemctl daemon-reload` コマンドを実行して、systemd に変更を認識させる必要がある。その後、対象のサービスを再起動することで変更が適用される。
設定を変更したのに反映されない。。。というときは、まずこの有効化を疑う。

### 確認方法

`systemctl status サービス名` を使用すると、そのサービスに適用されているドロップインの一覧を確認できる。

---

## サービスの状態

サービスは以下の状態を持つ。

| 状態         | 説明 |
|------------|-------------------------------------------------------------|
| `active`   | サービスが現在稼働中であることを示す。 |
| `inactive` | サービスが停止していることを示す。 |
| `enabled`  | サービスがシステム起動時に自動的に開始されるように設定されている。 |
| `disabled` | サービスがシステム起動時に自動的には開始されないように設定されいる。 |
| `failed`   | サービスが何らかの理由で起動に失敗したことを示す。 |
| `reloading`| サービスが設定のリロード中であることを示す。 |
| `masked`   | サービスが完全に無効化され、起動できない状態にあることを示す。 |

### 状態遷移

```plantuml
@startuml

inactive --> active : start\n(systemctl start)
active --> inactive : stop\n(systemctl stop)
active --> active : restart\n(systemctl restart)
inactive --> failed : failed to start
failed --> inactive : reset-failed\n(systemctl reset-failed)
active --> reloading : reload\n(systemctl reload)
reloading --> active : finish reload
inactive --> enabled : enable\n(systemctl enable)
enabled --> inactive : disable\n(systemctl disable)
inactive --> masked : mask\n(systemctl mask)
masked --> inactive : unmask\n(systemctl unmask)

@enduml
```

### 状態遷移の状況確認

`systemctl list-jobs` で状態遷移中のサービスを確認できる。
が、ほとんどが一瞬でほとんど確認することはできない。
`systemctl restart サービス名`等を行って、応答がない場合などに試すと表示される。

---

## ランレベルとターゲット

`systemd` では `SysV init` のランレベルをターゲットにマッピングしている。

| SysVinitのランレベル | 対応する`systemd`ターゲット       | 説明 |
|------------------|------------------------------|-----------------------------------------------|
| 0                | `runlevel0.target`, `poweroff.target` | システムのシャットダウン（電源オフ）。 |
| 1                | `runlevel1.target`, `rescue.target`   | シングルユーザーモード（システムレスキューモード）。 |
| 2                | `runlevel2.target`, `multi-user.target` | ユーザが多数ログイン可能だが、ネットワークサービスが非アクティブ。 |
| 3                | `runlevel3.target`, `multi-user.target` | マルチユーザーモードでネットワークサービスが有効。 |
| 4                | `runlevel4.target`, `multi-user.target` | 未使用/ユーザー定義（ディストリビューションによって異なる）。 |
| 5                | `runlevel5.target`, `graphical.target`  | マルチユーザーモードでグラフィカルインターフェースが有効。 |
| 6                | `runlevel6.target`, `reboot.target`    | システムの再起動。 |

## ターゲットの変更

ターゲットの変更を行うことで、シャットダウンや再起動を行うことができる。

- `systemctl poweroff` - システムのシャットダウン（電源オフ）
- `systemctl reboot` - システムの再起動
- `systemctl rescue` - シングルユーザーモード（ネットワーク利用不可）
- `systemctl emergency` - 緊急モード（シングルユーザモード ＋ ネットワーク利用可能）

## service のタイプ

man systemd.service から抜粋

タイプ=
このサービスユニットのプロセス起動タイプを設定します。simple、exec、forking、oneshot、dbus、notify、またはidleのいずれかです：

ExecStart=が指定されているがType=もBusName=も指定されていない場合のデフォルトであるsimpleに設定されている場合、サービスマネージャーはメインサービスプロセスがフォークされた直後にユニットが開始されたと見なします。ExecStart=で設定されたプロセスがサービスのメインプロセスであることが期待されます。このモードでは、プロセスがシステム上の他のプロセスに機能を提供する場合、サービスが起動する前に通信チャネルが設定されている必要があります（例えば、systemdによって設定されたソケット、ソケットアクティベーションを介して）。なぜなら、サービスマネージャーはメインサービスプロセスの作成直後、サービスのバイナリを実行する前に、直ちにフォローアップユニットの起動を進めるからです。これは、simpleなサービスのsystemctl startコマンドラインが、サービスのバイナリが正常に呼び出されなかった場合でも成功を報告することを意味します（例えば、選択されたUser=が存在しない場合や、サービスバイナリが欠けている場合）。

execタイプはsimpleに似ていますが、サービスマネージャーはメインサービスバイナリが実行された直後にユニットが開始されたと見なします。サービスマネージャーはその時点までフォローアップユニットの開始を遅延します。（つまり、simpleはfork()が返された直後にさらなるジョブに進みますが、execはサービスプロセスでfork()とexecve()の両方が成功するまで進みません。）これは、execサービスのsystemctl startコマンドラインが、サービスのバイナリが正常に呼び出されなかった場合に失敗を報告することを意味します（例えば、選択されたUser=が存在しない場合や、サービスバイナリが欠けている場合）。

forkingに設定されている場合、ExecStart=で設定されたプロセスがスタートアップの一環としてfork()を呼び出すことが期待されます。親プロセスは、スタートアップが完了し、すべての通信チャネルが設定されたときに終了することが期待されます。子プロセスはメインサービスプロセスとして実行を続け、親プロセスが終了したときにユニットが開始されたとサービスマネージャーによって見なされます。これは伝統的なUNIXサービスの動作です。この設定を使用する場合、systemdがサービスのメインプロセスを確実に識別できるように、PIDFile=オプションの使用も推奨されます。systemdは、親プロセスが終了するとすぐにフォローアップユニットの開始を進めます。

oneshotの動作はsimpleに似ていますが、サービスマネージャーはメインプロセスが終了した後にユニットが起動したと見なします。その後、フォローアップユニットの開始が行われます。このタイプのサービスには、RemainAfterExit=が特に有用です。Type=oneshotは、Type=もExecStart=も指定されていない場合の暗黙のデフォルトです。このオプションがRemainAfterExit=なしで使用された場合、サービスは「アクティブ」なユニット状態には入らず、「アクティブ化」から「非アクティブ化」または「死亡」に直接移行します。なぜなら、継続的に実行されるプロセスが設定されていないからです。特にこれは、このタイプのサービスが実行された後（そしてRemainAfterExit=が設定されていない場合）、それが開始された後としてではなく、死亡したとして表示されることを意味します。

dbusの動作はsimpleに似ていますが、サービスがBusName=で設定されたD-Busバス上で名前を取得することが期待されます。systemdは、D-Busバス名が取得された後にフォローアップユニットの開始を進めます。このオプションが設定されたサービスユニットは、dbus.socketユニットに対する暗黙の依存関係を持ちます。BusName=が指定されている場合、このタイプはデフォルトです。指定されたバス名が取得されるまで、このタイプのサービスユニットはアクティブ化状態と見なされます。バス名が取られている間はアクティブ化されていると見なされます。バス名が解放されると、サービスは機能を失ったと見なされ、サービスマネージャーはサービスに属する残りのプロセスの終了を試みます。シャットダウンロジックの一部としてバス名を削除するサービスは、SIGTERM（またはKillSignal=で設定された信号）を結果として受け取ることを準備するべきです。

notifyの動作はexecに似ていますが、サービスが起動を完了したことを示す通知メッセージをsd_notify(3)または同等の呼び出しを通じて送信することが期待されます。systemdは、この通知メッセージが送信された後にフォローアップユニットの開始を進めます。このオプションを使用する場合、NotifyAccess=（下記参照）は、systemdによって提供される通知ソケットへのアクセスを開放するように設定されるべきです。NotifyAccess=が欠けているかnoneに設定されている場合、mainに強制的に設定されます。

idleの動作はsimpleに非常に似ていますが、サービスプログラムの実際の実行は、すべてのアクティブなジョブがディスパッチされるまで遅延されます。これは、シェルサービスの出力がコンソールのステータス出力と交錯するのを避けるために使用されるかもしれません。このサービスタイプはコンソール出力を改善するためにのみ有用であり、一般的なユニット順序付けツールとしては有用ではないこと、そしてこのサービスタイプの効果は5秒のタイムアウトの対象であることに注意してください。その後、サービスプログラムはいずれにせよ呼び出されます。

通常、長時間実行されるサービスに対しては、可能な限りType=simpleを使用することが推奨されます。これは最もシンプルで高速なオプションだからです。しかし、このサービスタイプではサービスの起動失敗が伝播せず、サービスの初期化完了に対して他のユニットを順序付けることができないため（例えば、クライアントが何らかの形のIPCを通じてサービスに接続する必要があり、IPCチャネルがサービス自体によってのみ確立される場合 - ソケットやバスアクティベーションなどを通じて事前に行うのとは対照的に）、多くの場合には十分ではないかもしれません。その場合、サービスプログラムコードが、サービスの起動が成功したと見なすタイミングと、フォローアップユニットに進むタイミングを正確にスケジュールすることを可能にするnotifyまたはdbus（後者はサービスがD-Busインターフェースを提供する場合のみ）が推奨されるオプションです。notifyサービスタイプは、サービスコードベースで明示的なサポートが必要です（sd_notify()または同等のAPIを適切なタイミングでサービスによって呼び出す必要があります）。サポートされていない場合、forkingが代替となります。これは伝統的なUNIXサービスの起動プロトコルをサポートしています。最後に、execはサービスバイナリが呼び出されることを確実にし、サービスバイナリ自体がほとんどまたは全く初期化を実行しない場合（またはその初期化が失敗する可能性が低い場合）に適したオプションかもしれません。simple以外のタイプを使用すると、サービスマネージャーがサービスの初期化が完了するまで待つ必要があるため、ブートプロセスが遅延する可能性があることに注意してください。そのため、不必要にsimple以外のタイプを使用しないことが推奨されます。（また、長時間実行されるサービスにidleまたはoneshotを使用することは一般的に推奨されません。）

## BOOTUP におけるターゲットの関連性

man page bootup `SYSTEM MANAGER BOOTUP` から抜粋

起動時、OSイメージ上のシステムマネージャーは、システムの運用に必要なファイルシステム、サービス、およびドライバーを初期化する責任を持ちます。systemd(1) システムでは、このプロセスは様々な個別のステップに分割され、これらはターゲットユニットとして公開されています。（ターゲットユニットに関する詳細情報については、systemd.target(5)を参照してください。）起動プロセスは高度に並列化されているため、特定のターゲットユニットが到達される順序は決定的ではありませんが、限られた順序構造には従っています。

systemdがシステムを起動するとき、default.target（およびその依存関係の依存関係も再帰的に）のすべてのユニットがアクティブ化されます。通常、default.targetは単にgraphical.targetまたはmulti-user.targetのエイリアスです。これは、システムがグラフィカルUI用に設定されているか、テキストコンソールのみ用に設定されているかに依存します。ユニット間に最小限の順序を強制するために、systemd.special(7)に記載されているような、多くのよく知られたターゲットユニットが利用可能です。

次のチャートは、これらのよく知られたユニットと、起動ロジック内での位置を概観したものです。矢印は、どのユニットが他のどのユニットの前に引き込まれ、順序付けられるかを示しています。チャートの上部にあるユニットは、チャートの下部に近いユニットよりも前に開始されます。

```plantuml
@startuml

[cryptsetup-pre.target veritysetup-pre.target] -down-> [cryptsetup.target]
[cryptsetup-pre.target veritysetup-pre.target] -down-> [remote-cryptsetup.target remote-veritysetup.target]
[veritysetup-pre.target] -down-> [remote-veritysetup.target]
[cryptsetup.target] -down-> [sysinit.target]
[remote-fs-pre.target] -down-> [cryptsetup-pre.target veritysetup-pre.target]
[remote-fs-pre.target] -down-> [remote-fs.target]
[remote-cryptsetup.target] -down-> [multi-user.target]
[remote-veritysetup.target] -down-> [multi-user.target]
[remote-fs.target] -down-> [multi-user.target]
[swap.target] -down-> [sysinit.target]
[local-fs-pre.target] -down-> [local-fs.target]
[local-fs.target] -down-> [sysinit.target]
[sysinit.target] -down-> [timers.target]
[sysinit.target] -down-> [paths.target]
[sysinit.target] -down-> [sockets.target]
[sysinit.target] -down-> [basic.target]
[sysinit.target] -down-> [rescue.service]
[rescue.service] -down-> [rescue.target]
[basic.target] -down-> [display-manager.service]
[basic.target] -down-> [multi-user.target]
[paths.target] -down-> [basic.target]
[sockets.target] -down-> [basic.target]
[display-manager.service] -down-> [graphical.target]
[multi-user.target] -down-> [graphical.target]
[emergency.service] -down-> [emergency.target]

@enduml
```

## Special System Units

man page systemd.special から抜粋

| ユニット | 説明 |
| ------ | ---- |
| -.mount | ルートマウントポイント、つまり/パスのマウントユニットです。このユニットは、システムが起動している間、常にアクティブです。なぜなら、このマウントポイントは基本的なユーザースペースが動作している場所だからです。 |
| basic.target |基本的な起動をカバーする特別なターゲットユニット。systemdは、このターゲットユニットに対して、After=のタイプの依存関係を自動的に全てのサービスに追加します（DefaultDependencies=noのものを除く）。通常、これにはすべてのローカルマウントポイントプラス/var/、/tmp/、/var/tmp/、スワップデバイス、ソケット、タイマー、パスユニット、および一般目的のデーモンに必要な他の基本的な初期化が含まれるべきです。言及されたマウントポイントは、リモートであることを可能にするために特別なケースとして扱われます。このターゲットは通常、他の早期起動ターゲットを介して間接的に行う場合を除いて、直接的に非ターゲットユニットを引き込むことはありません。代わりに、後期の起動サービスのための同期ポイントとして意図されています。関連するターゲットの詳細については、bootup(7)を参照してください。|
|boot-complete.target|このターゲットは、ブートプロセスが正常に完了したかどうかを判断したり、その結果に基づいて行動するサービスのための一般的な同期ポイントとして意図されています。ブートプロセスが成功したと見なされる前に成功する必要があるユニットをこのユニットの前に配置し、そのターゲットユニットからそれらにRequires=依存関係を追加してください。ブートプロセスが成功したと見なされた後にのみ実行されるべきユニットは、ターゲットユニットの後に配置し、またRequires=でそれからターゲットを引き込んでください。デフォルトでは、このターゲットユニットは初期ブートトランザクションの一部ではありませんが、成功したブート時にのみ実行したいユニットによって必要とされる場合にのみ引き込まれることを意図しています。ジェネリックなシステムヘルスチェックを実装し、自身をboot-complete.targetの前に配置するサービスについては、systemd-boot-check-no-failures.service(8)を参照してください。ブートローダーにブート成功情報を伝播し、自身をboot-complete.targetの後に配置するサービスについては、systemd-bless-boot.service(8)を参照してください。|
|ctrl-alt-del.target|systemdは、コンソールでControl+Alt+Delが押されると、このターゲットを開始します。通常、これはreboot.targetにエイリアス（シンボリックリンク）されるべきです。|
|cryptsetup.target|すべての暗号化されたブロックデバイスのセットアップサービスを引き込むターゲットです。|
|veritysetup.target|すべてのverity整合性保護されたブロックデバイスのセットアップサービスを引き込むターゲットです。|
|dbus.service|D-Busバスデーモンのための特別なユニットです。このサービスが完全に起動すると、systemdはそれに接続し、自身のサービスを登録します。|
|dbus.socket|D-Busシステムバスソケットのための特別なユニットです。Type=dbusを持つすべてのユニットは自動的にこのユニットに依存関係を持ちます。|
|default.target|systemdが起動時に開始するデフォルトユニットです。通常、これはmulti-user.targetまたはgraphical.targetにエイリアス（シンボリックリンク）されるべきです。詳細についてはbootup(7)を参照してください。systemdが起動時に開始するデフォルトユニットは、systemd.unit=カーネルコマンドラインオプションでオーバーライドすることができます。また、single、rescue、1、3、5などの短い名前でより便利に設定することもできます。詳細についてはsystemd(1)を参照してください。|
|display-manager.service|ディスプレイマネージャーサービスです。通常、これはgdm.serviceまたは類似のディスプレイマネージャーサービスにエイリアス（シンボリックリンク）されるべきです。|
|emergency.target|メインコンソールで緊急シェルを起動する特別なターゲットユニットです。このターゲットは他のサービスやマウントを引き込みません。これは、対話型シェルを取得するためにシステムを起動する最も最小限のバージョンで、通常動作しているプロセスはシステムマネージャー（PID 1）とシェルプロセスだけです。このユニットは、カーネルコマンドラインにemergencyを指定することで使用されます。また、必須のファイルシステムのチェックに失敗し、ブートアップが続行できない場合にも使用されます。rescue.targetと比較してください。これも同様の目的を果たしますが、最も基本的なサービスも起動し、すべてのファイルシステムもマウントします。emergency.targetにブートすることは、カーネルコマンドラインで"init=/bin/sh"を使用してブートする効果と多くの点で似ていますが、緊急モードでは完全なシステムとサービスマネージャーが提供され、個々のユニットを起動してブートプロセスを段階的に続行することが可能です。emergency.targetに到達する方法によっては、ルートファイルシステムが読み取り専用または読み書き可能でマウントされている可能性があります（このターゲットのために特別に再マウントは行われません）。例えば、カーネルコマンドラインでroを使用すると、システムが読み取り専用でルートをマウントしてブートし、emergency.targetにそのままの状態で移行することがあります。または、システムが部分的にブートされ、ディスクがすでに読み書き可能に再マウントされた後にemergency.targetに移行することがあります。
|exit.target|システムまたはユーザーサービスマネージャーをシャットダウンするための特別なサービスユニットです。コンテナ非搭載システムではpoweroff.targetに相当し、コンテナ内でも機能します。systemdは、ユーザーサービスデーモンとして実行されている際にSIGTERMまたはSIGINTシグナルを受け取ると、このユニットを開始します。通常、これは（間接的に）shutdown.targetを引き込みます。これは、サービスマネージャーが終了し始めるときにシャットダウンがスケジュールされることを望むすべてのユニットによって競合されるべきです。|
|final.target|シャットダウンロジック中に使用される特別なターゲットユニットで、すべての通常のサービスが既に終了し、すべてのマウントがアンマウントされた後に遅いサービスを引き込むために使用される場合があります。|
|getty.target|静的に設定されたローカルTTY gettyインスタンスを引き込む特別なターゲットユニットです。|
|graphical.target|グラフィカルログイン画面を設定するための特別なターゲットユニットです。これはmulti-user.targetを引き込みます。グラフィカルログインに必要なユニットは、インストール中にこのユニット（またはmulti-user.target）へのWants=依存関係を追加する必要があります。これは、ユニットの[Install]セクションのWantedBy=graphical.targetを介して最もよく設定されます。|
|hibernate.target|システムを休止状態にするための特別なターゲットユニットです。これはsleep.targetを引き込みます。|
|hybrid-sleep.target|システムを同時に休止状態とスリープ状態にするための特別なターゲットユニットです。これはsleep.targetを引き込みます。|
|suspend-then-hibernate.target|一定時間システムをスリープ状態にし、目覚めさせて休止状態にするための特別なターゲットユニットです。これはsleep.targetを引き込みます。|
|halt.target|システムをシャットダウンして停止するための特別なターゲットユニットです。このターゲットはpoweroff.targetとは異なり、通常はシステムを停止させるだけで、電源を切るわけではありません。システムを停止させたいアプリケーションは、このユニットを直接起動するのではなく、systemctl halt（オプションで--no-blockを使用）を実行するか、systemd(1)のorg.freedesktop.systemd1.Manager.Halt D-Busメソッドを直接呼び出すべきです。|
|init.scope|このスコープユニットは、システムおよびサービスマネージャー（PID 1）自体が存在する場所です。システムが稼働している限り、このユニットはアクティブです。|
|initrd.target|これはinitramfsのデフォルトターゲットで、メインシステムのdefault.targetに似ています。実際のルートをマウントし、それに移行するために使用されます。詳細についてはbootup(7)を参照してください。|
|initrd-fs.target|systemd-fstab-generator(3)は、sysroot-usr.mountおよび/etc/fstabに見つかるすべてのマウントポイントに対して、x-initrd.mountマウントオプションが設定されており、noautoマウントオプションが設定されていない場合、Before=タイプの依存関係を自動的に追加します。また、sysroot.mountの後に間接的に順序付けられています。したがって、このターゲットに到達すると、/sysroot/階層がホストOSへの移行の準備として完全にセットアップされます。|
|initrd-root-device.target|ルートファイルシステムデバイスが利用可能になったが、まだマウントされていない時点で到達する特別なinitrdターゲットユニットです。systemd-fstab-generator(3)およびsystemd-gpt-auto-generator(3)は、これが実現するように適切な依存関係を自動的に設定します。|
|initrd-root-fs.target|systemd-fstab-generator(3)は、カーネルコマンドラインのroot=設定（または同等のもの）から生成されるsysroot.mountユニットに対して、Before=タイプの依存関係を自動的に追加します。|
|initrd-usr-fs.target|systemd-fstab-generator(3)は、カーネルコマンドラインのusr=スイッチから生成されるsysusr-usr.mountユニットに対して、Before=タイプの依存関係を自動的に追加します。サービスは、初期のルートファイルシステムなしで起動し、/usr/を初期化した後、ルートファイルシステムを設定して最終的に切り替える前にそれにアクセスする必要があるシステムで、/sysusr/階層が利用可能になると実行するために、このターゲットユニットの後に自分自身を順序付けることができます。usr=が使用されないシステムでは、このターゲットはsysroot.mountの後に順序付けられ、ほとんどinitrd-root-fs.targetと同等です。効果的には、このターゲットに到達すると、/usr/をバックアップするファイルシステムはマウントされていますが、/sysusr/または/sysroot/階層の下の2つの異なる場所である可能性があります。|
|kbrequest.target|systemdは、コンソールでAlt+ArrowUpが押されると、このターゲットを開始します。物理的にマシンにアクセスできる任意のユーザーが、認証なしでこれを行うことができるため、慎重に使用する必要があります。|
|kexec.target|kexecを通じてシステムをシャットダウンして再起動するための特別なターゲットユニットです。システムを再起動したいアプリケーションは、このユニットを直接開始するのではなく、systemctl kexec（オプションで--no-blockを使用）を実行するか、systemd(1)のorg.freedesktop.systemd1.Manager.KExec D-Busメソッドを直接呼び出すべきです。|
|local-fs.target|systemd-fstab-generator(3)は、このターゲットユニットに対するローカルマウントポイントを参照するすべてのマウントユニットにBefore=タイプの依存関係を自動的に追加します。さらに、/etc/fstabにリストされているautoマウントオプションが設定されているマウントに対して、このターゲットユニットにWants=タイプの依存関係を追加します。|
|machines.target|すべてのコンテナやその他の仮想マシンを起動するための標準的なターゲットユニットです。`systemd-nspawn@.service` を例として参照してください。|
|multi-user.target|マルチユーザーシステム（非グラフィカル）を設定するための特別なターゲットユニットです。これはgraphical.targetによって引き込まれます。マルチユーザーシステムに必要なユニットは、インストール中にこのユニットに対してWants=依存関係を追加する必要があります。これは、ユニットの[Install]セクションのWantedBy=multi-user.targetを介して最もよく設定されます。|
|network-online.target|設定されたネットワーク接続を厳密に必要とするユニットは、network-online.targetを引き込む必要があります（Wants=タイプの依存関係を介して）し、それに従って順序付けされるべきです。このターゲットユニットは、ネットワークが十分に設定されるまでさらなる実行を遅らせるサービスを引き込むことを意図しています。これが正確に何を必要とするかは、ネットワーク管理サービスの実装に任されています。このユニットとnetwork.targetとの違いに注意してください。このユニットはアクティブユニット（つまり、この機能の消費者によって引き込まれる）であり、さらなる実行にかなりの遅延をもたらす可能性のあるサービスを引き込みます。対照的に、network.targetはパッシブユニット（つまり、この機能の提供者によって引き込まれる）で、通常は実行をあまり遅らせません。通常、network.targetはほとんどのシステムのブートの一部ですが、network-online.targetは少なくとも1つのユニットがそれを必要とする場合を除いてそうではありません。詳細については、Running Services After the Network is up[1]を参照してください。リモートネットワークファイルシステムのすべてのマウントユニットは自動的にこのユニットを引き込み、それに従って順序付けされます。他のホストに機能を提供するだけのネットワーキングデーモン（他のホストの機能を利用するのではなく）は、通常、これを引き込む必要はありません。systemdは、"$network"設備を参照するLSBヘッダーを持つすべてのSysV initスクリプトサービスユニットに対して、このターゲットユニットにWants=およびAfter=タイプの依存関係を自動的に追加します。このユニットは、元のシステム起動ロジック中にのみ役立ちます。システムが起動を完了した後、これはもはやシステムのオンライン状態を追跡しません。このため、ネットワーク接続モニター概念としては使用できず、純粋に一度限りのシステム起動概念です。|
|paths.target|ブート後にアクティブになるすべてのパスユニット（詳細についてはsystemd.path(5)を参照）を設定する特別なターゲットユニットです。アプリケーションによってインストールされたパスユニットは、このユニットからWants=依存関係を介して引き込むことを推奨します。これは、パスユニットの[Install]セクションのWantedBy=paths.targetを介して最もよく設定されます。|
|poweroff.target|システムをシャットダウンして電源を切るための特別なターゲットユニットです。システムの電源を切りたいアプリケーションは、このユニットを直接開始するのではなく、systemctl poweroff（オプションで--no-blockを使用）を実行するか、systemd-logind(8)のorg.freedesktop.login1.Manager.PowerOff D-Busメソッドを直接呼び出すべきです。runlevel0.targetは、SysVとの互換性のためにこのターゲットユニットのエイリアスです。|
|reboot.target|システムをシャットダウンして再起動するための特別なターゲットユニットです。システムを再起動したいアプリケーションは、このユニットを直接開始するのではなく、systemctl reboot（オプションで--no-blockを使用）を実行するか、systemd-logind(8)のorg.freedesktop.login1.Manager.Reboot D-Busメソッドを直接呼び出すべきです。runlevel6.targetは、SysVとの互換性のためにこのターゲットユニットのエイリアスです。|
|remote-cryptsetup.target|cryptsetup.targetに似ていますが、ネットワーク経由でアクセスされる暗号化デバイス用です。_netdevでマークされたcrypttab(8)エントリに使用されます。|
|remote-veritysetup.target|veritysetup.targetに似ていますが、ネットワーク経由でアクセスされる整合性保護されたverityデバイス用です。_netdevでマークされたveritytab(8)エントリに使用されます。|
|remote-fs.target|local-fs.targetに似ていますが、リモートマウントポイント用です。systemdは、"$remote_fs"施設を参照するLSBヘッダーを持つすべてのSysV initスクリプトサービスユニットに対して、このターゲットユニットにAfter=タイプの依存関係を自動的に追加します。|
|rescue.target|基本システム（システムマウントを含む）を引き込み、レスキューシェルを起動する特別なターゲットユニットです。このターゲットで分離して、すべてのファイルシステムがマウントされているが、最も基本的なサービスを除いてサービスが実行されていないシングルユーザーモードでシステムを管理します。emergency.targetと比較してください。これははるかに簡素化されており、ファイルシステムや最も基本的なサービスを提供しません。multi-user.targetと比較すると、このターゲットはsingle-user.targetと見なすことができます。runlevel1.targetは、SysVとの互換性のためにこのターゲットユニットのエイリアスです。このモードでブートするには、カーネルコマンドラインオプション"systemd.unit=rescue.target"を使用します。このカーネルコマンドラインオプションの短いエイリアスは"1"で、SysVとの互換性のためです。|
|runlevel2.target, runlevel3.target, runlevel4.target, runlevel5.target|これらは、SysV互換コードがそれぞれrunlevel 2、3、4、5を要求した場合に呼び出されるターゲットです。これをgraphical.target（runlevel 5の場合）またはmulti-user.target（その他の場合）へのエイリアス（つまりシンボリックリンク）にすることをお勧めします。|
|shutdown.target|システムシャットダウン時にサービスを終了するための特別なターゲットユニットです。システムシャットダウン時に終了するサービスは、Conflicts=およびBefore=依存関係をこのユニットに対してサービスユニットに追加する必要があります。これは、DefaultDependencies=yes（デフォルト）が設定されている場合に暗黙的に行われます。|
|sigpwr.target|systemdがSIGPWRプロセスシグナルを受け取ったときに開始される特別なターゲットで、通常は電源が故障したときにカーネルやUPSデーモンによって送信されます。|
|sleep.target|suspend.target、hibernate.target、およびhybrid-sleep.targetによって引き込まれる特別なターゲットユニットで、スリープ状態ロジックにユニットをフックするために使用される可能性があります。|
|slices.target|ブート後に常にアクティブであるべきすべてのスライスユニット（詳細についてはsystemd.slice(5)を参照）を設定する特別なターゲットユニットです。デフォルトでは、一般的なsystem.sliceスライスユニットおよびルートスライスユニット-.sliceが引き込まれ、このユニットの前に順序付けられています（下記参照）。スライスユニットをslices.targetに追加することは通常必要ありません。代わりに、Slice=を使用するユニットが開始されると、指定されたスライスは自動的に開始されます。WantedBy=slices.target行を[Install]セクションに追加する必要があるのは、常にアクティブである必要があるユニットの場合のみです。その場合、"親"スライスへの自動依存関係を通じてループを作成しないように注意する必要があります。|
|sockets.target|ブート後にアクティブであるべきすべてのソケットユニット（詳細についてはsystemd.socket(5)を参照）を設定する特別なターゲットユニットです。ソケットアクティベーションが可能なサービスは、インストール中にこのユニットに対してソケットユニットのWants=依存関係を追加する必要があります。これは、ソケットユニットの[Install]セクションのWantedBy=sockets.targetを介して最もよく設定されます。|
|suspend.target|システムをスリープ状態にするための特別なターゲットユニットです。これはsleep.targetを引き込みます。|

# さいごに

わすれたくない(半年に1回書いてる)