「Systemd」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(文字列「カスタム .service ファイルを書く」を「ユニットファイル」に置換)
(→‎電源管理: 情報を更新)
 
(6人の利用者による、間の91版が非表示)
1行目: 1行目:
 
{{Lowercase title}}
 
{{Lowercase title}}
[[Category:デーモンとシステムサービス]]
+
[[Category:Init]]
[[Category:ブートプロセス]]
 
[[ar:Systemd]]
 
 
[[de:Systemd]]
 
[[de:Systemd]]
[[fa:Systemd]]
 
[[el:Systemd]]
 
 
[[en:Systemd]]
 
[[en:Systemd]]
 
[[es:Systemd]]
 
[[es:Systemd]]
  +
[[fa:Systemd]]
  +
[[fi:Systemd]]
 
[[fr:Systemd]]
 
[[fr:Systemd]]
[[it:Systemd]]
 
 
[[pt:Systemd]]
 
[[pt:Systemd]]
 
[[ru:Systemd]]
 
[[ru:Systemd]]
 
[[zh-hans:Systemd]]
 
[[zh-hans:Systemd]]
[[zh-hant:Systemd]]
 
 
{{Related articles start}}
 
{{Related articles start}}
 
{{Related|systemd/ユーザー}}
 
{{Related|systemd/ユーザー}}
 
{{Related|systemd/タイマー}}
 
{{Related|systemd/タイマー}}
  +
{{Related|systemd/ジャーナル}}
 
{{Related|systemd FAQ}}
 
{{Related|systemd FAQ}}
 
{{Related|init}}
 
{{Related|init}}
{{Related|init 比較表}}
 
 
{{Related|デーモン#デーモン一覧}}
 
{{Related|デーモン#デーモン一覧}}
 
{{Related|udev}}
 
{{Related|udev}}
{{Related|ブートパフォーマンスの向上}}
+
{{Related|パフォーマンスの向上/ブートプロセス}}
 
{{Related|ユーザーにシャットダウンを許可}}
 
{{Related|ユーザーにシャットダウンを許可}}
 
{{Related articles end}}
 
{{Related articles end}}
   
[http://freedesktop.org/wiki/Software/systemd プロジェクトウェブページ] より:
+
[https://freedesktop.org/wiki/Software/systemd プロジェクトウェブページ] より:
   
 
:'''systemd''' は Linux 環境の基本構成スイートであり、SysV や LSB init スクリプトと互換性のある、Linux 用のシステム・サービスマネージャです。'''systemd''' はサービスの起動を積極的に並行化します。また、ソケットや [[D-Bus]] のアクティベーションを使用してサービスを起動し、必要なデーモンの開始を行うことができ、Linux の [[cgroups]] によるプロセス管理ができます。システム状態のスナップショット作成と復元、(自動) マウントポイントの管理、煩雑な依存関係に基づいたサービスのコントロールを処理します。''systemd'' は sysvinit の代替として SysV や LSB init スクリプトをサポートしています。init としての機能以外にも、ログデーモンやホストネーム・時刻・ロケールなどシステムの基本設定を制御するユーティリティ、ログイン中のユーザーから実行中のコンテナや仮想マシン、システムアカウントまで管理する機能、ネットワーク設定や時刻同期あるいは名前解決などを管理するシンプルなデーモンも含まれています。
 
:'''systemd''' は Linux 環境の基本構成スイートであり、SysV や LSB init スクリプトと互換性のある、Linux 用のシステム・サービスマネージャです。'''systemd''' はサービスの起動を積極的に並行化します。また、ソケットや [[D-Bus]] のアクティベーションを使用してサービスを起動し、必要なデーモンの開始を行うことができ、Linux の [[cgroups]] によるプロセス管理ができます。システム状態のスナップショット作成と復元、(自動) マウントポイントの管理、煩雑な依存関係に基づいたサービスのコントロールを処理します。''systemd'' は sysvinit の代替として SysV や LSB init スクリプトをサポートしています。init としての機能以外にも、ログデーモンやホストネーム・時刻・ロケールなどシステムの基本設定を制御するユーティリティ、ログイン中のユーザーから実行中のコンテナや仮想マシン、システムアカウントまで管理する機能、ネットワーク設定や時刻同期あるいは名前解決などを管理するシンプルなデーモンも含まれています。
  +
  +
歴史的には、systemd が "サービス" と呼ぶものは [[Wikipedia:ja:デーモン (ソフトウェア)|デーモン]] と呼ばれていました:"バックグラウンド" プロセスとして (ターミナルやユーザーインターフェイスなしで) 実行され、一般的にイベントの発生を待ち、サービスを提供するプログラムです。ウェブサーバーがページを配信するリクエストを待ったり、ssh サーバーがログインしようとする人を待ったりするのが良い例です。これらは完全な機能を持つアプリケーションですが、デーモンも存在します。デーモンは、ログファイルにメッセージを書き込んだり (例:{{ic|syslog}}、{{ic|metalog}})、システムの時刻を正確に保つ (例:[[Network Time Protocol daemon|ntpd]]) といったタスクを実行します。詳しくは {{man|7|daemon}} を参照してください。
   
 
{{Note|1=systemd が Arch に採用された理由については、[https://bbs.archlinux.org/viewtopic.php?pid=1149530#p1149530 フォーラムへのこの投稿]をご覧ください。}}
 
{{Note|1=systemd が Arch に採用された理由については、[https://bbs.archlinux.org/viewtopic.php?pid=1149530#p1149530 フォーラムへのこの投稿]をご覧ください。}}
34行目: 32行目:
 
== systemctl の基本的な使い方 ==
 
== systemctl の基本的な使い方 ==
   
''systemd'' を管理したり内部情報を見るために使うメインのコマンドが {{ic|systemctl}} です。システムの状態を確かめたりシステムやサービスを管理するために使うのは使い方の一部です。詳しくは {{ic|man 1 systemctl}} を見て下さい。
+
''systemd'' を管理したり内部情報を見るために使うメインのコマンドが ''systemctl'' です。システムの状態を確かめたりシステムやサービスを管理するために使うのは使い方の一部です。詳しくは {{man|1|systemctl}} を見て下さい。
   
 
{{Tip|
 
{{Tip|
*{{ic|systemctl}} コマンドに {{ic|-H <user>@<host>}} を渡すと、リモートの systemd と対話できます。[[Secure Shell|SSH]] を利用してリモートの systemd インスタンスに繋ぐのに使われます。
+
* ''systemctl'' コマンドに {{ic|-H ''user''@''host''}} を渡すと、リモートの ''systemd'' と対話できます。これは [[Secure Shell|SSH]] を利用してリモートの ''systemd'' インスタンスに接続します。
*{{ic|systemctl}} の公式グラフィカルフロントエンドとして {{ic|systemadm}} が存在します。[[公式リポトリ]]からインストールでき{{Pkg|systemd-ui}}入っています。
+
* [[Plasma]] を使っている場合 {{Pkg|systemdgenie}} をインストールすることで ''systemctl'' のグラフィカルフロントエンドを使えます。ュールをインストール ''System'' の下設定が追加されます。}}
* [[Plasma]] を使っている場合 {{Pkg|systemd-kcm}} をインストールすることで ''systemctl'' のグラフィカルフロントエンドを使えます。モジュールをインストールすると ''System administration'' の下に設定が追加されます。}}
 
 
=== システムの状態を分析する ===
 
 
システムの状態を表示:
 
 
$ systemctl status
 
 
実行中のユニットを一覧する:
 
 
$ systemctl
 
 
または:
 
 
$ systemctl list-units
 
 
失敗したユニットを一覧する:
 
 
$ systemctl --failed
 
 
実行可能なユニットファイルは {{ic|/usr/lib/systemd/system/}} や {{ic|/etc/systemd/system/}} にあります (後者が優先的に使われます)。インストールされたユニットを一覧するには:
 
 
$ systemctl list-unit-files
 
   
 
=== ユニットを使う ===
 
=== ユニットを使う ===
   
ユニットには、例えば、サービス ({{ic|.service}}) やマウントポイント ({{ic|.mount}})、デバイス ({{ic|.device}})、ソケット ({{ic|.socket}}) などがあります。
+
ユニットには、例えば、サービス (''.service'') やマウントポイント (''.mount'')、デバイス (''.device'')、ソケット (''.socket'') などがあります。
   
{{ic|systemctl}} を使とき、一般的には拡張子 (suffix) を含むユニットファイルの完全な名前を指定する必要があります。例えば、{{ic|sshd.socket}} のように。しかし、以下のような場合には省略形が存在します:
+
''systemctl'' を使うとき、例えば {{ic|sshd.socket}} のよ、一般的には拡張子 (suffix) を含むユニットファイルの完全な名前を指定する必要があります。しかし、以下のような場合には省略形が存在します:
   
* 拡張子が指定されない場合、systemctl は {{ic|.service}} とみなします。例えば {{ic|netctl}} と {{ic|netctl.service}} は同じように扱われます。
+
* 拡張子が指定されない場合、systemctl は ''.service'' とみなします。例えば {{ic|netctl}} と {{ic|netctl.service}} は同じように扱われます。
* マウントポイントは自動的に対応する {{ic|.mount}} ユニットとして扱われます。例えば、{{ic|/home}} を指定することは {{ic|home.mount}} の指定と同じです。
+
* マウントポイントは自動的に対応する ''.mount'' ユニットとして扱われます。例えば、{{ic|/home}} を指定することは {{ic|home.mount}} の指定と同じです。
* マウントポイントと同じく、デバイスも自動的に対応する {{ic|.device}} ユニットとして扱われます。従って、{{ic|/dev/sda2}} の指定は {{ic|dev-sda2.device}} と同じです。
+
* マウントポイントと同じく、デバイスも自動的に対応する ''.device'' ユニットとして扱われます。従って、{{ic|/dev/sda2}} の指定は {{ic|dev-sda2.device}} と同じです。
   
詳細は {{ic|man systemd.unit}} を見てください。
+
詳細は {{man|5|systemd.unit}} を見てください。
   
 
{{Note|ユニットによっては名前に {{ic|@}} 記号が含まれていることがあります (例: {{ic|name@''string''.service}}): これは、そのサービスが''テンプレート''ユニットの [http://0pointer.de/blog/projects/instances.html インスタンス] であることを意味しており、テンプレートユニットのファイル名には {{ic|''string''}} の部分が含まれていません (例: {{ic|name@.service}})。{{ic|''string''}} は ''instance identifier'' と呼ばれ、''systemctl'' コマンドでテンプレートユニットを実行するときに指定する引数と似ています: ユニットファイルの中の {{ic|%i}} が置き換えられます。
 
{{Note|ユニットによっては名前に {{ic|@}} 記号が含まれていることがあります (例: {{ic|name@''string''.service}}): これは、そのサービスが''テンプレート''ユニットの [http://0pointer.de/blog/projects/instances.html インスタンス] であることを意味しており、テンプレートユニットのファイル名には {{ic|''string''}} の部分が含まれていません (例: {{ic|name@.service}})。{{ic|''string''}} は ''instance identifier'' と呼ばれ、''systemctl'' コマンドでテンプレートユニットを実行するときに指定する引数と似ています: ユニットファイルの中の {{ic|%i}} が置き換えられます。
   
正確に言うと、{{ic|name@.suffix}} テンプレートユニットのインスタンスを作成する''前に''、''systemd'' は {{ic|name@string.suffix}} というファイル名のユニットが存在しないか確認します。ただし名前の"衝突"が発生するのは極めて稀で、{{ic|@}} 記号を含むユニットファイルは大抵テンプレートです。そういう決まりです。また、テンプレートユニットが instance identifier を付けられずに呼ばれたときは、{{ic|%i}} が置き換えられないため実行失敗になります。}}
+
正確に言うと、{{ic|name@.suffix}} テンプレートユニットのインスタンスを作成する''前に''、''systemd'' は {{ic|name@string.suffix}} というファイル名のユニットが存在しないか確認します。ただし名前の"衝突"が発生するのは極めて稀で、{{ic|@}} 記号を含むユニットファイルは大抵テンプレートです。そういう決まりです。また、テンプレートユニットが instance identifier を付けられずに呼ばれたときは、{{ic|%i}} が置き換えられないため実行失敗になります ({{ic|cat}} のような特定の ''systemctl'' コマンドを除く)。}}
  +
  +
以下の表のコマンドは、''systemctl'' の暗黙のデフォルトである {{ic|--system}} から、'''system unit''' を操作するものです。代わりに、'''ユーザー単位''' で操作するには、root 権限なしで [[systemctl --user]] を使ってください。全てのユーザーに対してユーザーユニットを有効・無効にするには [[systemd/ユーザー#基本設定]] も見て下さい。
   
 
{{Tip|
 
{{Tip|
* 以下のコマンドのほとんどは複数のユニットを指定することが可能です、詳しくは {{ic|man systemctl}} を参照。
+
* 以下のコマンドのほとんどは複数のユニットを指定することが可能です、詳しくは {{man|1|systemctl}} を参照。
  +
* {{ic|--now}} スイッチは {{ic|enable}}, {{ic|disable}}, {{ic|mask}} と一緒に使うことで、それぞれ起動、停止、マスクをリブート後ではなく即座に行うことができます。
 
* パッケージには様々な目的のユニットが入っています。パッケージをインストールしたら、{{ic|pacman -Qql ''package'' <nowiki>|</nowiki> grep -Fe .service -e .socket}} でサービスを確認することができます。
 
* パッケージには様々な目的のユニットが入っています。パッケージをインストールしたら、{{ic|pacman -Qql ''package'' <nowiki>|</nowiki> grep -Fe .service -e .socket}} でサービスを確認することができます。
 
}}
 
}}
   
  +
{| class="wikitable"
いますぐユニットを実行:
 
  +
! アクション || コマンド || 注意
  +
|-
  +
! colspan="3" | システム状態の分析
  +
|-
  +
| '''システムステータスを表示する''' || {{ic|systemctl status}} ||
  +
|-
  +
| '''実行中のユニット''' リスト || {{ic|systemctl}} or<br>{{ic|systemctl list-units}} ||
  +
|-
  +
| '''失敗したユニット''' 一覧 || {{ic|systemctl --failed}} ||
  +
|-
  +
| '''インストールされているユニット''' 一覧<sup>1</sup> || {{ic|systemctl list-unit-files}} ||
  +
|-
  +
| '''PID のプロセスステータス''' を表示 || {{ic|systemctl status ''pid''}} || [[cgroups|cgroup slice]], メモリ と 上位プロセス
  +
|-
  +
! colspan="3" | ユニットの状態を確認する
  +
|-
  +
| ユニットに関連付けられている '''マニュアルページを表示する''' || {{ic|systemctl help ''unit''}} || ユニットでサポートされています
  +
|-
  +
| ユニットの '''ステータス''' || {{ic|systemctl status ''unit''}} || 実行されているかどうかを含む
  +
|-
  +
| ユニットが有効かどうかを '''チェック''' する || {{ic|systemctl is-enabled ''unit''}} ||
  +
|-
  +
! colspan="3" | 本体の起動、再起動、再読み込み
  +
|-
  +
| ユニットを即座に '''スタート''' する || {{ic|systemctl start ''unit''}} as root ||
  +
|-
  +
| ユニットを即座に '''ストップ''' する || {{ic|systemctl stop ''unit''}} as root ||
  +
|-
  +
| ユニットを '''再起動''' する || {{ic|systemctl restart ''unit''}} as root ||
  +
|-
  +
| ユニットとその設定を '''再読み込み''' する || {{ic|systemctl reload ''unit''}} as root ||
  +
|-
  +
| '''systemd マネージャーの再読み込み''' 設定<sup>2</sup> || {{ic|systemctl daemon-reload}} as root || ユニットスキャン
  +
|-
  +
! colspan="3" | ユニットの有効化
  +
|-
  +
| ブート時に自動的に起動するユニットを '''有効''' にする || {{ic|systemctl enable ''unit''}} as root ||
  +
|-
  +
| 起動時に自動起動するユニットを '''有効''' にして、すぐに '''起動''' する || {{ic|systemctl enable --now ''unit''}} as root ||
  +
|-
  +
| '''無効''' にすると、ブート時に起動しなくなります || {{ic|systemctl disable ''unit''}} as root ||
  +
|-
  +
| ユニット<sup>3</sup>を ''再有効化'' する || {{ic|systemctl reenable ''unit''}} as root || つまり、無効化して新たに有効化する
  +
|-
  +
! colspan="3" | ユニットのマスキング
  +
|-
  +
| '''mask''' して起動不能にするユニット<sup>4</sup> || {{ic|systemctl mask ''unit''}} as root ||
  +
|-
  +
| '''unmask''' ユニット || {{ic|systemctl unmask ''unit''}} as root ||
  +
|}
   
  +
# 利用可能なユニットファイルがあるディレクトリは {{man|5|systemd.unit|UNIT FILE LOAD PATH}} を参照してください。
# systemctl start ''unit''
 
  +
# これは変更されたユニットに設定の再読み込みを要求しません (アクション '''Reload''' を参照して下さい)。
 
  +
# 例えば、最後に有効化してからその {{ic|[Install]}} セクションが変更された場合。
いますぐユニットを停止:
 
  +
# 手動でも依存関係としても、マスクは危険です。既存のマスクされたユニットをチェックします。{{bc|1=$ systemctl list-unit-files --state=masked}}
 
# systemctl stop ''unit''
 
 
ユニットを再始動:
 
 
# systemctl restart ''unit''
 
 
ユニットに設定を再読み込みするように通知:
 
 
# systemctl reload ''unit''
 
 
ユニットの状態を表示(動いているかどうかなど):
 
 
$ systemctl status ''unit''
 
 
有効化(起動時に自動で実行するよう設定)されているかどうか表示:
 
 
$ systemctl is-enabled ''unit''
 
 
起動時に実行されるように有効化する:
 
 
# systemctl enable ''unit''
 
 
システム起動時に実行されないように無効化する:
 
 
# systemctl disable ''unit''
 
 
ユニットをマスクすることで起動しないようにできます:
 
 
# systemctl mask ''unit''
 
 
ユニットのマスクを解除:
 
 
# systemctl unmask ''unit''
 
 
ユニットに関連する(ユニットファイルによってサポートされている)マニュアルページを参照する:
 
 
$ systemctl help ''unit''
 
 
systemd をリロードし、新しい、もしくは変化のあったユニットをスキャンする:
 
 
# systemctl daemon-reload
 
 
{{Tip|[https://github.com/systemd/systemd/blob/master/NEWS#L323-L326 systemd 220] から、{{ic|--now}} スイッチを使うことで {{ic|enable}} で指定したユニットをすぐに起動して、{{ic|disable}} や {{ic|mask}} したユニットを停止できるようになりました。}}
 
   
 
=== 電源管理 ===
 
=== 電源管理 ===
   
  +
非特権ユーザーでの電源管理には、[[polkit]] が必要です。ローカルの ''systemd-logind'' ユーザーセッションで、他のセッションがアクティブでない場合、以下のコマンドは root 権限がなくても動作します。そうでない場合(例えば、他のユーザーが tty にログインしているなど)、''systemd'' は自動的に root パスワードを要求します。
電源管理には {{ic|polkit}} が必要です。
 
ローカルの {{ic|systemd-logind}} のユーザーセッション中で、他のセッションがアクティブでなければ、ルート権限なしで以下のコマンドが使えます。そうでなければ (他のユーザが tty でログインしている場合など)、systemd は自動的に root のパスワードを要求するでしょう。
 
   
  +
{| class="wikitable"
再起動:
 
  +
! アクション || コマンド
 
  +
|-
$ systemctl reboot
 
  +
| システムをシャットダウンして再起動する || {{ic|systemctl reboot}}
 
  +
|-
シャットダウンしてパワーオフ:
 
  +
| システムをシャットダウンして電源を切る || {{ic|systemctl poweroff}}
 
  +
|-
$ systemctl poweroff
 
  +
| システムを一時停止する || {{ic|systemctl suspend}}
 
  +
|-
サスペンド(待機):
 
  +
| システムをハイバネーションにする || {{ic|systemctl hibernate}}
 
  +
|-
$ systemctl suspend
 
  +
| システムをハイブリッドスリープ状態にする (または suspend-to-both) にする || {{ic|systemctl hybrid-sleep}}
 
  +
|-
ハイバネート(休止):
 
  +
| まずシステムをサスペンドし、設定された時間の経過後にウェイクアップしてシステムを休止状態にする || {{ic|systemctl suspend-then-hibernate}}
 
  +
|-
$ systemctl hibernate
 
  +
|}
 
ハイブリッドスリープ (もしくは suspend-to-both):
 
 
$ systemctl hybrid-sleep
 
   
 
== ユニットファイル ==
 
== ユニットファイル ==
   
systemd の [http://www.freedesktop.org/software/systemd/man/systemd.unit.html ユニットファイル] の構文は XDG の Desktop Entry Specification である ''.desktop'' から影響を受けています。そして ''.desktop'' は Microsoft Windows の ''.ini'' ファイルからインスパイアされています。ユニットファイルは2つの場所に配置されます優先度が低い方から説明すると:
+
systemd のユニットファイル ({{man|5|systemd.unit}}) の構文は [[デスクトップエントリ|XDG の Desktop Entry Specification である .desktop ファイル]] から影響を受けています。そして ''.desktop'' は [[Wikipedia:ja:INIファイル|Microsoft Windows の .ini ファイル]] からインスパイアされています。ユニットファイルは複数の場所に配置されます (配置場所のリストを確認するには {{ic|1=systemctl show --property=UnitPath}} を実行してください)が、主な場所は (優先度が低い方から説明すると):
   
 
* {{ic|/usr/lib/systemd/system/}}: インストールしたパッケージに含まれているユニット
 
* {{ic|/usr/lib/systemd/system/}}: インストールしたパッケージに含まれているユニット
168行目: 149行目:
 
{{Note|
 
{{Note|
 
*[[systemd/ユーザー|ユーザーモード]]で ''systemd'' を動作させたときにロードされるパスは完全に異なります。
 
*[[systemd/ユーザー|ユーザーモード]]で ''systemd'' を動作させたときにロードされるパスは完全に異なります。
*systemd ユニットの名前に使うことができるのは ASCII 英数字とアンダーバー、ピリオドだけです。他の文字列は "\x2d" エスケープに置き換える必要があります。詳しくは {{ic|man systemd.unit}} や {{ic|man systemd-escape}} を見て下さい。
+
*systemd ユニットの名前に使うことができるのは ASCII 英数字とアンダーバー、ピリオドだけです。他の文字列は C スタイルの "\x2d" エスケープに置き換えるか、事前に定義された方法 ('@' や '-') を使う必要があります。詳しくは {{man|5|systemd.unit}} や {{man|1|systemd-escape}} を見て下さい。
 
}}
 
}}
  +
  +
例としてパッケージによりインストールされたユニットや {{man|5|systemd.service|EXAMPLES}} を参照してください。
  +
  +
{{Tip|{{ic|#}} で始まるコメントはユニットファイルでも使うことができますが、行頭でのみ有効です。''systemd'' のパラメータの後で行末のコメントを使わないでください。ユニットの有効化が失敗する原因となります。}}
   
 
=== 依存関係を解決する ===
 
=== 依存関係を解決する ===
   
systemd ではユニットファイルを適切に書くことで依存関係を解決します。一番典型的なケースは、ユニット {{ic|A}} が走る前に、ユニット {{ic|A}} がユニット {{ic|B}} を必要としている場合です。この場合、{{ic|A}} の {{ic|[Unit]}} セクションに {{ic|1=Requires=B}} と {{ic|1=After=B}} を加えます。依存が必然ではない場合、代わりに {{ic|1=Wants=B}} と {{ic|1=After=B}} を加えます。{{ic|1=Wants=}} と {{ic|1=Requires=}} は {{ic|1=After=}} を含まないことに注意してください、もし {{ic|1=After=}} を明記しなかったときは、つのユニットは並行して実行されます。
+
systemd ではユニットファイルを適切に書くことで依存関係を解決します。一番典型的なケースは、ユニット {{ic|A}} が走る前に、ユニット {{ic|A}} がユニット {{ic|B}} を必要としている場合です。この場合、{{ic|A}} の {{ic|[Unit]}} セクションに {{ic|1=Requires=B}} と {{ic|1=After=B}} を加えます。依存が必然ではない場合、代わりに {{ic|1=Wants=B}} と {{ic|1=After=B}} を加えます。{{ic|1=Wants=}} と {{ic|1=Requires=}} は {{ic|1=After=}} を含まないことに注意してください、もし {{ic|1=After=}} を明記しなかったときは、2つのユニットは並行して実行されます。
   
 
基本的に、依存関係は[[#ターゲット|ターゲット]]ではなくサービスに記述します。例えば、{{ic|network.target}} はネットワークインターフェースを設定する全てのサービスによって使われるので、カスタムユニットを起動させる順番は {{ic|network.target}} が起動し終わってからにする必要があります。
 
基本的に、依存関係は[[#ターゲット|ターゲット]]ではなくサービスに記述します。例えば、{{ic|network.target}} はネットワークインターフェースを設定する全てのサービスによって使われるので、カスタムユニットを起動させる順番は {{ic|network.target}} が起動し終わってからにする必要があります。
   
=== タイプ ===
+
=== サービスタイプ ===
   
カスタムサービスファイルを書くときにどのスタートアップタイプを使うべきか考える必要があります。タイプは {{ic|[Service]}} セクションの {{ic|1=Type=}} パラメータで設定します。より詳しい説明は {{ic|man systemd.service}} を見て下さい
+
カスタムサービスファイルを書くときにどのスタートアップタイプを使うべきか考える必要があります。タイプは {{ic|[Service]}} セクションの {{ic|1=Type=}} パラメータで設定します。
   
* {{ic|1=Type=simple}} (デフォルト): systemd はプロセスを起動した時点でサービスが立ち上がったとみなします。プロセスをフォークすることはできません。ソケットアクティベーション以外で他のサービスが必要な場合に、このタイプを使ってはいけません。
+
* {{ic|1=Type=simple}} (デフォルト): ''systemd'' はプロセスを起動した時点でサービスが立ち上がったとみなします。プロセスをフォークすることはできません。ソケットアクティベーション以外で他のサービスが必要な場合に、このタイプを使ってはいけません。
* {{ic|1=Type=forking}}: 起動したプロセスが一旦フォークし、親プロセス側が終了したときに、 systemd はサービスが立ち上がったとみなします。このタイプでなくてもかまわないとき以外は、古典的なデーモンにはこのタイプを使って下さい。また {{ic|1=PIDFile=}} を指定することで systemd はメインプロセスの情報を追い続けます。
+
* {{ic|1=Type=forking}}: 起動したプロセスが一旦フォークし、親プロセス側が終了したときに、 ''systemd'' はサービスが立ち上がったとみなします。このタイプでなくてもかまわないとき以外は、古典的なデーモンにはこのタイプを使って下さい。また {{ic|1=PIDFile=}} を指定することで ''systemd'' はメインプロセスの情報を追い続けます。
* {{ic|1=Type=oneshot}}: シングルジョブを行い終了するスクリプト用のタイプです。また {{ic|1=RemainAfterExit=yes}} を設定することで systemd はプロセスが終了した後もサービスがアクティブだとみなします。
+
* {{ic|1=Type=oneshot}}: シングルジョブを行い終了するスクリプト用のタイプです。また {{ic|1=RemainAfterExit=yes}} を設定することで ''systemd'' はプロセスが終了した後もサービスがアクティブだとみなします。
* {{ic|1=Type=notify}}: {{ic|1=Type=simple}} と同じですが、利用可能になったときにデーモンが systemd に信号を送るように条件がつけられます。この通知のリファレンス実装は {{ic|libsystemd-daemon.so}} によって提供されています。
+
* {{ic|1=Type=notify}}: {{ic|1=Type=simple}} と同じですが、利用可能になったときにデーモンが ''systemd'' に信号を送るように条件がつけられます。この通知のリファレンス実装は ''libsystemd-daemon.so'' によって提供されています。
 
* {{ic|1=Type=dbus}}: 指定の {{ic|BusName}} が DBus のシステムバスに乗ったときに使うことができるサービス。
 
* {{ic|1=Type=dbus}}: 指定の {{ic|BusName}} が DBus のシステムバスに乗ったときに使うことができるサービス。
* {{ic|1=Type=idle}}: idle の挙動は {{ic|1=Type=simple}} と非常に似ています。ただし、サービスバイナリの実行は全てのジョブが処理されるまで待たされます。を使えば、コンソール状態を出力するシェルサービスで、出力が混じっしまうのを避けることができます。
+
* {{ic|1=Type=idle}}: ただし、サービスバイナリの実行は全てのジョブが処理されるまで待たされます。以外の挙動は {{ic|1=Type=simple}} と非常ます。
  +
  +
{{ic|Type}} の値のより詳しい説明は {{man|5|systemd.service|OPTIONS}} を見て下さい。
   
 
=== ユニットファイルの編集 ===
 
=== ユニットファイルの編集 ===
   
パッケージに入っているユニットファイルを編集する方法は2つあります: 新しいユニットファイルで完全に置き換えるか、ドロップインファイルを作成して既存のユニットファイルに上書きして適用させるかです。どちらの方法でも、変更を加えた後はユニットをリロードする必要があります。{{ic|systemctl edit}} でユニットを編集するか (自動でユニットがリロードされます) または次のコマンドで全てのユニットをリロードしてください:
+
pacman との競合を避けるために、パッケージに含まれるユニットファイルは直接編集しないでください。パッケージに入っているユニットファイルを元のファイルに触れずに編集する安全な方法は2つあります: 新しいユニットファイルで[[#ユニットファイルを置換する|完全に置き換える]]か、[[#ドロップインファイル|ドロップインファイル]]を作成して既存のユニットファイルに上書きして適用させるかです。どちらの方法でも、変更を加えた後はユニットをリロードする必要があります。{{ic|systemctl edit}} でユニットを編集するか (自動でユニットがリロードされます) または次のコマンドで全てのユニットをリロードしてください:
   
 
# systemctl daemon-reload
 
# systemctl daemon-reload
197行目: 184行目:
 
* {{ic|systemd-delta}} を使うことでどのファイルが上書きされ、どこが変更されたのか調べることができます。
 
* {{ic|systemd-delta}} を使うことでどのファイルが上書きされ、どこが変更されたのか調べることができます。
 
* ユニットファイルや関連するドロップインファイルの中身を見るには {{ic|systemctl cat ''unit''}} を使います。
 
* ユニットファイルや関連するドロップインファイルの中身を見るには {{ic|systemctl cat ''unit''}} を使います。
* [[公式リポジトリ]]から {{Pkg|vim-systemd}} をインストールすることで、[[Vim]] で ''systemd'' ユニットファイルのシンタックスハイライトが可能です。
 
 
}}
 
}}
   
 
==== ユニットファイルを置換する ====
 
==== ユニットファイルを置換する ====
   
ユニットファイル {{ic|/usr/lib/systemd/system/''unit''}} を置き換えたいときは、{{ic|/etc/systemd/system/''unit''}} ファイルを作成してユニットを再有効することでシンボリックリンクをアップデートします:
+
ユニットファイル {{ic|/usr/lib/systemd/system/''unit''}} を置き換えたいときは、{{ic|/etc/systemd/system/''unit''}} ファイルを作成してユニットを [[#ユニットを使う|再有効化]] することでシンボリックリンクをアップデートします
 
# systemctl reenable ''unit''
 
   
 
もしくは、次を実行:
 
もしくは、次を実行:
234行目: 218行目:
 
例えば、ユニットに依存するデーモンを追加したい場合、以下のファイルを作成することができます:
 
例えば、ユニットに依存するデーモンを追加したい場合、以下のファイルを作成することができます:
   
{{hc|/etc/systemd/system/<unit>.d/customdependency.conf|2=
+
{{hc|/etc/systemd/system/''unit''.d/customdependency.conf|2=
 
[Unit]
 
[Unit]
Requires=<new dependency>
+
Requires=''new dependency''
After=<new dependency>}}
+
After=''new dependency''}}
   
 
{{ic|oneshot}} タイプでないユニットの {{ic|ExecStart}} ディレクティブを置き換えるには、以下のファイルを作成します:
 
{{ic|oneshot}} タイプでないユニットの {{ic|ExecStart}} ディレクティブを置き換えるには、以下のファイルを作成します:
257行目: 241行目:
 
== ターゲット ==
 
== ターゲット ==
   
Systemd ではランレベルに似たものとして''ターゲット''を使っています。ただしその挙動には少し違いがあります。それぞれの''ターゲット''はナンバリングされる代わりに名前がつけられ、ある特定の目的のために作られ、複数のターゲットを同時に有効にできるようになっています。''ターゲット''によっては、他の''ターゲット''のサービスを全て引継ぎ、そこにサービスを追加するよう実装されています。一般的な SystemVinit ランレベルに擬態する systemd ''ターゲット''もあり、親しみのある {{ic|telinit RUNLEVEL}} コマンドを使って使用する''ターゲット''を切り替えることが可能です。
+
Systemd では [[Wikipedia:ja:ランレベル|ランレベル]] に似たものとして''ターゲット''を使っています。ただしその挙動には少し違いがあります。それぞれの''ターゲット''はナンバリングされる代わりに名前がつけられ、ある特定の目的のために作られ、複数のターゲットを同時に有効にできるようになっています。''ターゲット''によっては、他の''ターゲット''のサービスを全て引継ぎ、そこにサービスを追加するよう実装されています。一般的な SystemVinit ランレベルに擬態する systemd ''ターゲット''もあり、親しみのある {{ic|telinit RUNLEVEL}} コマンドを使って使用する''ターゲット''を切り替えることが可能です。
   
=== 現在のターゲットを得 ===
+
=== 現在のターゲットを得 ===
   
systemd では {{ic|runlevel}} の代わりに次のコマンドが使われます:
+
''systemd'' では {{ic|runlevel}} の代わりに次のコマンドが使われます:
   
 
$ systemctl list-units --type=target
 
$ systemctl list-units --type=target
267行目: 251行目:
 
=== カスタムターゲットを作る ===
 
=== カスタムターゲットを作る ===
   
標準の Fedora インストールではランレベルごとに特定の目的が設定されています; 0, 1, 3, 5, 6 のランレベルには特定の sytemd ''ターゲット''と一対一の対応関係が存在します。残念ながら、ユーザー定義のランレベル (2 や 4 など) で同じことをする良い方法はありません。もしあなたがそうしたいならば、既に存在しているランレベルをベースに新しい systemd ''ターゲット''を {{ic|/etc/systemd/system/<your target>}} として作り ({{ic|/usr/lib/systemd/system/graphical.target}} がサンプルになるかもしれません)、{{ic|/etc/systemd/system/<your target>.wants}} ディレクトリを作って、有効にしたいサービスに {{ic|/usr/lib/systemd/system/}} からシンボリックリンクを貼ることが示唆されています。
+
sysvinit ではランレベルごとに特定の目的が設定されています; 0, 1, 3, 5, 6 のランレベルには特定の sytemd ''ターゲット''と一対一の対応関係が存在します。残念ながら、ユーザー定義のランレベル (2 や 4 など) で同じことをする良い方法はありません。もしあなたがそうしたいならば、既に存在しているランレベルをベースに新しい systemd ''ターゲット''を {{ic|/etc/systemd/system/''your target''}} として作り ({{ic|/usr/lib/systemd/system/graphical.target}} がサンプルになるかもしれません)、{{ic|/etc/systemd/system/''your target''.wants}} ディレクトリを作って、有効にしたいサービスに {{ic|/usr/lib/systemd/system/}} からシンボリックリンクを貼ることが示唆されています。
   
 
=== SysV ランレベルと systemd ターゲットの対応表 ===
 
=== SysV ランレベルと systemd ターゲットの対応表 ===
292行目: 276行目:
 
=== 現在のターゲットを変更する ===
 
=== 現在のターゲットを変更する ===
   
systemd ではターゲットは"ターゲットユニット"を通して扱うことができます。ターゲットを変えるには次のようにします:
+
''systemd'' ではターゲットは ''ターゲットユニット'' を通して扱うことができます。ターゲットを変えるには次のようにします:
   
 
# systemctl isolate graphical.target
 
# systemctl isolate graphical.target
   
これは現在のターゲットを変えるだけで、次の起動時には影響がありません。[[SysVinit]] での、{{ic|telinit 3}} や {{ic|telinit 5}} のようなコマンドと同じです。
+
これは現在のターゲットを変えるだけで、次の起動時には影響がありません。SysVinit での、{{ic|telinit 3}} や {{ic|telinit 5}} のようなコマンドと同じです。
   
=== 起動時のデフォルトターゲットを変更する ===
+
=== 起動するデフォルトターゲットを変更 ===
   
標準のターゲットは {{ic|default.target}} で、デフォルトで (昔のランレベル 5 に大体対応している) {{ic|graphical.target}} にエイアスされています。起動時のデフォルトターゲットを変更するには、以下の[[カーネパラメータ]]のどれかをブートローダ加えてください:
+
標準のターゲットは {{ic|default.target}} で、これは {{ic|graphical.target}} へのシンボックリンクです。これは、古いランレベ5ほぼ対応します。
   
  +
''systemctl'' を使用して現在のターゲットを確認するには、次の手順に従います。
{{Tip|{{ic|.target}} 拡張子は省くことができます。}}
 
   
  +
$ systemctl get-default
* {{ic|1=systemd.unit=multi-user.target}} (昔のランレベル 3 とほぼ同じ)。
 
* {{ic|1=systemd.unit=rescue.target}} (昔のランレベル 1 とほぼ同じ)。
 
   
また、ブートには修正を加えずに {{ic|default.target}} を変えることもできます。{{ic|systemctl}} を使います:
+
ブート先のデフォルトタゲットを変更するには{{ic|default.target}} シンボリックリンクを変更します。''systemctl'' の場合
   
# systemctl set-default multi-user.target
+
{{hc|1=# systemctl set-default multi-user.target|2=
  +
Removed /etc/systemd/system/default.target.
  +
Created symlink /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target.}}
   
  +
または、次の [[カーネルパラメータ]] のいずれかをブートローダに追加します。
以前に設定した ''default.target'' を上書きできるようにするには、force オプションを使って下さい:
 
   
  +
* {{ic|1=systemd.unit=multi-user.target}} (これは、古いランレベル3にほぼ対応しています)
# systemctl set-default -f multi-user.target
 
  +
* {{ic|1=systemd.unit=rescue.target}} (これは、古いランレベル1にほぼ対応しています)
   
  +
=== デフォルトのターゲット順序 ===
このコマンドの効果は {{ic|systemctl}} によって出力されます; 新しいデフォルトターゲットのシンボリックリンクは {{ic|/etc/systemd/system/default.target}} に作成されます。
 
   
  +
''systemd'' は、次の順序に従って {{ic|default.target}} を選択します。
== 一時ファイル ==
 
   
  +
# 上記のカーネルパラメータ
Systemd-tmpfiles は {{ic|/usr/lib/tmpfiles.d/}} と {{ic|/etc/tmpfiles.d/}} 下にある設定ファイルを読み、通常 {{ic|/run}} や {{ic|/tmp}} などのディレクトリに存在している一時ファイル・ディレクトリの作成、内容の消去、削除などを行います。それぞれの設定ファイル名は {{ic|/etc/tmpfiles.d/<program>.conf}} です。{{ic|/usr/lib/tmpfiles.d/}} に同名の設定ファイルがある場合上書きされます。
 
  +
# {{ic|/etc/systemd/system/default.target}} への Symlink
  +
# {{ic|/usr/lib/systemd/system/default.target}} への Symlink
   
  +
== systemd の構成要素 ==
tmpfiles は一時ファイルを必要とするデーモンのサービスファイルに同梱されます。例えば [[Samba]] デーモンは {{ic|/run/samba}} を一時ディレクトリとして使用するため、正しいパーミッションに設定されていることを期待します。これを表す tmpfile は以下のようになります:
 
   
  +
''systemd'' のコンポーネントをいくつか(網羅的ではない)紹介します。
{{hc|/usr/lib/tmpfiles.d/samba.conf|
 
D /run/samba 0755 root root}}
 
   
  +
* [[systemd-boot]] — シンプルな UEFI [[Arch ブートプロセス|ブートマネージャー]] です。
tmpfiles は起動時にファイルに値を書き込むのにも使われることがあります。例えば、{{ic|/etc/rc.local}} を使って USB デバイスからの wakeup を無効化する {{ic|echo USBE > /proc/acpi/wakeup}} は、tmpfile では以下のように書けます:
 
  +
* {{man|1|systemd-cryptenroll}} — LUKS2 で暗号化されたボリュームに PKCS#11、FIDO2、TPM2 トークン/デバイスを登録します。
  +
* [[systemd-firstboot]] — 最初のブートの前に基本的なシステム設定を初期化します。
  +
* [[systemd-homed]] — ポータブルな人間のユーザー [[ユーザーとグループ|アカウント]] です。
  +
* {{man|8|systemd-logind}} — [https://dvdhrm.wordpress.com/2013/08/24/session-management-on-linux/ セッション管理]
  +
* [[systemd-networkd]] — [[ネットワーク設定]] 管理。
  +
* [[systemd-nspawn]] — 軽量なネームスペースコンテナ。
  +
* [[systemd-resolved]] — ネットワークの [[ドメイン名前解決|名前解決]]
  +
* {{man|8|systemd-sysusers}} — パッケージのインストール時または起動時に、システムユーザーとグループを作成し、ユーザーをグループに追加します。
  +
* [[systemd-timesyncd]] — ネットワーク上で [[時刻|システム時刻]] を同期します。
  +
* [[systemd/ジャーナル]] — システムのログを記録します。
  +
* [[systemd/タイマー]] — ファイルやイベントを制御するための単調またはリアルタイムのタイマー ''.service'' [[cron]] の代替。
  +
* {{man|7|systemd-stub}} — [https://wiki.archlinux.org/title/Unified_kernel_image Unified カーネルイメージ] を作成するために使用される UEFI ブートスタブです。
   
  +
=== systemd.mount - マウント ===
{{hc|/etc/tmpfiles.d/disable-usb-wake.conf|
 
w /proc/acpi/wakeup - - - - USBE}}
 
   
  +
''systemd'' は {{ic|/etc/fstab}} で指定されたパーティションとファイルシステムのマウントを担当します。{{man|8|systemd-fstab-generator}} は {{ic|/etc/fstab}} の全てのエントリを ''systemd'' ユニットに変換します; これは起動時とシステムマネージャの設定が再ロードされた時に実行されます。
詳細は {{ic|systemd-tmpfiles(8)}} や {{ic|tmpfiles.d(5)}} の man ページを参照してください。
 
   
  +
''systemd'' は通常の [[fstab]] 機能を拡張し、追加のマウントオプションを提供します。これらのオプションはマウントユニットの依存関係に影響を与えます。例えば、ネットワークが立ち上がった時だけマウントするようにしたり、他のパーティションがマウントされた時だけマウントするようにすることができます。特定の ''systemd'' マウントオプションの完全なリストは、通常 {{ic|x-systemd.}} で始まり、 {{man|5|systemd.mount|FSTAB}} で詳細に説明されています。
{{Note|''systemd-tmpfiles-setup'' サービスは適切なモジュールがロードされる前に実行されることがあるので、{{ic|/sys}} にオプションを設定するのにこの方法は使えません。このため設定したいオプションのパラメータをモジュールが持っているか確認するには {{ic|modinfo ''module''}} を使い、オプションを設定は [[カーネルモジュール#設定|/etc/modprobe.d 下の設定ファイル]]を使って下さい。もしくはデバイスが現れたときにすぐ適切な属性を設定する [[Udev#udev ルールについて|udev ルール]]を書いて下さい。}}
 
   
  +
これらのマウントオプションの例として、''自動マウント''があります。これは、ブート時に自動的にマウントするのではなく、リソースが必要な時にだけマウントすることを意味します。これは [[fstab#systemd による自動マウント]] で提供されています。
== タイマー ==
 
   
  +
==== GPT パーティションの自動マウント ====
タイマーは ".timer" で終わる名前を持つユニット設定ファイルで、時間に基づく実行を行うために、''systemd'' で制御・管理するタイマーの情報をエンコードしています。[[systemd/タイマー]] を参照してください。
 
   
  +
UEFI で起動したシステムでは、特定の条件が満たされると {{man|8|systemd-gpt-auto-generator}} は [https://systemd.io/DISCOVERABLE_PARTITIONS/ Discoverable Partitions Specification] に従って GPT パーティションを自動マウントし、[[fstab]] から省略することができるようになります。
{{Note|タイマーは cron の機能をほぼ全て置き換えることができます。詳しくは、[[systemd/タイマー#cron を置き換える]] を参照してください。}}
 
   
  +
前提条件は以下の通りです。
== マウント ==
 
   
  +
* ブートローダは [https://systemd.io/BOOT_LOADER_INTERFACE/ LoaderDevicePartUUID] EFI 変数を設定し、使用する EFI システムパーティションが特定できるようにする必要があります。これは [[systemd-boot]], {{man|7|systemd-stub}} と [[rEFInd#LoaderDevicePartUUID|rEFInd (not enabled by default)]] でサポートされています。これは {{ic|bootctl}} を実行して {{ic|Boot loader sets ESP information}} の状態をチェックすることによって確認できます。
systemd は System V init を置き換えるため、{{ic|/etc/fstab}} に指定されたマウントも処理します。{{ic|fstab}} の通常機能だけでなく、{{ic|x-systemd.}} が前に付く特殊なマウントオプションを利用することが可能です。拡張機能を使用する具体的な例として [[Fstab#systemd による自動マウント]] には必要に応じて自動マウントする方法が書かれています。拡張機能のドキュメントは [https://www.freedesktop.org/software/systemd/man/systemd.mount.html#fstab] を参照してください。
 
  +
* ルートパーティションは、使用する EFI システムパーティションと同じ物理ディスク上になければなりません。自動マウントされる他のパーティションは、ルートパーティションと同じ物理ディスク上になければなりません。これは基本的に、オートマウントされる全てのパーティションは ESP と同じ物理ディスクを共有していなければならないことを意味します。
  +
* (必要であれば) {{ic|/efi}} マウントポイントは手動で作成する必要があります。存在しない場合、{{ic|systemd-gpt-auto-generator}} は {{ic|/boot}} を使用します。
   
  +
{{Warning|GPT 自動マウントを使用している既存のシステムに {{ic|/efi}} を作成するときは、十分に注意してください。次回の起動時には {{ic|/efi}} がデフォルトのマウントポイントとして使用され、{{ic|/boot}} ディレクトリが空になってシステムが不整合状態になる可能性があります。恐らくカーネルとマイクロコードを再インストールしたり、initramfs を再生成したりする必要があるでしょう。}}
== Journal ==
 
systemd は、バージョン 38 から自前のログシステムである journal を搭載しています。従って、syslog デーモンを起動する必要はもはやありません。ログを読むには:
 
   
  +
{{Tip|パーティションのオートマウントを無効にするには、パーティションの [[Wikipedia:GUID Partition Table#Partition type GUIDs|type GUID]] を変更するか、パーティション属性ビットを 63 "do not automount" に設定します、詳しくは [[gdisk#GPT パーティションの自動マウントを防ぐ]] を参照してください。}}
# journalctl
 
   
  +
===== /var =====
デフォルトで ({{ic|/etc/systemd/journald.conf}} 内で {{ic|Storage&#61;}} が {{ic|auto}} に設定されているとき)、journal は {{ic|/var/log/journal/}} へ書き込みを行います。Arch Linux では {{ic|/var/log/journal/}} ディレクトリは {{Pkg|systemd}} の一部であり、あなたや何らかのプログラムがディレクトリを削除した場合、systemd は自動で'''再作成しません'''が、systemd のアップデートがあるとディレクトリは作りなおされます。それまでログは代わりに {{ic|/run/systemd/journal}} に書き込まれます。ただし再起動時にこのログは消失してしまいます。
 
   
  +
{{ic|/var}} の自動マウントが動作するためには、PARTUUID がパーティションタイプの UUID ({{ic|4d21b016-b534-45c2-a9fb-5c16e091fd2d}}) の SHA256 HMAC ハッシュにマシン ID でキーを付けたものと一致している必要があります。必要な PARTUUID は、以下の方法で取得できます。
{{Tip|{{ic|/var/log/journal/}} が [[btrfs]] ファイルシステムに存在する場合、ディレクトリの Copy-on-Write を無効にするべきです。詳しくは [[Btrfs#コピーオンライト (CoW)]] を読んで下さい。}}
 
   
  +
$ systemd-id128 -u --app-specific=4d21b016-b534-45c2-a9fb-5c16e091fd2d machine-id
Systemd ジャーナルはメッセージを[[#プライオリティレベル|プライオリティレベル]]と[[#ファシリティ|ファシリティ]]で分類します。古典的な [[wikipedia:Syslog|Syslog]] プロトコルと対応しています ([https://tools.ietf.org/html/rfc5424 RFC 5424])。
 
   
  +
{{Note|{{man|1|systemd-id128}}はマシンIDを{{ic|/etc/machine-id}} から読み取るので、システムをインストールする前に必要な PARTUUID を知ることは不可能です。}}
===プライオリティレベル===
 
   
  +
=== systemd-sysvcompat ===
メッセージの重要度は syslog の重大度コード (systemd ではプライオリティと呼ばれます) を使って示されます [https://tools.ietf.org/html/rfc5424#section-6.2.1 RFC 5424 Section 6.2.1]:
 
   
  +
{{Pkg|systemd-sysvcompat}} ({{Pkg|base}} の依存) の主な役割は、伝統的な linux [[init]] バイナリを提供することです。''systemd'' により制御されているシステムでは、{{ic|init}} はその {{ic|systemd}} 実行ファイルへのシンボリックリンクに過ぎません。
{| class="wikitable"
 
|-
 
! 値 !! 重大度 !! キーワード !! 説明 || 例
 
|-
 
| 0 || Emergency || emerg || システムは利用不可能 || 重大なカーネルのバグ/systemd によってコアダンプが作成された。アプリケーションが使用するレベルではありません。
 
|-
 
| 1 || Alert || alert || 即時対応が必要 || 重要なサブシステムが機能していない/データが消失している。<br>{{ic|kernel: BUG: unable to handle kernel paging request at ffffc90403238ffc}}。
 
|-
 
| 2 || Critical || crit || 緊急状態 || クラッシュ/コアダンプ。{{ic|systemd-coredump[25319]: Process 25310 (plugin-containe) of user 1000 dumped core}}。X11 などのシステムにとって重要なアプリケーションが機能を失っている。
 
|-
 
| 3 || Error || err || エラー状態 || 重大度は低いエラー: {{ic|kernel: usb 1-3: 3:1: cannot get freq at ep 0x84}},<br>{{ic|systemd[1]: Failed unmounting /var.}}, {{ic|libvirtd[1720]: internal error: Failed to initialize a valid firewall backend}})。
 
|-
 
| 4 || Warning || warning || エラーが発生する前に対応が必要 || ルートファイルシステム以外のファイルシステムの空き領域が 1GB しかない。{{ic|org.freedesktop. Notifications[1860]: (process:5999): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale}}。
 
|-
 
| 5 || Notice || notice || 通常ではないイベントが発生しているがエラー状態ではない || {{ic|systemd[1]: var.mount: Directory /var to mount over is not empty, mounting anyway}}, {{ic|gcr-prompter[4997]: Gtk: GtkDialog mapped without a transient parent. This is discouraged}}。
 
|-
 
| 6 || Informational || info || 何も対応が必要な通常のメッセージ || {{ic|lvm[585]: 7 logical volume(s) in volume group "archvg" now active}}。
 
|-
 
| 7 || Debug || debug || アプリケーションをデバッグするのに役立つ情報 || {{ic|kdeinit5[1900]: powerdevil: Scheduling inhibition from ":1.14" "firefox" with cookie 13 and reason "screen"}}。
 
|}
 
   
  +
さらに、[[SysVinit]] のユーザーが慣れ親しんでいるであろう4つの便利なショートカットも提供されています。便利なショートカットは {{man|8|halt}}, {{man|8|poweroff}}, {{man|8|reboot}}, {{man|8|shutdown}} です。これら4つのコマンドはそれぞれ {{ic|systemctl}} へのシンボリックリンクであり、''systemd'' の動作に支配されます。そのため、[[#電源管理]] での議論が適用されます。
上記のレベルで問題が確認できない場合、上下のプライオリティレベルも調べてみてください。厳しくルールが決められているわけではありません。発生する確率が高いエラーは開発者によってプライオリティが低く設定されている可能性があります。逆に、緊急度が高いメッセージが大量に出力されることもありますが、必ずしも切羽詰まった状況を表しているとは限りません。
 
   
  +
''systemd'' ベースのシステムは {{ic|1= init=}} [[カーネルパラメータ#パラメータ一覧|ブートパラメータ]] (例えば、[https://bbs.archlinux.org/viewtopic.php?id=233387 /bin/init is in systemd-sysvcompat ?]) と ''systemd'' ネイティブ {{ic|systemctl}} コマンド引数を使うことで、これらの System V 互換の方法を諦めることができます。
===ファシリティ===
 
   
  +
=== systemd-tmpfiles - 一時ファイル ===
メッセージを出力したプログラムのタイプは syslog のファシリティコードで指定されます [https://tools.ietf.org/html/rfc5424#section-6.2.1 RFC 5424 Section 6.2.1]:
 
   
  +
''systemd-tmpfiles'' は揮発性ファイルや一時ファイル、ディレクトリの作成、削除、クリーンアップを行います。systemd-tmpfiles は {{ic|/etc/tmpfiles.d/}} と {{ic|/usr/lib/tmpfiles.d/}} にある設定ファイルを読んで、実行するアクションを決めます。前者のディレクトリにある設定ファイルは後者のディレクトリにある設定ファイルより優先されます。
{| class="wikitable"
 
! ファシリティコード !! キーワード !! 説明 !! 情報
 
|-
 
| 0 || kern || カーネルメッセージ
 
|-
 
| 1 || user || ユーザーレベルメッセージ
 
|-
 
| 2 || mail || メールシステム || 詳しくは {{ic|man mail}}) を見てください。
 
|-
 
| 3 || daemon || システムデーモン || systemd やサブシステムを含む全てのデーモン
 
|-
 
| 4 || auth || セキュリティ/認証メッセージ || ファシリティ10もあります。
 
|-
 
| 5 || syslog || syslogd の内部メッセージ || syslogd 用のファシリティなので systemd は使用していません (ファシリティ3を使います)。
 
|-
 
| 6 || lpr || ラインプリンターサブシステム (旧式のサブシステム)
 
|-
 
| 7 || news || ネットワークニュースサブシステム (旧式のサブシステム)
 
|-
 
| 8 || uucp || UUCP サブシステム (旧式のサブシステム)
 
|-
 
| 9 || || クロックデーモン || systemd-timesyncd
 
|-
 
| 10 || authpriv || セキュリティ/認証メッセージ || ファシリティ4もあります。
 
|-
 
| 11 || ftp || FTP デーモン
 
|-
 
| 12 || - || NTP サブシステム
 
|-
 
| 13 || - || log audit
 
|-
 
| 14 || - || log alert
 
|-
 
| 15 || cron || スケジューリングデーモン
 
|-
 
| 16 || local0 || ローカル使用 0 (local0)
 
|-
 
| 17 || local1 || ローカル使用 1 (local1)
 
|-
 
| 18 || local2 || ローカル使用 2 (local2)
 
|-
 
| 19 || local3 || ローカル使用 3 (local3)
 
|-
 
| 20 || local4 || ローカル使用 4 (local4)
 
|-
 
| 21 || local5 || ローカル使用 5 (local5)
 
|-
 
| 22 || local6 || ローカル使用 6 (local6)
 
|-
 
| 23 || local7 || ローカル使用 7 (local7)
 
|}
 
   
  +
設定ファイルは通常サービスファイルと一緒に提供され、{{ic|/usr/lib/tmpfiles.d/''program''.conf}} というスタイルで命名されます。例えば、[[Samba]] デーモンはディレクトリ {{ic|/run/samba}} が存在し、正しいパーミッションを持っていることを期待します。そのため、{{Pkg|samba}} パッケージはこの設定で出荷されます。
意味のあるファシリティは次の7つになります: 0, 1, 3, 4, 9, 10, 15。
 
   
  +
{{hc|/usr/lib/tmpfiles.d/samba.conf|
=== フィルタリング ===
 
  +
D /run/samba 0755 root root
  +
}}
   
  +
設定ファイルは、起動時に特定のファイルに値を書き込むために使用することもできます。例えば、{{ic|/etc/rc.local}} で USB デバイスからの wakeup を無効にするために {{ic|echo USBE > /proc/acpi/wakeup}} を使った場合、代わりに以下の tmpfile を使用することができます。
{{ic|journalctl}} を使って出力にフィルタをかけることができます。表示したりフィルタリングをするメッセージが大量にある場合、かなり時間がかかります。コマンドの出力は相当の時間がたってから表示されるかもしれません。
 
   
  +
{{hc|/etc/tmpfiles.d/disable-usb-wake.conf|
{{Tip|journal はバイナリ形式で保存されますが、保存されるメッセージの中身に修正は加わりません。このため、''systemd'' をインストールしていない環境でリカバリなどをするために、''strings'' を使って回覧することが可能です。コマンドの例: {{ic|$ strings /mnt/arch/var/log/journal/af4967d77fba44c6b093d0e9862f6ddd/system.journal <nowiki>| grep -i</nowiki> ''message''}}}}
 
  +
# Path Mode UID GID Age Argument
  +
w /proc/acpi/wakeup - - - - USBE
  +
}}
   
  +
詳しくは {{man|8|systemd-tmpfiles}} および {{man|5|tmpfiles.d}} のマニュアルページを参照してください。
例:
 
   
  +
{{Note|適切なモジュールのロードが完了するまでに systemd-tmpfiles-setup サービスが起動することがあるため、この方法は {{ic|/sys}} のオプションを設定するのには使えないかもしれません。この場合、{{ic|modinfo ''module''}} で設定したいオプションのパラメータがモジュールにあるかどうかを調べ、 [[カーネルモジュール#モジュールオプションを設定する|/etc/modprobe.d にある設定ファイル]] でそのオプションを設定することができます。そうでない場合は、デバイスが現れたらすぐに適切な属性を設定するように [[udev#udev ルールについて|udevルール]] を書く必要があります。}}
* 起動時からの全てのメッセージを表示: {{bc|# journalctl -b}} 場合によっては最新のブートメッセージではなく、以前のブートのメッセージを読みたいことがあります (例えば復旧できないシステムクラッシュが起こった場合)。{{ic|-b}} フラグに任意のパラメータを付けることでメッセージをオフセットして読むことが可能です: {{ic|journalctl -b -0}} は最新のブートのメッセージを、{{ic|journalctl -b -1}} は一つ前のブートのメッセージを表示し {{ic|journalctl -b -2}} は二つ前、と続きます。詳しくは {{ic|man 1 journalctl}} を見て下さい、セマンティックスはより強力です。
 
* 特定の日付 (任意で時間も指定可能) からのメッセージを全て表示: {{bc|1=# journalctl --since="2012-10-30 18:17:16"}}
 
* 20分前からのメッセージを全て表示: {{bc|1=# journalctl --since "20 min ago"}}
 
* 新しいメッセージを表示: {{bc|# journalctl -f}}
 
* 特定の実行ファイルによる全てのメッセージを表示: {{bc|# journalctl /usr/lib/systemd/systemd}}
 
* 特定のプロセスによる全てのメッセージを表示: {{bc|1=# journalctl _PID=1}}
 
* 特定のユニットによる全てのメッセージを表示: {{bc|# journalctl -u netcfg}}
 
* カーネルのリングバッファを表示: {{bc|1=# journalctl -k}}
 
* プライオリティレベルがエラー・クリティカル・アラートのメッセージだけを表示: {{bc|# journalctl -p err..alert}} {{ic|journalctl -p 3..1}} と数字を使うこともできます。{{ic|journalctl -p 3}} のようにひとつだけ指定した場合、指定されたプライオリティよりも高いレベルのメッセージも表示されます。
 
* syslog の facility をフィルタリングすることで {{ic|auth.log}} と同等の内容を表示: {{bc|1=# journalctl SYSLOG_FACILITY=10}}
 
   
  +
== ヒントとテクニック ==
詳しくは {{ic|man 1 journalctl}}, {{ic|man 7 systemd.journal-fields}} や Lennart の[http://0pointer.de/blog/projects/journalctl.html ブログ記事] を見て下さい。
 
   
  +
=== GUI 設定ツール ===
{{Tip|1=
 
デフォルトで、''journalctl'' は画面からはみ出る行を切り詰めますが、場合によっては、折り返しが有効になっていたほうが読みやすいことがあります。{{ic|SYSTEMD_LESS}} [[環境変数]]によってこれを制御することができ、[[Core Utilities#less|less]] (デフォルトのページャ) に渡すオプションを指定します。デフォルトは {{ic|FRSXMK}} (詳しくは {{ic|man 1 less}} や {{ic|man 1 journalctl}} を参照) です。
 
   
  +
* {{App|systemadm|''systemd'' ユニット用のグラフィカルブラウザ。ユニットのリストを表示することができ、タイプでフィルタリングすることもできます。|https://cgit.freedesktop.org/systemd/systemd-ui/|{{Pkg|systemd-ui}}}}
{{ic|S}} オプションを省くことで、出力は折り返されるようになります。例えば、以下のように ''journalctl'' を起動してください:
 
  +
* {{App|SystemdGenie|''systemd'' KDE 技術に基づく管理ユーティリティ。|https://invent.kde.org/system/systemdgenie|{{Pkg|systemdgenie}}}}
   
  +
=== ネットワークが稼働した後にサービスを実行する ===
$ SYSTEMD_LESS=FRXMK journalctl
 
   
  +
ネットワークが立ち上がった後までサービスを遅らせるには、以下の依存関係を ''.service'' ファイルに含めます。
この挙動をデフォルトに設定したいならば、{{ic|~/.bashrc}} や {{ic|~/.zshrc}} でこの変数を [[環境変数#ユーザーごと|export]] してください。
 
  +
  +
{{hc|/etc/systemd/system/''foo''.service|2=
  +
[Unit]
  +
...
  +
Wants=network-online.target
  +
After=network-online.target
  +
...
 
}}
 
}}
   
  +
ネットワークを管理する特定のアプリケーションのネットワーク待ち受けサービスも有効にして、{{ic|network-online.target}} がネットワークの状態を適切に反映するようにする必要があります。
=== journal のサイズ制限 ===
 
   
  +
* [[NetworkManager]] を利用している場合、{{ic|NetworkManager-wait-online.service}} は {{ic|NetworkManager.service}} と一緒に有効になっています。{{ic|systemctl is-enabled NetworkManager-wait-online.service}} で確認してください。有効になっていない場合は、{{ic|NetworkManager.service}} を [[systemd#ユニットを使う|再有効化]] してください。
journal が永続的(不揮発性)の場合、デフォルトではファイルシステムの容量の 10% に制限されます (4 GiB が上限)。例えば、{{ic|/var/log/journal}} が 20GiB の root パーティションにのっている場合、2GiB がログデータの上限になります。{{ic|/etc/systemd/journald.conf}} の {{ic|SystemMaxUse}} を変更すれば、最大サイズを変更できます。例えば制限を 50Mib にする場合、適切な行を次のようにアンコメント・編集します:
 
  +
* [[netctl]] の場合、{{ic|netctl-wait-online.service}} を [[systemd#ユニットを使う|有効化]] して下さい (''netctl-auto'' を使っていない場合。{{Bug|75836}} を参照してください)。
  +
* [[systemd-networkd]] を利用している場合、{{ic|systemd-networkd-wait-online.service}} は {{ic|systemd-networkd.service}} と一緒に有効になっています。{{ic|systemctl is-enabled systemd-networkd-wait-online.service}} でこの状態にあるかどうか確認してください。有効になっていない場合は、{{ic|systemd-networkd.service}} を [[systemd#ユニットを使う|再有効化]] してください。
   
  +
より詳しい説明は [https://systemd.io/NETWORK_ONLINE/#discussion ネットワーク設定の同期のポイント] の議論をご覧ください。
SystemMaxUse=50M
 
   
  +
サービスが DNS クエリを実行する必要がある場合、追加で {{ic|nss-lookup.target}} の後に命令する必要があります。
上記のように設定ファイルを編集する代わりにドロップインファイルを使用する方法もあります。その場合 {{ic|[Journal]}} ヘッダーを使って以下のように記述してください:
 
   
{{hc|/etc/systemd/journald.conf.d/00-journal-size.conf|2=
+
{{hc|/etc/systemd/system/''foo''.service|2=
[Journal]
+
[Unit]
  +
...
SystemMaxUse=50M
 
  +
Wants=network-online.target
  +
After=network-online.target nss-lookup.target
  +
...
 
}}
 
}}
   
詳細は {{ic|man journald.conf}} を参照してください。
+
{{man|7|systemd.special|Special Passive System Units}} を参照してください。
   
  +
{{ic|nss-lookup.target}} が効果を発揮するためには、{{ic|1=Wants=nss-lookup.target}} で実行を要求して、{{ic|1=Before=nss-lookup.target}} で事前に実行されているように指定してあるサービスが必要です。通常、これはローカルの [[ドメイン名前解決|DNSリゾルバ]] によって行われます。
=== ジャーナルファイルを手動で消去 ===
 
   
  +
どのアクティブなサービスが {{ic|nss-lookup.target}} で実行を要求しているのかを確認してください。
journal のファイルは {{ic|/var/log/journal}} に存在します。{{ic|rm}} で消去することもできますが、{{ic|journalctl}} を使って消去することも可能です。例:
 
   
  +
$ systemctl list-dependencies --reverse nss-lookup.target
* 使用ディスク容量が 100M 以下になるまで journal ファイルを削除する: {{bc|1=# journalctl --vacuum-size=100M}}
 
* 2週間以上前のデータを含んでいる journal ファイルを削除する: {{bc|1=# journalctl --vacuum-time=2weeks}}
 
   
  +
=== インストールされたユニットをデフォルトで有効にする ===
詳しくは {{ic|man journalctl}} を見て下さい。
 
   
  +
Arch Linux の {{ic|/usr/lib/systemd/system-preset/99-default.preset}} には {{ic|disable *}} と記述されています。systemctl プリセットがデフォルトで全てのユニットを無効化するようになり、新しいパッケージがインストールされたときも、ユーザーが手動でユニットを有効化する必要があります。
=== journald と syslog の結合 ===
 
   
  +
自動的に有効化させたい場合、{{ic|/etc/systemd/system-preset/99-default.preset}} から {{ic|/dev/null}} にシンボリックリンクを作成して設定ファイルを上書きしてください。systemctl プリセットの設定ディレクトリで指定しないかぎり、インストールされた全てのユニットが、ユニットのタイプに関わらず有効化されるようになります。詳しくは {{man|5|systemd.preset}} の man ページを参照。
古典的な [[syslog-ng|syslog]] との互換性は、すべてのメッセージがソケット {{ic|/run/systemd/journal/syslog}} に転送されることで実現されます。syslog を使うには、{{ic|/dev/log/}} の代わりにこのソケットを指定します ([http://lwn.net/Articles/474968/ 公式アナウンス])。
 
   
  +
{{Note|デフォルトで全てのユニットを有効化すると、パッケージに(互いに両立しない)複数のユニットが含まれている場合に問題が生じます。systemctl プリセットはディストリビューションやシステム管理者によって使われることを意図されて作られています。衝突するユニットが有効化されてしまう場合、{{ic|systemd.preset}} の man ページに書かれているように、プリセットの設定ファイルを使ってどちらか片方を明示的に無効化させる必要があります。}}
''systemd'' 216 からオーバーヘッドを減らすために {{ic|journald.conf}} のソケットの転送はデフォルトで無効になっています ({{ic|1=ForwardToSyslog=no}})。[[rsyslog]] や [[syslog-ng]] (3.6 以降) は [http://lists.freedesktop.org/archives/systemd-devel/2014-August/022295.html#journald 自力で] journal からメッセージを取得するためです。
 
   
  +
=== アプリケーション環境のサンドボックス化 ===
設定の詳細は [[Syslog-ng#概要]], [[Syslog-ng#syslog-ng と systemd journal]], [[rsyslog]] を見て下さい。
 
  +
ユニットファイルをサンドボックスとして作成して堅牢な仮想環境にアプリケーションやプロセスを分離させることが可能です。systemd は[[wikipedia:Linux_namespaces|名前空間]]や、許可・拒否された [[ケイパビリティ]] のリスト、[[Cgroups]] を活用して実行環境を設定しプロセスをコンテナ化します—{{man|5|systemd.exec}}。
   
  +
既存の systemd ユニットファイルを使ってアプリケーションをサンドボックス化するには {{Pkg|strace}}, [[wikipedia:ja:標準ストリーム#標準エラー出力 (stderr)|stderr]], [https://www.freedesktop.org/software/systemd/man/journalctl.html journalctl] などでエラーや出力を確認しながら試行錯誤が必要です。まずは上流のドキュメントを検索して先例がないか確認すると良いでしょう。堅牢にし得る選択肢の出発点を探すには、以下のコマンドを実行します。
=== journald を /dev/tty12 に転送する ===
 
   
  +
$ systemd-analyze security ''unit''
[[#ユニットファイルの編集|ドロップインディレクトリ]] {{ic|/etc/systemd/journald.conf.d}} を作成して、ディレクトリの中に {{ic|fw-tty12.conf}} ファイルを作成してください:
 
{{hc|1=/etc/systemd/journald.conf.d/fw-tty12.conf|2=
 
[Journal]
 
ForwardToConsole=yes
 
TTYPath=/dev/tty12
 
MaxLevelConsole=info
 
}}
 
   
  +
''systemd'' をサンドボックス化するいくつかの例は以下にあります。
次を実行して journald を再起動してください:
 
# systemctl restart systemd-journald
 
   
  +
* {{ic|CapabilityBoundingSet}} は、ユニットに許可または拒否された {{man|7|capabilities}} のリストを定義します。{{man|5|systemd.exec|CAPABILITIES}} を参照してください。
=== 別のジャーナルを指定して表示 ===
 
  +
** 例えば、[https://lwn.net/Articles/486306/ 安全なサンドボックスのゴール] の1つである {{Ic|CAP_SYS_ADM}} ケイパビリティ: {{ic|1=CapabilityBoundingSet=~ CAP_SYS_ADM}}
ライブ環境から起動して本番環境を修復する場合など、トラブルが発生した他のシステムのログを確認する必要があるような場合、{{ic|/mnt}} などにディスクをマウントしてから、ジャーナルのパスを {{ic|-D}}/{{ic|--directory}} で指定することができます:
 
   
  +
=== サービスの失敗を通知する ===
$ journalctl -D ''/mnt''/var/log/journal -xe
 
   
  +
サービス障害を通知するためには、{{ic|1=OnFailure=}} ディレクティブを、例えば [[systemd# ドロップインファイル|ドロップイン設定ファイル]] を使用して、該当するサービスファイルに追加する必要があります。このディレクティブを各サービスユニットに追加するには、トップレベルのドロップイン設定ファイルを使用します。トップレベルのドロップインについて詳しくは {{man|5|systemd.unit}} を参照してください。
== Tips and tricks ==
 
   
  +
サービス用のトップレベルのドロップインを作成します。
=== インストールされたユニットをデフォルトで有効にする ===
 
   
  +
{{hc|/etc/systemd/system/service.d/toplevel-override.conf|2=
Arch Linux の {{ic|/usr/lib/systemd/system-preset/99-default.preset}} には {{ic|disable *}} と記述されています。systemctl プリセットがデフォルトで全てのユニットを無効化するようになり、新しいパッケージがインストールされたときも、ユーザーが手動でユニットを有効化する必要があります。
 
  +
[Unit]
  +
OnFailure=failure-notification@%n
  +
}}
   
  +
これにより、すべてのサービスファイルに {{ic|1=OnFailure=failure-notification@%n}} が追加されます。''some_service_unit'' が失敗すると、{{ic|failure-notification@''some_service_unit''}}が開始されて通知(または実行するよう設定された任意のタスク)を処理するようになります。
自動的に有効化させたい場合、{{ic|/etc/systemd/system-preset/99-default.preset}} から {{ic|/dev/null}} にシンボリックリンクを作成して設定ファイルを上書きしてください。systemctl プリセットの設定ディレクトリで指定しないかぎり、インストールされた全てのユニットが有効化されるようになります。詳しくは {{ic|systemd.preset}} の man ページを参照。
 
   
  +
テンプレートユニット {{ic|failure-notification@}} を作成します。
{{Note|デフォルトで全てのユニットを有効化すると、パッケージに(互いに両立しない)複数のユニットが含まれている場合に問題が生じます。systemctl プリセットはディストリビューションやシステム管理者によって使われることを意図されて作られています。衝突するユニットが有効化されてしまう場合、{{ic|systemd.preset}} の man ページに書かれているように、プリセットの設定ファイルを使ってどちらか片方を明示的に無効化させる必要があります。}}
 
   
  +
{{hc|/etc/systemd/system/failure-notification@.service|2=
=== アプリケーション環境のサンドボックス化 ===
 
  +
[Unit]
ユニットファイルをサンドボックスとして作成して堅牢な仮想環境にアプリケーションやプロセスを分離させることが可能です。systemd は[[wikipedia:Linux_namespaces|名前空間]]や[[ケイパビリティ]]のホワイトリスト・ブラックリスト、[[Cgroups]] を活用して [https://www.freedesktop.org/software/systemd/man/systemd.exec.html 実行環境を設定] しプロセスをコンテナ化します。
 
  +
Description=Send a notification about a failed systemd unit
  +
After=network.target
   
  +
[Service]
既存の systemd ユニットファイルを使ってアプリケーションをサンドボックス化するには {{Pkg|strace}}, [[wikipedia:ja:標準ストリーム#標準エラー出力 (stderr)|stderr]], [https://www.freedesktop.org/software/systemd/man/journalctl.html journalctl] などでエラーや出力を確認しながら試行錯誤が必要です。まずは上流のドキュメントを検索して先例がないか確認すると良いでしょう。
 
  +
Type=simple
  +
ExecStart=/''path''/''to''/failure-notification.sh %i
  +
}}
   
  +
{{ic|failure-notification.sh}} スクリプトを作成し、何をするか、どのように通知するか(メール、gotify、xmpp など)を定義します。{{ic|%i}} は失敗したサービスユニットの名前で、スクリプトの引数として渡されます。
{{Ic|CapabilityBoundingSet}} では許可されるケイパビリティのホワイトリストを定義できますが、特定のケイパビリティをブラックリストに追加する用途で使うこともできます。例: {{ic|1=CapabilityBoundingSet=~ CAP_SYS_ADMIN}}。
 
   
  +
起動に失敗した場合に、何度も {{ic|failure-notification@.service}} のインスタンスを起動する再帰を防ぐために、トップレベルのドロップインと同じ名前の空のドロップイン設定ファイルを作成します(空のサービスレベルのドロップイン設定ファイルはトップレベルのドロップインより優先され、後者をオーバーライドします。)
== トラブルシューティング ==
 
   
  +
# mkdir -p /etc/systemd/system/failure-notification@.service.d
=== systemd のエラーを調査する ===
 
  +
# touch /etc/systemd/system/failure-notification@.service.d/toplevel-override.conf
   
  +
=== シャットダウン時に自動で外部HDDの電源を切る ===
例えば、{{ic|systemd-modules-load}} サービスのエラーを調べるとします:
 
   
  +
もしシステムのシャットダウン時に外部 HDD の電源が正常に切れない場合は、その問題を修正することが望ましいでしょう。電源を切る最も便利な方法は [[udisks]] を使用することです。
1. 起動に失敗している systemd サービスを探しましょう:
 
{{hc|1=$ systemctl --state=failed|2=
 
systemd-modules-load.service loaded '''failed failed''' Load Kernel Modules}}
 
   
  +
{{ic|udisks2.service}} を [[有効化]] します。
もしくは ''systemd'' のライブログメッセージを確認します:
 
$ journalctl -fp err
 
   
  +
スクリプトを実行するサービスは以下のようになります。
2. Ok, {{ic|systemd-modules-load}} サービスに問題が発生していることがわかりました。詳しく見てみましょう:
 
{{hc|$ systemctl status systemd-modules-load|2=
 
systemd-modules-load.service - Load Kernel Modules
 
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
 
Active: '''failed''' (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
 
Docs: man:systemd-modules-load.service(8).
 
man:modules-load.d(5)
 
Process: '''15630''' ExecStart=/usr/lib/systemd/systemd-modules-load ('''code=exited, status=1/FAILURE''')
 
}}
 
{{ic|Process ID}} が載っていない場合は、{{ic|systemctl restart systemd-modules-load}} で失敗したサービスを再実行してください。
 
   
  +
{{hc|/etc/systemd/system/handle_external_hdds.service|2=
3. エラーを細かく調べるためのプロセス ID (PID) を入手しました。{{ic|Process ID}} を使って (ここでは: 15630) 以下のコマンドを実行してください:
 
  +
[Unit]
{{hc|1=$ journalctl _PID=15630|2=
 
  +
Requires=udisks2.service
-- Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. --
 
  +
Requires=graphical.target
Aug 25 11:48:13 mypc systemd-modules-load[15630]: '''Failed to find module 'blacklist usblp''''
 
  +
After=graphical.target
Aug 25 11:48:13 mypc systemd-modules-load[15630]: '''Failed to find module 'install usblp /bin/false''''
 
  +
[Service]
  +
Type=oneshot
  +
RemainAfterExit=yes
  +
ExecStop=/usr/local/bin/handle_external_hdds.sh
  +
[Install]
  +
WantedBy=graphical.target
 
}}
 
}}
   
  +
{{ic|handle_external_hdds.service}} を [[有効化]] します。
4. カーネルモジュールに間違った設定がなされているようです。よって {{ic|/etc/modules-load.d/}} 下の設定を見てみましょう:
 
{{hc|$ ls -Al /etc/modules-load.d/|
 
...
 
-rw-r--r-- 1 root root 79 1. Dez 2012 blacklist.conf
 
-rw-r--r-- 1 root root 1 2. Mär 14:30 encrypt.conf
 
-rw-r--r-- 1 root root 3 5. Dez 2012 printing.conf
 
-rw-r--r-- 1 root root 6 14. Jul 11:01 realtek.conf
 
-rw-r--r-- 1 root root 65 2. Jun 23:01 virtualbox.conf
 
...
 
}}
 
   
  +
systemd の [[daemon-reload]] を実行して、新しい設定を適用します。
5. エラーメッセージ {{ic|Failed to find module 'blacklist usblp'}} はおそらく {{ic|blacklist.conf}} 内に間違った設定があることを示しています。手順 3 で見つけたオプションの前に '''#''' を挿入して無効化してみましょう:
 
{{hc|/etc/modules-load.d/blacklist.conf|
 
'''#''' blacklist usblp
 
'''#''' install usblp /bin/false
 
}}
 
   
6. では、{{ic|systemd-modules-load}} を起動してみることにします:
+
再起動するか {{ic|graphical.target}} をリスタートして、正常動作するか確認します
$ systemctl start systemd-modules-load
 
成功した場合、何も表示されないはずです。何かエラーが表示される場合は、手順 3 に戻って下さい。そして新しい PID を使って残った問題を解決してください。
 
   
  +
1つのディスクの任意の量のパーティションを扱うスクリプトの例は以下のようになります。
全て問題ないならば、サービスが正しく起動したか次のコマンドで確認することができます:
 
  +
{{hc|$ systemctl status systemd-modules-load|2=
 
  +
{{hc|/usr/local/bin/handle_external_hdds.sh|2=
systemd-modules-load.service - Load Kernel Modules
 
  +
#!/bin/bash -u
Loaded: '''loaded''' (/usr/lib/systemd/system/systemd-modules-load.service; static)
 
  +
Active: '''active (exited)''' since So 2013-08-25 12:22:31 CEST; 34s ago
 
  +
declare -a uuids=(''uuid_list'')
Docs: man:systemd-modules-load.service(8)
 
  +
man:modules-load.d(5)
 
  +
# Only proceed if the drive is present.
Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
 
  +
if <nowiki>[[ ! -L "/dev/disk/by-uuid/${uuids[0]}" ]]</nowiki>; then
Aug 25 12:22:31 mypc systemd[1]: '''Started Load Kernel Modules'''.
 
  +
exit 0
  +
fi
  +
  +
for uuid in "${uuids[@]}"; do
  +
if findmnt "/dev/disk/by-uuid/$uuid"; then
  +
umount "/dev/disk/by-uuid/$uuid"
  +
fi
  +
done
  +
  +
# udisksctl powers off proper drive even if its partition is supplied
  +
udisksctl power-off -b "/dev/disk/by-uuid/${uuids[0]}"
 
}}
 
}}
   
  +
''uuid_list'' はスペース区切りの UUID リストで、例えば {{ic|"''uuid_1''" "''uuid_2''"}} のように、チェックするデバイスのパーティションに対応します。
この種の問題は上のように解決できます。より詳しい調査をする場合は次の[[#ブート問題の診断|ブート問題の診断]]を見て下さい。
 
  +
  +
== トラブルシューティング ==
  +
  +
=== systemd のエラーを調査する ===
  +
  +
起動に失敗している systemd サービスを探すには以下のコマンドを実行します。
  +
  +
$ systemctl --state=failed
   
  +
失敗している理由を探すには、ログ出力を調べてください。詳細は [[systemd/ジャーナル#フィルタリング]] を参照してください。
=== ブート問題の診断 ===
 
   
  +
=== ブート問題の診断 ===
カーネルコマンドラインに次のパラメータをつけて起動してください: {{ic|<nowiki>systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M</nowiki>}}。
 
   
詳しくは[[ブートデバッグ]] [http://freedesktop.org/wiki/Software/systemd/Debugging] を見さい。
+
''systemd'' は、ブートプロセスの問題を診断するためのいつかのオプションを提供しています。一般的な手順や、''systemd'' が [[ブートプロセス]] を引き継ぐ前のブートメッセージを残す方法について [[ブートデバッグ]] を参照してください。freedesktop.org の [https://freedesktop.org/wiki/Software/systemd/Debugging/ systemd デバッグドキュメント] も参照しください。
   
 
=== 特定のサービスの問題を診断 ===
 
=== 特定のサービスの問題を診断 ===
   
 
ある systemd サービスが上手く動作せず、どうなっているのか詳しい情報が欲しい場合、環境変数 {{ic|SYSTEMD_LOG_LEVEL}} を {{ic|debug}} に設定してください。以下は systemd-networkd デーモンをデバッグモードで動かす例です:
 
ある systemd サービスが上手く動作せず、どうなっているのか詳しい情報が欲しい場合、環境変数 {{ic|SYSTEMD_LOG_LEVEL}} を {{ic|debug}} に設定してください。以下は systemd-networkd デーモンをデバッグモードで動かす例です:
# systemctl stop systemd-networkd
 
# SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd
 
   
もしくは同じようにサービスファイルを修正してください:
+
サービスに [[#ドロップインファイル|ドロップインファイル]] を追加して、次の2行追記してください
   
  +
[Service]
{{hc|/lib/systemd/system/systemd-networkd.service|2=
 
  +
Environment=SYSTEMD_LOG_LEVEL=debug
[Service]
 
...
 
Environment=SYSTEMD_LOG_LEVEL=debug
 
....
 
}}
 
   
  +
あるいは、環境変数を手動でセットしても同じです。
=== シャットダウン/再起動にものすごく時間がかかる ===
 
   
  +
# SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd
シャットダウンに非常に長い時間がかかる(もしくはフリーズする)場合、サービスが存在していないことが問題かもしれません。Systemd はサービスを kill する前に終了するのを待ちます。なにが原因か知るには [http://freedesktop.org/wiki/Software/systemd/Debugging/#shutdowncompleteseventually この記事] を見て下さい。
 
   
  +
その後 ''systemd-networkd'' を [[リスタート]] して、サービスのジャーナルを {{ic|-f}}/{{ic|--follow}} オプションで監視してください。
=== 短いプロセスがログを出力しない ===
 
   
  +
=== シャットダウン/再起動にものすごく時間がかかる ===
{{ic|journalctl -u foounit.service}} が短いプロセスについてなにも表示しない場合、かわりに PID を見て下さい。例えば、{{ic|systemd-modules-load.service}} が失敗したとき、{{ic|systemctl status systemd-modules-load}} によってそれが PID 123 として動いているとわかったら、その PID の journal の出力を見ることができます、{{ic|journalctl -b _PID&#61;123}}。journal の {{ic|_SYSTEMD_UNIT}} や {{ic|_COMM}} などのメタデータは非同期に収集され {{ic|/proc}} ディレクトリにプロセスが存在している時だけ表示されます。これを修正するには、{{ic|SCM_CREDENTIALS}} のように、ソケット接続を使ってデータを流すようカーネルを変更する必要があります。
 
   
  +
シャットダウンに非常に長い時間がかかる(もしくはフリーズする)場合、サービスが存在していないことが問題かもしれません。Systemd はサービスを kill する前に終了するのを待ちます。該当しているか確認するには、''systemd'' wiki の [https://freedesktop.org/wiki/Software/systemd/Debugging/#shutdowncompleteseventually Shutdown completes eventually] を参照してください。
=== クラッシュしたアプリケーションのダンプのジャーナルを無効にする ===
 
   
  +
一般的な問題は、シャットダウンやサスペントのプロセスが停止することです。該当するかどうか確かめるには、以下のどちらかのコマンドを実行して、出力を確認してください。
{{ic|/etc/systemd/coredump.conf}} ファイルを編集して次の行を追加してください:
 
Storage=none
 
   
  +
{{hc
そして設定をリロードしてください:
 
# systemctl daemon-reload
+
|1=# systemctl poweroff
  +
|2=Failed to power off system via logind: There's already a shutdown or sleep operation in progress
  +
}}
   
  +
{{hc
=== 再起動やシャットダウン時のエラーメッセージ ===
 
  +
|1=# systemctl list-jobs
  +
|2= JOB UNIT TYPE STATE
  +
...
  +
21593 systemd-suspend.service start running
  +
21592 suspend.target start waiting
  +
..
  +
}}
   
  +
これの [https://unix.stackexchange.com/a/579531 解決策] は、以下を実行してそれらのジョブをキャンセルすることです。
==== cgroup : option or name mismatch, new: 0x0 "", old: 0x4 "systemd" ====
 
この警告は {{ic|kernel/cgroup.c}} のカーネルコードから来ています:
 
   
  +
# systemctl cancel
/* Don't allow flags or name to change at remount */
 
  +
# systemctl stop systemd-suspend.service
if (((opts.flags ^ root->flags) & CGRP_ROOT_OPTION_MASK) ||
 
(opts.name && strcmp(opts.name, root->name))) {
 
pr_err("option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"\n",
 
opts.flags & CGRP_ROOT_OPTION_MASK, opts.name ?: "",
 
root->flags & CGRP_ROOT_OPTION_MASK, root->name);
 
ret = -EINVAL;
 
goto out_unlock;
 
}
 
   
  +
すると、シャットダウンやリブートをまた再開します。
つまり、何かが cgroups を別の名前で再マウントしようとしてカーネルがそれに抵抗しているというわけです。ローカルの設定ファイルのエラーではなく、エラーメッセージ以外には何も症状が現れません。これが systemd のバグなのか、Arch の systemd パッケージに問題があるのかは判っていません [https://bbs.archlinux.org/viewtopic.php?pid=1372562#p1372562]。2014年11月現在、Arch の systemd パッケージにバグレポートは送られていないようです。
 
   
  +
=== 短いプロセスがログを出力しない ===
==== watchdog watchdog0: watchdog did not stop! ====
 
   
  +
{{ic|journalctl -u foounit}} が短いプロセスについてなにも表示しない場合、かわりに PID を見て下さい。例えば、{{ic|systemd-modules-load.service}} が失敗したとき、{{ic|systemctl status systemd-modules-load}} によってそれが PID 123 として動いているとわかったら、その PID の journal の出力を見ることができます、{{ic|journalctl -b _PID&#61;123}}。journal の {{ic|_SYSTEMD_UNIT}} や {{ic|_COMM}} などのメタデータは非同期に収集され {{ic|/proc}} ディレクトリにプロセスが存在している時だけ表示されます。これを修正するには、{{ic|SCM_CREDENTIALS}} のように、ソケット接続を使ってデータを流すようカーネルを変更する必要があります。簡単に言うと、これは [https://github.com/systemd/systemd/issues/2913 バグ] です。''systemd'' の設計によって、即座に失敗するサービスはジャーナルに何も出力しない場合があることを覚えておいてください。
[https://bbs.archlinux.org/viewtopic.php?pid=1372562#p1372562 このスレッド]を見て下さい。
 
   
 
===少しづつ起動時間が長くなっている===
 
===少しづつ起動時間が長くなっている===
666行目: 598行目:
 
{{ic|systemd-analyze}} を使用して、以前と比べて起動時間が明らかに伸びていると複数のユーザーが報告しています。{{ic|systemd-analyze blame}} を使って [[NetworkManager]] が起動するのに異常に長い時間かかるようになったという報告もあります。
 
{{ic|systemd-analyze}} を使用して、以前と比べて起動時間が明らかに伸びていると複数のユーザーが報告しています。{{ic|systemd-analyze blame}} を使って [[NetworkManager]] が起動するのに異常に長い時間かかるようになったという報告もあります。
   
問題の原因として {{ic|/var/log/journal}} が巨大になりすぎている可能性があります。そのような場合、フォルダ内のファイルを全て削除して journal のファイルサイズを[[#journal のサイズ制限|ここ]]に書かれているように制限するよう設定すれば解決しますできればファイルを削除する前に、どこかに一時的にバックアップしてください
+
問題の原因として {{ic|/var/log/journal}} が巨大になりすぎている可能性があります。そのような場合、フォルダ内のファイルを全て削除して journal のファイルサイズを[[systemd/ジャーナル#journal のサイズ制限|ここ]]に書かれているように制限するよう設定すれば解決します(できればファイルを削除する前に、どこかに一時的にバックアップしてください)
   
 
=== 起動時に systemd-tmpfiles-setup.service の実行に失敗する ===
 
=== 起動時に systemd-tmpfiles-setup.service の実行に失敗する ===
674行目: 606行目:
 
{{ic|/var/log/journal}} が存在するファイルシステムで ACL を有効化する方法は[[アクセス制御リスト#ACL の有効化]]を見て下さい。
 
{{ic|/var/log/journal}} が存在するファイルシステムで ACL を有効化する方法は[[アクセス制御リスト#ACL の有効化]]を見て下さい。
   
  +
=== リモートマシンで緊急モードを無効化 ===
=== systemctl enable で /etc/systemd/system にシンボリックリンクが作成されない ===
 
   
  +
リモートマシン (例えば Azure や Google Cloud でホストしている仮想マシン) の緊急モードは無効化すると良いでしょう。緊急モードが起動すると、ネットワークからマシンに接続できなくなってしまうからです。無効化するには以下のコマンドを実行:
{{ic|/etc/systemd/system/''foo''.service}} がシンボリックリンクの場合、{{ic|systemctl enable ''foo''.service}} を実行しても以下のエラーで失敗します:
 
   
  +
# systemctl mask emergency.service
Failed to issue method call: No such file or directory
 
  +
# systemctl mask emergency.target
   
  +
== 参照 ==
これは systemd の [https://bugzilla.redhat.com/show_bug.cgi?id=955379#c14 仕様] です。絶対パスで有効にすることで回避できます:
 
   
  +
* [[Wikipedia:systemd]]
# systemctl enable ''/absolute/path/foo''.service
 
  +
* [https://systemd.io/ 公式ウェブサイト]
 
  +
** [https://www.freedesktop.org/wiki/Software/systemd/Optimizations systemd の最適化]
== 参照 ==
 
  +
** [https://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions systemd FAQ]
  +
** [https://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks systemd のヒントとテクニック]
  +
* {{man|1|systemd}}
  +
* その他のディストリビューション
  +
** [[Gentoo:Systemd]]
  +
** [[Fedora:Systemd]]
  +
** [[Fedora:How to debug Systemd problems]]
  +
** [[Fedora:SysVinit to Systemd Cheatsheet]]
  +
** [[Debian:systemd]]
  +
* [http://0pointer.de/blog/projects/systemd.html Lennart's blog story], [http://0pointer.de/blog/projects/systemd-update.html update 1], [http://0pointer.de/blog/projects/systemd-update-2.html update 2], [http://0pointer.de/blog/projects/systemd-update-3.html update 3], [http://0pointer.de/blog/projects/why.html summary]
  +
* [https://containersolutions.github.io/runbooks/posts/linux/debug-systemd-service-units Systemd サービスのデバッグ]
  +
* [http://0pointer.de/public/systemd-ebook-psankar.pdf 管理者向け systemd (PDF)]
  +
* [https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units Systemctl を使用して Systemd サービスとユニットを管理する方法]
  +
* [https://dvdhrm.wordpress.com/2013/08/24/session-management-on-linux/ systemd-logind によるセッション管理]
  +
* [[Emacs#Syntax highlighting for systemd Files|Emacs Systemd ファイルの構文強調表示]]
  +
* [http://www.h-online.com/open/features/Control-Centre-The-systemd-Linux-init-system-1565543.html Two] [http://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html part] ''The H Open'' 誌の紹介記事。
   
  +
{{TranslationStatus|Systemd|2022-10-27|753672}}
*[http://www.freedesktop.org/wiki/Software/systemd 公式ウェブサイト]
 
*[[Wikipedia:ja:systemd|Wikipedia の記事]]
 
*[http://0pointer.de/public/systemd-man/ Manual Pages]
 
*[http://freedesktop.org/wiki/Software/systemd/Optimizations systemd Optimizations]
 
*[http://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions FAQ]
 
*[http://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks Tips And Tricks]
 
*[http://0pointer.de/public/systemd-ebook-psankar.pdf systemd for Administrators (PDF)]
 
*[http://fedoraproject.org/wiki/Systemd Fedora プロジェクトによる systemd の説明]
 
*[http://fedoraproject.org/wiki/How_to_debug_Systemd_problems systemd の問題をデバッグする方法]
 
*[http://www.h-online.com/open/features/Control-Centre-The-systemd-Linux-init-system-1565543.html] [http://www.h-online.com/open/features/Booting-up-Tools-and-tips-for-systemd-1570630.html] ''The H Open'' マガジンに記載された二部からなる紹介記事
 
*[http://0pointer.de/blog/projects/systemd.html Lennart のブログ記事]
 
*[http://0pointer.de/blog/projects/systemd-update.html ステータスアップデート]
 
*[http://0pointer.de/blog/projects/systemd-update-2.html ステータスアップデート 2]
 
*[http://0pointer.de/blog/projects/systemd-update-3.html ステータスアップデート 3]
 
*[http://0pointer.de/blog/projects/why.html 近況]
 
*[http://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet Fedora の SysVinit と systemd のチートシート]
 
*[[Emacs#Systemd ファイルのシンタックスハイライト|Emacs の Systemd ファイルのシンタックスハイライト]]
 
*[https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units digital ocean のチュートリアル]
 

2024年1月19日 (金) 22:07時点における最新版

関連記事

プロジェクトウェブページ より:

systemd は Linux 環境の基本構成スイートであり、SysV や LSB init スクリプトと互換性のある、Linux 用のシステム・サービスマネージャです。systemd はサービスの起動を積極的に並行化します。また、ソケットや D-Bus のアクティベーションを使用してサービスを起動し、必要なデーモンの開始を行うことができ、Linux の cgroups によるプロセス管理ができます。システム状態のスナップショット作成と復元、(自動) マウントポイントの管理、煩雑な依存関係に基づいたサービスのコントロールを処理します。systemd は sysvinit の代替として SysV や LSB init スクリプトをサポートしています。init としての機能以外にも、ログデーモンやホストネーム・時刻・ロケールなどシステムの基本設定を制御するユーティリティ、ログイン中のユーザーから実行中のコンテナや仮想マシン、システムアカウントまで管理する機能、ネットワーク設定や時刻同期あるいは名前解決などを管理するシンプルなデーモンも含まれています。

歴史的には、systemd が "サービス" と呼ぶものは デーモン と呼ばれていました:"バックグラウンド" プロセスとして (ターミナルやユーザーインターフェイスなしで) 実行され、一般的にイベントの発生を待ち、サービスを提供するプログラムです。ウェブサーバーがページを配信するリクエストを待ったり、ssh サーバーがログインしようとする人を待ったりするのが良い例です。これらは完全な機能を持つアプリケーションですが、デーモンも存在します。デーモンは、ログファイルにメッセージを書き込んだり (例:syslogmetalog)、システムの時刻を正確に保つ (例:ntpd) といったタスクを実行します。詳しくは daemon(7) を参照してください。

ノート: systemd が Arch に採用された理由については、フォーラムへのこの投稿をご覧ください。

目次

systemctl の基本的な使い方

systemd を管理したり内部情報を見るために使うメインのコマンドが systemctl です。システムの状態を確かめたりシステムやサービスを管理するために使うのは使い方の一部です。詳しくは systemctl(1) を見て下さい。

ヒント:
  • systemctl コマンドに -H user@host を渡すと、リモートの systemd と対話できます。これは SSH を利用してリモートの systemd インスタンスに接続します。
  • Plasma を使っている場合 systemdgenie をインストールすることで systemctl のグラフィカルフロントエンドを使えます。モジュールをインストールすると System の下に設定が追加されます。

ユニットを使う

ユニットには、例えば、サービス (.service) やマウントポイント (.mount)、デバイス (.device)、ソケット (.socket) などがあります。

systemctl を使うとき、例えば sshd.socket のように、一般的には拡張子 (suffix) を含むユニットファイルの完全な名前を指定する必要があります。しかし、以下のような場合には省略形が存在します:

  • 拡張子が指定されない場合、systemctl は .service とみなします。例えば netctlnetctl.service は同じように扱われます。
  • マウントポイントは自動的に対応する .mount ユニットとして扱われます。例えば、/home を指定することは home.mount の指定と同じです。
  • マウントポイントと同じく、デバイスも自動的に対応する .device ユニットとして扱われます。従って、/dev/sda2 の指定は dev-sda2.device と同じです。

詳細は systemd.unit(5) を見てください。

ノート: ユニットによっては名前に @ 記号が含まれていることがあります (例: name@string.service): これは、そのサービスがテンプレートユニットの インスタンス であることを意味しており、テンプレートユニットのファイル名には string の部分が含まれていません (例: name@.service)。stringinstance identifier と呼ばれ、systemctl コマンドでテンプレートユニットを実行するときに指定する引数と似ています: ユニットファイルの中の %i が置き換えられます。 正確に言うと、name@.suffix テンプレートユニットのインスタンスを作成する前にsystemdname@string.suffix というファイル名のユニットが存在しないか確認します。ただし名前の"衝突"が発生するのは極めて稀で、@ 記号を含むユニットファイルは大抵テンプレートです。そういう決まりです。また、テンプレートユニットが instance identifier を付けられずに呼ばれたときは、%i が置き換えられないため実行失敗になります (cat のような特定の systemctl コマンドを除く)。

以下の表のコマンドは、systemctl の暗黙のデフォルトである --system から、system unit を操作するものです。代わりに、ユーザー単位 で操作するには、root 権限なしで systemctl --user を使ってください。全てのユーザーに対してユーザーユニットを有効・無効にするには systemd/ユーザー#基本設定 も見て下さい。

ヒント:
  • 以下のコマンドのほとんどは複数のユニットを指定することが可能です、詳しくは systemctl(1) を参照。
  • --now スイッチは enable, disable, mask と一緒に使うことで、それぞれ起動、停止、マスクをリブート後ではなく即座に行うことができます。
  • パッケージには様々な目的のユニットが入っています。パッケージをインストールしたら、pacman -Qql package | grep -Fe .service -e .socket でサービスを確認することができます。
アクション コマンド 注意
システム状態の分析
システムステータスを表示する systemctl status
実行中のユニット リスト systemctl or
systemctl list-units
失敗したユニット 一覧 systemctl --failed
インストールされているユニット 一覧1 systemctl list-unit-files
PID のプロセスステータス を表示 systemctl status pid cgroup slice, メモリ と 上位プロセス
ユニットの状態を確認する
ユニットに関連付けられている マニュアルページを表示する systemctl help unit ユニットでサポートされています
ユニットの ステータス systemctl status unit 実行されているかどうかを含む
ユニットが有効かどうかを チェック する systemctl is-enabled unit
本体の起動、再起動、再読み込み
ユニットを即座に スタート する systemctl start unit as root
ユニットを即座に ストップ する systemctl stop unit as root
ユニットを 再起動 する systemctl restart unit as root
ユニットとその設定を 再読み込み する systemctl reload unit as root
systemd マネージャーの再読み込み 設定2 systemctl daemon-reload as root ユニットスキャン
ユニットの有効化
ブート時に自動的に起動するユニットを 有効 にする systemctl enable unit as root
起動時に自動起動するユニットを 有効 にして、すぐに 起動 する systemctl enable --now unit as root
無効 にすると、ブート時に起動しなくなります systemctl disable unit as root
ユニット3再有効化 する systemctl reenable unit as root つまり、無効化して新たに有効化する
ユニットのマスキング
mask して起動不能にするユニット4 systemctl mask unit as root
unmask ユニット systemctl unmask unit as root
  1. 利用可能なユニットファイルがあるディレクトリは systemd.unit(5) § UNIT FILE LOAD PATH を参照してください。
  2. これは変更されたユニットに設定の再読み込みを要求しません (アクション Reload を参照して下さい)。
  3. 例えば、最後に有効化してからその [Install] セクションが変更された場合。
  4. 手動でも依存関係としても、マスクは危険です。既存のマスクされたユニットをチェックします。
    $ systemctl list-unit-files --state=masked

電源管理

非特権ユーザーでの電源管理には、polkit が必要です。ローカルの systemd-logind ユーザーセッションで、他のセッションがアクティブでない場合、以下のコマンドは root 権限がなくても動作します。そうでない場合(例えば、他のユーザーが tty にログインしているなど)、systemd は自動的に root パスワードを要求します。

アクション コマンド
システムをシャットダウンして再起動する systemctl reboot
システムをシャットダウンして電源を切る systemctl poweroff
システムを一時停止する systemctl suspend
システムをハイバネーションにする systemctl hibernate
システムをハイブリッドスリープ状態にする (または suspend-to-both) にする systemctl hybrid-sleep
まずシステムをサスペンドし、設定された時間の経過後にウェイクアップしてシステムを休止状態にする systemctl suspend-then-hibernate

ユニットファイル

systemd のユニットファイル (systemd.unit(5)) の構文は XDG の Desktop Entry Specification である .desktop ファイル から影響を受けています。そして .desktopMicrosoft Windows の .ini ファイル からインスパイアされています。ユニットファイルは複数の場所に配置されます (配置場所のリストを確認するには systemctl show --property=UnitPath を実行してください)が、主な場所は (優先度が低い方から説明すると):

  • /usr/lib/systemd/system/: インストールしたパッケージに含まれているユニット
  • /etc/systemd/system/: システムの管理者がインストールしたユニット
ノート:
  • ユーザーモードsystemd を動作させたときにロードされるパスは完全に異なります。
  • systemd ユニットの名前に使うことができるのは ASCII 英数字とアンダーバー、ピリオドだけです。他の文字列は C スタイルの "\x2d" エスケープに置き換えるか、事前に定義された方法 ('@' や '-') を使う必要があります。詳しくは systemd.unit(5)systemd-escape(1) を見て下さい。

例としてパッケージによりインストールされたユニットや systemd.service(5) § EXAMPLES を参照してください。

ヒント: # で始まるコメントはユニットファイルでも使うことができますが、行頭でのみ有効です。systemd のパラメータの後で行末のコメントを使わないでください。ユニットの有効化が失敗する原因となります。

依存関係を解決する

systemd ではユニットファイルを適切に書くことで依存関係を解決します。一番典型的なケースは、ユニット A が走る前に、ユニット A がユニット B を必要としている場合です。この場合、A[Unit] セクションに Requires=BAfter=B を加えます。依存が必然ではない場合、代わりに Wants=BAfter=B を加えます。Wants=Requires=After= を含まないことに注意してください、もし After= を明記しなかったときは、2つのユニットは並行して実行されます。

基本的に、依存関係はターゲットではなくサービスに記述します。例えば、network.target はネットワークインターフェースを設定する全てのサービスによって使われるので、カスタムユニットを起動させる順番は network.target が起動し終わってからにする必要があります。

サービスタイプ

カスタムサービスファイルを書くときにどのスタートアップタイプを使うべきか考える必要があります。タイプは [Service] セクションの Type= パラメータで設定します。

  • Type=simple (デフォルト): systemd はプロセスを起動した時点でサービスが立ち上がったとみなします。プロセスをフォークすることはできません。ソケットアクティベーション以外で他のサービスが必要な場合に、このタイプを使ってはいけません。
  • Type=forking: 起動したプロセスが一旦フォークし、親プロセス側が終了したときに、 systemd はサービスが立ち上がったとみなします。このタイプでなくてもかまわないとき以外は、古典的なデーモンにはこのタイプを使って下さい。また PIDFile= を指定することで systemd はメインプロセスの情報を追い続けます。
  • Type=oneshot: シングルジョブを行い終了するスクリプト用のタイプです。また RemainAfterExit=yes を設定することで systemd はプロセスが終了した後もサービスがアクティブだとみなします。
  • Type=notify: Type=simple と同じですが、利用可能になったときにデーモンが systemd に信号を送るように条件がつけられます。この通知のリファレンス実装は libsystemd-daemon.so によって提供されています。
  • Type=dbus: 指定の BusName が DBus のシステムバスに乗ったときに使うことができるサービス。
  • Type=idle: ただし、サービスバイナリの実行は全てのジョブが処理されるまで待たされます。それ以外の挙動は Type=simple と非常に似ています。

Type の値のより詳しい説明は systemd.service(5) § OPTIONS を見て下さい。

ユニットファイルの編集

pacman との競合を避けるために、パッケージに含まれるユニットファイルは直接編集しないでください。パッケージに入っているユニットファイルを元のファイルに触れずに編集する安全な方法は2つあります: 新しいユニットファイルで完全に置き換えるか、ドロップインファイルを作成して既存のユニットファイルに上書きして適用させるかです。どちらの方法でも、変更を加えた後はユニットをリロードする必要があります。systemctl edit でユニットを編集するか (自動でユニットがリロードされます) または次のコマンドで全てのユニットをリロードしてください:

# systemctl daemon-reload
ヒント:
  • systemd-delta を使うことでどのファイルが上書きされ、どこが変更されたのか調べることができます。
  • ユニットファイルや関連するドロップインファイルの中身を見るには systemctl cat unit を使います。

ユニットファイルを置換する

ユニットファイル /usr/lib/systemd/system/unit を置き換えたいときは、/etc/systemd/system/unit ファイルを作成してユニットを 再有効化 することでシンボリックリンクをアップデートします。

もしくは、次を実行:

# systemctl edit --full unit

このコマンドはテキストエディタで /etc/systemd/system/unit を開いて (ファイルが存在しない場合はインストールされているユニットがコピーされます)、編集を終えた時に自動的にユニットをリロードします。

ノート: Pacman は元のユニットファイルが更新されても置き換えられたユニットファイルをアップデートしません。そのため、この方法ではシステムメンテナンスが多少厄介になります。この理由があるために、次のセクションで説明する方法の方が推奨されます。

ドロップインファイル

ユニットファイル /usr/lib/systemd/system/unit のドロップインファイルを作成するには、/etc/systemd/system/unit.d/ という名のディレクトリ (例: /etc/systemd/system/httpd.service.d/) を作成してその中に *.conf を配置します。このファイルを使ってオプションを上書きしたり追加してください。systemd*.conf ファイルをパースして元のユニットファイルの一番上に設定を適用します。

ドロップインファイルを作成する一番簡単な方法は次のコマンドを実行することです:

# systemctl edit unit

テキストエディタで /etc/systemd/system/unit.d/override.conf ファイルが開かれ (必要であればファイルが作成されます)、編集を終えた時に自動でユニットがリロードされます。

初期状態にリバート

systemctl edit を使って変更したユニットを元に戻したい場合、以下のコマンドを実行:

# systemctl revert unit

サンプル

例えば、ユニットに依存するデーモンを追加したい場合、以下のファイルを作成することができます:

/etc/systemd/system/unit.d/customdependency.conf
[Unit]
Requires=new dependency
After=new dependency

oneshot タイプでないユニットの ExecStart ディレクティブを置き換えるには、以下のファイルを作成します:

/etc/systemd/system/unit.d/customexec.conf
[Service]
ExecStart=
ExecStart=new command
ノート: ExecStart は置き換える前に空白にする必要があるので注意してください ([1])。タイマーの OnCalendar など複数回指定できるアイテムも同じです。

サービスが自動的に再起動されるようにするには:

/etc/systemd/system/unit.d/restart.conf
[Service]
Restart=always
RestartSec=30

ターゲット

Systemd では ランレベル に似たものとしてターゲットを使っています。ただしその挙動には少し違いがあります。それぞれのターゲットはナンバリングされる代わりに名前がつけられ、ある特定の目的のために作られ、複数のターゲットを同時に有効にできるようになっています。ターゲットによっては、他のターゲットのサービスを全て引継ぎ、そこにサービスを追加するよう実装されています。一般的な SystemVinit ランレベルに擬態する systemd ターゲットもあり、親しみのある telinit RUNLEVEL コマンドを使って使用するターゲットを切り替えることが可能です。

現在のターゲットを取得

systemd では runlevel の代わりに次のコマンドが使われます:

$ systemctl list-units --type=target

カスタムターゲットを作る

sysvinit ではランレベルごとに特定の目的が設定されています; 0, 1, 3, 5, 6 のランレベルには特定の sytemd ターゲットと一対一の対応関係が存在します。残念ながら、ユーザー定義のランレベル (2 や 4 など) で同じことをする良い方法はありません。もしあなたがそうしたいならば、既に存在しているランレベルをベースに新しい systemd ターゲット/etc/systemd/system/your target として作り (/usr/lib/systemd/system/graphical.target がサンプルになるかもしれません)、/etc/systemd/system/your target.wants ディレクトリを作って、有効にしたいサービスに /usr/lib/systemd/system/ からシンボリックリンクを貼ることが示唆されています。

SysV ランレベルと systemd ターゲットの対応表

SysV ランレベル systemd ターゲット 説明
0 runlevel0.target, poweroff.target システムを停止。
1, s, single runlevel1.target, rescue.target シングルユーザーモード。
2, 4 runlevel2.target, runlevel4.target, multi-user.target ユーザー定義・サイト指定ランレベル。デフォルトでは、3 と同一。
3 runlevel3.target, multi-user.target マルチユーザー、非グラフィカル。一般的にマルチコンソールやネットワークを介してログインするのに使われます。
5 runlevel5.target, graphical.target マルチユーザー、グラフィカル。通常、ランレベル 3 の全てのサービスにグラフィカルログインを付加。
6 runlevel6.target, reboot.target 再起動
emergency emergency.target 緊急シェル

現在のターゲットを変更する

systemd ではターゲットは ターゲットユニット を通して扱うことができます。ターゲットを変えるには次のようにします:

# systemctl isolate graphical.target

これは現在のターゲットを変えるだけで、次の起動時には影響がありません。SysVinit での、telinit 3telinit 5 のようなコマンドと同じです。

起動するデフォルトターゲットを変更

標準のターゲットは default.target で、これは graphical.target へのシンボリックリンクです。これは、古いランレベル5にほぼ対応します。

systemctl を使用して現在のターゲットを確認するには、次の手順に従います。

$ systemctl get-default

ブート先のデフォルトターゲットを変更するには、default.target シンボリックリンクを変更します。systemctl の場合

# systemctl set-default multi-user.target
Removed /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target.

または、次の カーネルパラメータ のいずれかをブートローダに追加します。

  • systemd.unit=multi-user.target (これは、古いランレベル3にほぼ対応しています)
  • systemd.unit=rescue.target (これは、古いランレベル1にほぼ対応しています)

デフォルトのターゲット順序

systemd は、次の順序に従って default.target を選択します。

  1. 上記のカーネルパラメータ
  2. /etc/systemd/system/default.target への Symlink
  3. /usr/lib/systemd/system/default.target への Symlink

systemd の構成要素

systemd のコンポーネントをいくつか(網羅的ではない)紹介します。

systemd.mount - マウント

systemd/etc/fstab で指定されたパーティションとファイルシステムのマウントを担当します。systemd-fstab-generator(8)/etc/fstab の全てのエントリを systemd ユニットに変換します; これは起動時とシステムマネージャの設定が再ロードされた時に実行されます。

systemd は通常の fstab 機能を拡張し、追加のマウントオプションを提供します。これらのオプションはマウントユニットの依存関係に影響を与えます。例えば、ネットワークが立ち上がった時だけマウントするようにしたり、他のパーティションがマウントされた時だけマウントするようにすることができます。特定の systemd マウントオプションの完全なリストは、通常 x-systemd. で始まり、 systemd.mount(5) § FSTAB で詳細に説明されています。

これらのマウントオプションの例として、自動マウントがあります。これは、ブート時に自動的にマウントするのではなく、リソースが必要な時にだけマウントすることを意味します。これは fstab#systemd による自動マウント で提供されています。

GPT パーティションの自動マウント

UEFI で起動したシステムでは、特定の条件が満たされると systemd-gpt-auto-generator(8)Discoverable Partitions Specification に従って GPT パーティションを自動マウントし、fstab から省略することができるようになります。

前提条件は以下の通りです。

  • ブートローダは LoaderDevicePartUUID EFI 変数を設定し、使用する EFI システムパーティションが特定できるようにする必要があります。これは systemd-boot, systemd-stub(7)rEFInd (not enabled by default) でサポートされています。これは bootctl を実行して Boot loader sets ESP information の状態をチェックすることによって確認できます。
  • ルートパーティションは、使用する EFI システムパーティションと同じ物理ディスク上になければなりません。自動マウントされる他のパーティションは、ルートパーティションと同じ物理ディスク上になければなりません。これは基本的に、オートマウントされる全てのパーティションは ESP と同じ物理ディスクを共有していなければならないことを意味します。
  • (必要であれば) /efi マウントポイントは手動で作成する必要があります。存在しない場合、systemd-gpt-auto-generator/boot を使用します。
警告: GPT 自動マウントを使用している既存のシステムに /efi を作成するときは、十分に注意してください。次回の起動時には /efi がデフォルトのマウントポイントとして使用され、/boot ディレクトリが空になってシステムが不整合状態になる可能性があります。恐らくカーネルとマイクロコードを再インストールしたり、initramfs を再生成したりする必要があるでしょう。
ヒント: パーティションのオートマウントを無効にするには、パーティションの type GUID を変更するか、パーティション属性ビットを 63 "do not automount" に設定します、詳しくは gdisk#GPT パーティションの自動マウントを防ぐ を参照してください。
/var

/var の自動マウントが動作するためには、PARTUUID がパーティションタイプの UUID (4d21b016-b534-45c2-a9fb-5c16e091fd2d) の SHA256 HMAC ハッシュにマシン ID でキーを付けたものと一致している必要があります。必要な PARTUUID は、以下の方法で取得できます。

$ systemd-id128 -u --app-specific=4d21b016-b534-45c2-a9fb-5c16e091fd2d machine-id
ノート: systemd-id128(1)はマシンIDを/etc/machine-id から読み取るので、システムをインストールする前に必要な PARTUUID を知ることは不可能です。

systemd-sysvcompat

systemd-sysvcompat (base の依存) の主な役割は、伝統的な linux init バイナリを提供することです。systemd により制御されているシステムでは、init はその systemd 実行ファイルへのシンボリックリンクに過ぎません。

さらに、SysVinit のユーザーが慣れ親しんでいるであろう4つの便利なショートカットも提供されています。便利なショートカットは halt(8), poweroff(8), reboot(8), shutdown(8) です。これら4つのコマンドはそれぞれ systemctl へのシンボリックリンクであり、systemd の動作に支配されます。そのため、#電源管理 での議論が適用されます。

systemd ベースのシステムは init= ブートパラメータ (例えば、/bin/init is in systemd-sysvcompat ?) と systemd ネイティブ systemctl コマンド引数を使うことで、これらの System V 互換の方法を諦めることができます。

systemd-tmpfiles - 一時ファイル

systemd-tmpfiles は揮発性ファイルや一時ファイル、ディレクトリの作成、削除、クリーンアップを行います。systemd-tmpfiles は /etc/tmpfiles.d//usr/lib/tmpfiles.d/ にある設定ファイルを読んで、実行するアクションを決めます。前者のディレクトリにある設定ファイルは後者のディレクトリにある設定ファイルより優先されます。

設定ファイルは通常サービスファイルと一緒に提供され、/usr/lib/tmpfiles.d/program.conf というスタイルで命名されます。例えば、Samba デーモンはディレクトリ /run/samba が存在し、正しいパーミッションを持っていることを期待します。そのため、samba パッケージはこの設定で出荷されます。

/usr/lib/tmpfiles.d/samba.conf
D /run/samba 0755 root root

設定ファイルは、起動時に特定のファイルに値を書き込むために使用することもできます。例えば、/etc/rc.local で USB デバイスからの wakeup を無効にするために echo USBE > /proc/acpi/wakeup を使った場合、代わりに以下の tmpfile を使用することができます。

/etc/tmpfiles.d/disable-usb-wake.conf
#    Path                  Mode UID  GID  Age Argument
w    /proc/acpi/wakeup     -    -    -    -   USBE

詳しくは systemd-tmpfiles(8) および tmpfiles.d(5) のマニュアルページを参照してください。

ノート: 適切なモジュールのロードが完了するまでに systemd-tmpfiles-setup サービスが起動することがあるため、この方法は /sys のオプションを設定するのには使えないかもしれません。この場合、modinfo module で設定したいオプションのパラメータがモジュールにあるかどうかを調べ、 /etc/modprobe.d にある設定ファイル でそのオプションを設定することができます。そうでない場合は、デバイスが現れたらすぐに適切な属性を設定するように udevルール を書く必要があります。

ヒントとテクニック

GUI 設定ツール

  • systemadmsystemd ユニット用のグラフィカルブラウザ。ユニットのリストを表示することができ、タイプでフィルタリングすることもできます。
https://cgit.freedesktop.org/systemd/systemd-ui/ || systemd-ui
  • SystemdGeniesystemd KDE 技術に基づく管理ユーティリティ。
https://invent.kde.org/system/systemdgenie || systemdgenie

ネットワークが稼働した後にサービスを実行する

ネットワークが立ち上がった後までサービスを遅らせるには、以下の依存関係を .service ファイルに含めます。

/etc/systemd/system/foo.service
[Unit]
...
Wants=network-online.target
After=network-online.target
...

ネットワークを管理する特定のアプリケーションのネットワーク待ち受けサービスも有効にして、network-online.target がネットワークの状態を適切に反映するようにする必要があります。

  • NetworkManager を利用している場合、NetworkManager-wait-online.serviceNetworkManager.service と一緒に有効になっています。systemctl is-enabled NetworkManager-wait-online.service で確認してください。有効になっていない場合は、NetworkManager.service再有効化 してください。
  • netctl の場合、netctl-wait-online.service有効化 して下さい (netctl-auto を使っていない場合。FS#75836 を参照してください)。
  • systemd-networkd を利用している場合、systemd-networkd-wait-online.servicesystemd-networkd.service と一緒に有効になっています。systemctl is-enabled systemd-networkd-wait-online.service でこの状態にあるかどうか確認してください。有効になっていない場合は、systemd-networkd.service再有効化 してください。

より詳しい説明は ネットワーク設定の同期のポイント の議論をご覧ください。

サービスが DNS クエリを実行する必要がある場合、追加で nss-lookup.target の後に命令する必要があります。

/etc/systemd/system/foo.service
[Unit]
...
Wants=network-online.target
After=network-online.target nss-lookup.target
...

systemd.special(7) § Special Passive System Units を参照してください。

nss-lookup.target が効果を発揮するためには、Wants=nss-lookup.target で実行を要求して、Before=nss-lookup.target で事前に実行されているように指定してあるサービスが必要です。通常、これはローカルの DNSリゾルバ によって行われます。

どのアクティブなサービスが nss-lookup.target で実行を要求しているのかを確認してください。

$ systemctl list-dependencies --reverse nss-lookup.target

インストールされたユニットをデフォルトで有効にする

Arch Linux の /usr/lib/systemd/system-preset/99-default.preset には disable * と記述されています。systemctl プリセットがデフォルトで全てのユニットを無効化するようになり、新しいパッケージがインストールされたときも、ユーザーが手動でユニットを有効化する必要があります。

自動的に有効化させたい場合、/etc/systemd/system-preset/99-default.preset から /dev/null にシンボリックリンクを作成して設定ファイルを上書きしてください。systemctl プリセットの設定ディレクトリで指定しないかぎり、インストールされた全てのユニットが、ユニットのタイプに関わらず有効化されるようになります。詳しくは systemd.preset(5) の man ページを参照。

ノート: デフォルトで全てのユニットを有効化すると、パッケージに(互いに両立しない)複数のユニットが含まれている場合に問題が生じます。systemctl プリセットはディストリビューションやシステム管理者によって使われることを意図されて作られています。衝突するユニットが有効化されてしまう場合、systemd.preset の man ページに書かれているように、プリセットの設定ファイルを使ってどちらか片方を明示的に無効化させる必要があります。

アプリケーション環境のサンドボックス化

ユニットファイルをサンドボックスとして作成して堅牢な仮想環境にアプリケーションやプロセスを分離させることが可能です。systemd は名前空間や、許可・拒否された ケイパビリティ のリスト、Cgroups を活用して実行環境を設定しプロセスをコンテナ化します—systemd.exec(5)

既存の systemd ユニットファイルを使ってアプリケーションをサンドボックス化するには strace, stderr, journalctl などでエラーや出力を確認しながら試行錯誤が必要です。まずは上流のドキュメントを検索して先例がないか確認すると良いでしょう。堅牢にし得る選択肢の出発点を探すには、以下のコマンドを実行します。

$ systemd-analyze security unit

systemd をサンドボックス化するいくつかの例は以下にあります。

サービスの失敗を通知する

サービス障害を通知するためには、OnFailure= ディレクティブを、例えば ドロップイン設定ファイル を使用して、該当するサービスファイルに追加する必要があります。このディレクティブを各サービスユニットに追加するには、トップレベルのドロップイン設定ファイルを使用します。トップレベルのドロップインについて詳しくは systemd.unit(5) を参照してください。

サービス用のトップレベルのドロップインを作成します。

/etc/systemd/system/service.d/toplevel-override.conf
[Unit]
OnFailure=failure-notification@%n

これにより、すべてのサービスファイルに OnFailure=failure-notification@%n が追加されます。some_service_unit が失敗すると、failure-notification@some_service_unitが開始されて通知(または実行するよう設定された任意のタスク)を処理するようになります。

テンプレートユニット failure-notification@ を作成します。

/etc/systemd/system/failure-notification@.service
[Unit]
Description=Send a notification about a failed systemd unit
After=network.target

[Service]
Type=simple
ExecStart=/path/to/failure-notification.sh %i

failure-notification.sh スクリプトを作成し、何をするか、どのように通知するか(メール、gotify、xmpp など)を定義します。%i は失敗したサービスユニットの名前で、スクリプトの引数として渡されます。

起動に失敗した場合に、何度も failure-notification@.service のインスタンスを起動する再帰を防ぐために、トップレベルのドロップインと同じ名前の空のドロップイン設定ファイルを作成します(空のサービスレベルのドロップイン設定ファイルはトップレベルのドロップインより優先され、後者をオーバーライドします。)

# mkdir -p /etc/systemd/system/failure-notification@.service.d
# touch /etc/systemd/system/failure-notification@.service.d/toplevel-override.conf

シャットダウン時に自動で外部HDDの電源を切る

もしシステムのシャットダウン時に外部 HDD の電源が正常に切れない場合は、その問題を修正することが望ましいでしょう。電源を切る最も便利な方法は udisks を使用することです。

udisks2.service有効化 します。

スクリプトを実行するサービスは以下のようになります。

/etc/systemd/system/handle_external_hdds.service
[Unit]
Requires=udisks2.service
Requires=graphical.target
After=graphical.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStop=/usr/local/bin/handle_external_hdds.sh
[Install]
WantedBy=graphical.target

handle_external_hdds.service有効化 します。

systemd の daemon-reload を実行して、新しい設定を適用します。

再起動するか graphical.target をリスタートして、正常に動作するか確認します。

1つのディスクの任意の量のパーティションを扱うスクリプトの例は以下のようになります。

/usr/local/bin/handle_external_hdds.sh
#!/bin/bash -u

declare -a uuids=(uuid_list)

# Only proceed if the drive is present.
if [[ ! -L "/dev/disk/by-uuid/${uuids[0]}" ]]; then
  exit 0
fi

for uuid in "${uuids[@]}"; do
  if findmnt "/dev/disk/by-uuid/$uuid"; then
    umount "/dev/disk/by-uuid/$uuid"
  fi
done

# udisksctl powers off proper drive even if its partition is supplied
udisksctl power-off -b "/dev/disk/by-uuid/${uuids[0]}"

uuid_list はスペース区切りの UUID リストで、例えば "uuid_1" "uuid_2" のように、チェックするデバイスのパーティションに対応します。

トラブルシューティング

systemd のエラーを調査する

起動に失敗している systemd サービスを探すには以下のコマンドを実行します。

$ systemctl --state=failed

失敗している理由を探すには、ログ出力を調べてください。詳細は systemd/ジャーナル#フィルタリング を参照してください。

ブート問題の診断

systemd は、ブートプロセスの問題を診断するためのいくつかのオプションを提供しています。一般的な手順や、systemdブートプロセス を引き継ぐ前のブートメッセージを残す方法については ブートデバッグ を参照してください。freedesktop.org の systemd デバッグドキュメント も参照してください。

特定のサービスの問題を診断

ある systemd サービスが上手く動作せず、どうなっているのか詳しい情報が欲しい場合、環境変数 SYSTEMD_LOG_LEVELdebug に設定してください。以下は systemd-networkd デーモンをデバッグモードで動かす例です:

サービスに ドロップインファイル を追加して、次の2行を追記してください。

[Service]
Environment=SYSTEMD_LOG_LEVEL=debug

あるいは、環境変数を手動でセットしても同じです。

# SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd

その後 systemd-networkdリスタート して、サービスのジャーナルを -f/--follow オプションで監視してください。

シャットダウン/再起動にものすごく時間がかかる

シャットダウンに非常に長い時間がかかる(もしくはフリーズする)場合、サービスが存在していないことが問題かもしれません。Systemd はサービスを kill する前に終了するのを待ちます。該当しているか確認するには、systemd wiki の Shutdown completes eventually を参照してください。

一般的な問題は、シャットダウンやサスペントのプロセスが停止することです。該当するかどうか確かめるには、以下のどちらかのコマンドを実行して、出力を確認してください。

# systemctl poweroff
Failed to power off system via logind: There's already a shutdown or sleep operation in progress
# systemctl list-jobs
JOB UNIT                    TYPE  STATE  
...
21593 systemd-suspend.service start running
21592 suspend.target          start waiting
..

これの 解決策 は、以下を実行してそれらのジョブをキャンセルすることです。

# systemctl cancel
# systemctl stop systemd-suspend.service

すると、シャットダウンやリブートをまた再開します。

短いプロセスがログを出力しない

journalctl -u foounit が短いプロセスについてなにも表示しない場合、かわりに PID を見て下さい。例えば、systemd-modules-load.service が失敗したとき、systemctl status systemd-modules-load によってそれが PID 123 として動いているとわかったら、その PID の journal の出力を見ることができます、journalctl -b _PID=123。journal の _SYSTEMD_UNIT_COMM などのメタデータは非同期に収集され /proc ディレクトリにプロセスが存在している時だけ表示されます。これを修正するには、SCM_CREDENTIALS のように、ソケット接続を使ってデータを流すようカーネルを変更する必要があります。簡単に言うと、これは バグ です。systemd の設計によって、即座に失敗するサービスはジャーナルに何も出力しない場合があることを覚えておいてください。

少しづつ起動時間が長くなっている

systemd-analyze を使用して、以前と比べて起動時間が明らかに伸びていると複数のユーザーが報告しています。systemd-analyze blame を使って NetworkManager が起動するのに異常に長い時間かかるようになったという報告もあります。

問題の原因として /var/log/journal が巨大になりすぎている可能性があります。そのような場合、フォルダ内のファイルを全て削除して journal のファイルサイズをここに書かれているように制限するよう設定すれば解決します(できればファイルを削除する前に、どこかに一時的にバックアップしてください)。

起動時に systemd-tmpfiles-setup.service の実行に失敗する

systemd 219 から、/usr/lib/tmpfiles.d/systemd.conf/var/log/journal 下のディレクトリに対して ACL 属性を指定しており、それによって、ジャーナルが存在するファイルシステムで ACL のサポートを有効にしなくてはならなくなっています。

/var/log/journal が存在するファイルシステムで ACL を有効化する方法はアクセス制御リスト#ACL の有効化を見て下さい。

リモートマシンで緊急モードを無効化

リモートマシン (例えば Azure や Google Cloud でホストしている仮想マシン) の緊急モードは無効化すると良いでしょう。緊急モードが起動すると、ネットワークからマシンに接続できなくなってしまうからです。無効化するには以下のコマンドを実行:

# systemctl mask emergency.service
# systemctl mask emergency.target

参照

翻訳ステータス: このページは en:Systemd の翻訳バージョンです。最後の翻訳日は 2022-10-27 です。もし英語版に 変更 があれば、翻訳の同期を手伝うことができます。