「Systemd」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(→‎電源管理: 情報を更新)
 
(3人の利用者による、間の27版が非表示)
18行目: 18行目:
 
{{Related|デーモン#デーモン一覧}}
 
{{Related|デーモン#デーモン一覧}}
 
{{Related|udev}}
 
{{Related|udev}}
{{Related|ブートパフォーマンスの向上}}
+
{{Related|パフォーマンスの向上/ブートプロセス}}
 
{{Related|ユーザーにシャットダウンを許可}}
 
{{Related|ユーザーにシャットダウンを許可}}
 
{{Related articles end}}
 
{{Related articles end}}
25行目: 25行目:
   
 
:'''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 フォーラムへのこの投稿]をご覧ください。}}
115行目: 117行目:
 
# これは変更されたユニットに設定の再読み込みを要求しません (アクション '''Reload''' を参照して下さい)。
 
# これは変更されたユニットに設定の再読み込みを要求しません (アクション '''Reload''' を参照して下さい)。
 
# 例えば、最後に有効化してからその {{ic|[Install]}} セクションが変更された場合。
 
# 例えば、最後に有効化してからその {{ic|[Install]}} セクションが変更された場合。
# 手動でも依存関係としても、マスクは危険です。既存のマスクされたユニットをチェックします。{{bc|1=# systemctl list-unit-files --state=masked}}
+
# 手動でも依存関係としても、マスクは危険です。既存のマスクされたユニットをチェックします。{{bc|1=$ systemctl list-unit-files --state=masked}}
   
 
=== 電源管理 ===
 
=== 電源管理 ===
   
非特権ユーザーでの電源管理には、[[polkit]] が必要です。ローカルの ''systemd-logind'' ユーザーセッションで、他のセッションがアクティブでない場合、以下のコマンドは root 権限がなくても動作します。そうでない場合例えば、他のユーザーが tty にログインしているなど、''systemd'' は自動的に root パスワードを要求します。
+
非特権ユーザーでの電源管理には、[[polkit]] が必要です。ローカルの ''systemd-logind'' ユーザーセッションで、他のセッションがアクティブでない場合、以下のコマンドは root 権限がなくても動作します。そうでない場合(例えば、他のユーザーが tty にログインしているなど)、''systemd'' は自動的に root パスワードを要求します。
   
 
{| class="wikitable"
 
{| class="wikitable"
133行目: 135行目:
 
|-
 
|-
 
| システムをハイブリッドスリープ状態にする (または suspend-to-both) にする || {{ic|systemctl hybrid-sleep}}
 
| システムをハイブリッドスリープ状態にする (または suspend-to-both) にする || {{ic|systemctl hybrid-sleep}}
  +
|-
  +
| まずシステムをサスペンドし、設定された時間の経過後にウェイクアップしてシステムを休止状態にする || {{ic|systemctl suspend-then-hibernate}}
 
|-
 
|-
 
|}
 
|}
154行目: 158行目:
 
=== 依存関係を解決する ===
 
=== 依存関係を解決する ===
   
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}} が起動し終わってからにする必要があります。
307行目: 311行目:
 
== systemd の構成要素 ==
 
== systemd の構成要素 ==
   
''systemd'' のコンポーネントをいくつか網羅的ではない紹介します。
+
''systemd'' のコンポーネントをいくつか(網羅的ではない)紹介します。
   
 
* [[systemd-boot]] — シンプルな UEFI [[Arch ブートプロセス|ブートマネージャー]] です。
 
* [[systemd-boot]] — シンプルな UEFI [[Arch ブートプロセス|ブートマネージャー]] です。
404行目: 408行目:
   
 
* [[NetworkManager]] を利用している場合、{{ic|NetworkManager-wait-online.service}} は {{ic|NetworkManager.service}} と一緒に有効になっています。{{ic|systemctl is-enabled NetworkManager-wait-online.service}} で確認してください。有効になっていない場合は、{{ic|NetworkManager.service}} を [[systemd#ユニットを使う|再有効化]] してください。
 
* [[NetworkManager]] を利用している場合、{{ic|NetworkManager-wait-online.service}} は {{ic|NetworkManager.service}} と一緒に有効になっています。{{ic|systemctl is-enabled NetworkManager-wait-online.service}} で確認してください。有効になっていない場合は、{{ic|NetworkManager.service}} を [[systemd#ユニットを使う|再有効化]] してください。
* [[netctl]] の場合、{{ic|netctl-wait-online.service}} を [[systemd#ユニットを使う|有効化]] して下さい。
+
* [[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#ユニットを使う|再有効化]] してください。
 
* [[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#ユニットを使う|再有効化]] してください。
   
433行目: 437行目:
 
自動的に有効化させたい場合、{{ic|/etc/systemd/system-preset/99-default.preset}} から {{ic|/dev/null}} にシンボリックリンクを作成して設定ファイルを上書きしてください。systemctl プリセットの設定ディレクトリで指定しないかぎり、インストールされた全てのユニットが、ユニットのタイプに関わらず有効化されるようになります。詳しくは {{man|5|systemd.preset}} の man ページを参照。
 
自動的に有効化させたい場合、{{ic|/etc/systemd/system-preset/99-default.preset}} から {{ic|/dev/null}} にシンボリックリンクを作成して設定ファイルを上書きしてください。systemctl プリセットの設定ディレクトリで指定しないかぎり、インストールされた全てのユニットが、ユニットのタイプに関わらず有効化されるようになります。詳しくは {{man|5|systemd.preset}} の man ページを参照。
   
{{Note|デフォルトで全てのユニットを有効化すると、パッケージに互いに両立しない複数のユニットが含まれている場合に問題が生じます。systemctl プリセットはディストリビューションやシステム管理者によって使われることを意図されて作られています。衝突するユニットが有効化されてしまう場合、{{ic|systemd.preset}} の man ページに書かれているように、プリセットの設定ファイルを使ってどちらか片方を明示的に無効化させる必要があります。}}
+
{{Note|デフォルトで全てのユニットを有効化すると、パッケージに(互いに両立しない)複数のユニットが含まれている場合に問題が生じます。systemctl プリセットはディストリビューションやシステム管理者によって使われることを意図されて作られています。衝突するユニットが有効化されてしまう場合、{{ic|systemd.preset}} の man ページに書かれているように、プリセットの設定ファイルを使ってどちらか片方を明示的に無効化させる必要があります。}}
   
 
=== アプリケーション環境のサンドボックス化 ===
 
=== アプリケーション環境のサンドボックス化 ===
ユニットファイルをサンドボックスとして作成して堅牢な仮想環境にアプリケーションやプロセスを分離させることが可能です。systemd は[[wikipedia:Linux_namespaces|名前空間]]や[[ケイパビリティ]]のホワイトリスト・ブラックリスト、[[Cgroups]] を活用して [https://www.freedesktop.org/software/systemd/man/systemd.exec.html 実行環境を設定] しプロセスをコンテナ化します。
+
ユニットファイルをサンドボックスとして作成して堅牢な仮想環境にアプリケーションやプロセスを分離させることが可能です。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] などでエラーや出力を確認しながら試行錯誤が必要です。まずは上流のドキュメントを検索して先例がないか確認すると良いでしょう。
+
既存の systemd ユニットファイルを使ってアプリケーションをサンドボックス化するには {{Pkg|strace}}, [[wikipedia:ja:標準ストリーム#標準エラー出力 (stderr)|stderr]], [https://www.freedesktop.org/software/systemd/man/journalctl.html journalctl] などでエラーや出力を確認しながら試行錯誤が必要です。まずは上流のドキュメントを検索して先例がないか確認すると良いでしょう。堅牢にし得る選択肢の出発点を探すには、以下のコマンドを実行します
   
  +
$ systemd-analyze security ''unit''
{{Ic|CapabilityBoundingSet}} では許可されるケイパビリティのホワイトリストを定義できますが、特定のケイパビリティをブラックリストに追加する用途で使うこともできます。例: {{ic|1=CapabilityBoundingSet=~ CAP_SYS_ADMIN}}。
 
  +
  +
''systemd'' をサンドボックス化するいくつかの例は以下にあります。
  +
  +
* {{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}}
   
 
=== サービスの失敗を通知する ===
 
=== サービスの失敗を通知する ===
453行目: 462行目:
 
}}
 
}}
   
これにより、すべてのサービスファイルに {{ic|1=OnFailure=failure-notification@%n}} が追加されます。''some_service_unit'' が失敗すると、{{ic|failure-notification@''some_service_unit''}}が開始されて通知または実行するよう設定された任意のタスクを処理するようになります。
+
これにより、すべてのサービスファイルに {{ic|1=OnFailure=failure-notification@%n}} が追加されます。''some_service_unit'' が失敗すると、{{ic|failure-notification@''some_service_unit''}}が開始されて通知(または実行するよう設定された任意のタスク)を処理するようになります。
   
 
テンプレートユニット {{ic|failure-notification@}} を作成します。
 
テンプレートユニット {{ic|failure-notification@}} を作成します。
467行目: 476行目:
 
}}
 
}}
   
{{ic|failure-notification.sh}} スクリプトを作成し、何をするか、どのように通知するかメール、gotify、xmpp などを定義します。{{ic|%i}} は失敗したサービスユニットの名前で、スクリプトの引数として渡されます。
+
{{ic|failure-notification.sh}} スクリプトを作成し、何をするか、どのように通知するか(メール、gotify、xmpp など)を定義します。{{ic|%i}} は失敗したサービスユニットの名前で、スクリプトの引数として渡されます。
   
起動に失敗した場合に、何度も {{ic|failure-notification@.service}} のインスタンスを起動する再帰を防ぐために、トップレベルのドロップインと同じ名前の空のドロップイン設定ファイルを作成します空のサービスレベルのドロップイン設定ファイルはトップレベルのドロップインより優先され、後者をオーバーライドします。
+
起動に失敗した場合に、何度も {{ic|failure-notification@.service}} のインスタンスを起動する再帰を防ぐために、トップレベルのドロップインと同じ名前の空のドロップイン設定ファイルを作成します(空のサービスレベルのドロップイン設定ファイルはトップレベルのドロップインより優先され、後者をオーバーライドします。)
   
 
# mkdir -p /etc/systemd/system/failure-notification@.service.d
 
# mkdir -p /etc/systemd/system/failure-notification@.service.d
 
# touch /etc/systemd/system/failure-notification@.service.d/toplevel-override.conf
 
# touch /etc/systemd/system/failure-notification@.service.d/toplevel-override.conf
   
  +
=== シャットダウン時に自動で外部HDDの電源を切る ===
== トラブルシューティング ==
 
   
  +
もしシステムのシャットダウン時に外部 HDD の電源が正常に切れない場合は、その問題を修正することが望ましいでしょう。電源を切る最も便利な方法は [[udisks]] を使用することです。
=== systemd のエラーを調査する ===
 
   
例えば、{{ic|systemd-modules-load}} サービスのエラー調べるとします:
+
{{ic|udisks2.service}} を [[有効化]] します
   
  +
スクリプトを実行するサービスは以下のようになります。
1. 起動に失敗している systemd サービスを探しましょう:
 
{{hc|1=$ systemctl --state=failed|2=
 
systemd-modules-load.service loaded '''failed failed''' Load Kernel Modules}}
 
   
  +
{{hc|/etc/systemd/system/handle_external_hdds.service|2=
もしくは ''systemd'' のライブログメッセージを確認します:
 
  +
[Unit]
$ journalctl -fp err
 
  +
Requires=udisks2.service
 
  +
Requires=graphical.target
2. Ok, {{ic|systemd-modules-load}} サービスに問題が発生していることがわかりました。詳しく見てみましょう:
 
  +
After=graphical.target
{{hc|$ systemctl status systemd-modules-load|2=
 
  +
[Service]
systemd-modules-load.service - Load Kernel Modules
 
  +
Type=oneshot
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
 
  +
RemainAfterExit=yes
Active: '''failed''' (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
 
  +
ExecStop=/usr/local/bin/handle_external_hdds.sh
Docs: man:systemd-modules-load.service(8).
 
  +
[Install]
man:modules-load.d(5)
 
  +
WantedBy=graphical.target
Process: '''15630''' ExecStart=/usr/lib/systemd/systemd-modules-load ('''code=exited, status=1/FAILURE''')
 
 
}}
 
}}
{{ic|Process ID}} が載っていない場合は、{{ic|systemctl restart systemd-modules-load}} で失敗したサービスを再実行してください。
 
   
  +
{{ic|handle_external_hdds.service}} を [[有効化]] します。
3. エラーを細かく調べるためのプロセス ID (PID) を入手しました。{{ic|Process ID}} を使って (ここでは: 15630) 以下のコマンドを実行してください:
 
{{hc|1=$ journalctl _PID=15630|2=
 
-- Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. --
 
Aug 25 11:48:13 mypc systemd-modules-load[15630]: '''Failed to find module 'blacklist usblp''''
 
Aug 25 11:48:13 mypc systemd-modules-load[15630]: '''Failed to find module 'install usblp /bin/false''''
 
}}
 
   
  +
systemd の [[daemon-reload]] を実行して、新しい設定を適用します。
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
 
...
 
}}
 
   
  +
再起動するか {{ic|graphical.target}} をリスタートして、正常に動作するか確認します。
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
 
}}
 
   
  +
1つのディスクの任意の量のパーティションを扱うスクリプトの例は以下のようになります。
6. では、{{ic|systemd-modules-load}} を起動してみることにします:
 
$ systemctl start systemd-modules-load
 
成功した場合、何も表示されないはずです。何かエラーが表示される場合は、手順 3 に戻って下さい。そして新しい PID を使って残った問題を解決してください。
 
   
  +
{{hc|/usr/local/bin/handle_external_hdds.sh|2=
全て問題ないならば、サービスが正しく起動したか次のコマンドで確認することができます:
 
  +
#!/bin/bash -u
{{hc|$ systemctl status systemd-modules-load|2=
 
  +
systemd-modules-load.service - Load Kernel Modules
 
  +
declare -a uuids=(''uuid_list'')
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
 
  +
# Only proceed if the drive is present.
Docs: man:systemd-modules-load.service(8)
 
  +
if <nowiki>[[ ! -L "/dev/disk/by-uuid/${uuids[0]}" ]]</nowiki>; then
man:modules-load.d(5)
 
  +
exit 0
Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
 
  +
fi
Aug 25 12:22:31 mypc systemd[1]: '''Started Load Kernel Modules'''.
 
  +
  +
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 のエラーを調査する ===
カーネルコマンドラインに次のパラメータをつけて起動してください: {{ic|<nowiki>systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M</nowiki>}}。
 
   
  +
起動に失敗している systemd サービスを探すには以下のコマンドを実行します。
詳しくは[[ブートデバッグ]]や [https://freedesktop.org/wiki/Software/systemd/Debugging] を見て下さい。
 
  +
  +
$ systemctl --state=failed
  +
  +
失敗している理由を探すには、ログ出力を調べてください。詳細は [[systemd/ジャーナル#フィルタリング]] を参照してください。
  +
  +
=== ブート問題の診断 ===
  +
  +
''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-networkd'' を [[リスタート]] して、サービスのジャーナルを {{ic|-f}}/{{ic|--follow}} オプションで監視してください。
   
 
=== シャットダウン/再起動にものすごく時間がかかる ===
 
=== シャットダウン/再起動にものすごく時間がかかる ===
   
シャットダウンに非常に長い時間がかかるもしくはフリーズする場合、サービスが存在していないことが問題かもしれません。Systemd はサービスを kill する前に終了するのを待ちます。なにが原因るには [https://freedesktop.org/wiki/Software/systemd/Debugging/#shutdowncompleteseventually この記事] をさい。
+
シャットダウンに非常に長い時間がかかる(もしくはフリーズする)場合、サービスが存在していないことが問題かもしれません。Systemd はサービスを kill する前に終了するのを待ちます。該当している確認するには、''systemd'' wiki の [https://freedesktop.org/wiki/Software/systemd/Debugging/#shutdowncompleteseventually Shutdown completes eventually] を参照しください。
   
  +
一般的な問題は、シャットダウンやサスペントのプロセスが停止することです。該当するかどうか確かめるには、以下のどちらかのコマンドを実行して、出力を確認してください。
=== 短いプロセスがログを出力しない ===
 
   
  +
{{hc
{{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}} のように、ソケット接続を使ってデータを流すようカーネルを変更する必要があります。
 
  +
|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 解決策] は、以下を実行してそれらのジョブをキャンセルすることです。
{{ic|/etc/systemd/coredump.conf}} ファイルを編集して次の行を追加してください:
 
Storage=none
 
   
  +
# systemctl cancel
そして設定をリロードしてください:
 
# systemctl daemon-reload
+
# systemctl stop systemd-suspend.service
  +
  +
すると、シャットダウンやリブートをまた再開します。
  +
  +
=== 短いプロセスがログを出力しない ===
  +
  +
{{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'' の設計によって、即座に失敗するサービスはジャーナルに何も出力しない場合があることを覚えておいてください。
   
 
===少しづつ起動時間が長くなっている===
 
===少しづつ起動時間が長くなっている===
580行目: 598行目:
 
{{ic|systemd-analyze}} を使用して、以前と比べて起動時間が明らかに伸びていると複数のユーザーが報告しています。{{ic|systemd-analyze blame}} を使って [[NetworkManager]] が起動するのに異常に長い時間かかるようになったという報告もあります。
 
{{ic|systemd-analyze}} を使用して、以前と比べて起動時間が明らかに伸びていると複数のユーザーが報告しています。{{ic|systemd-analyze blame}} を使って [[NetworkManager]] が起動するのに異常に長い時間かかるようになったという報告もあります。
   
問題の原因として {{ic|/var/log/journal}} が巨大になりすぎている可能性があります。そのような場合、フォルダ内のファイルを全て削除して journal のファイルサイズを[[systemd/ジャーナル#journal のサイズ制限|ここ]]に書かれているように制限するよう設定すれば解決しますできればファイルを削除する前に、どこかに一時的にバックアップしてください
+
問題の原因として {{ic|/var/log/journal}} が巨大になりすぎている可能性があります。そのような場合、フォルダ内のファイルを全て削除して journal のファイルサイズを[[systemd/ジャーナル#journal のサイズ制限|ここ]]に書かれているように制限するよう設定すれば解決します(できればファイルを削除する前に、どこかに一時的にバックアップしてください)
   
 
=== 起動時に systemd-tmpfiles-setup.service の実行に失敗する ===
 
=== 起動時に systemd-tmpfiles-setup.service の実行に失敗する ===
587行目: 605行目:
   
 
{{ic|/var/log/journal}} が存在するファイルシステムで ACL を有効化する方法は[[アクセス制御リスト#ACL の有効化]]を見て下さい。
 
{{ic|/var/log/journal}} が存在するファイルシステムで ACL を有効化する方法は[[アクセス制御リスト#ACL の有効化]]を見て下さい。
 
=== systemctl enable で /etc/systemd/system にシンボリックリンクが作成されない ===
 
 
{{ic|/etc/systemd/system/''foo''.service}} がシンボリックリンクの場合、{{ic|systemctl enable ''foo''.service}} を実行しても以下のエラーで失敗します:
 
 
Failed to issue method call: No such file or directory
 
 
これは systemd の [https://bugzilla.redhat.com/show_bug.cgi?id=955379#c14 仕様] です。絶対パスで有効にすることで回避できます:
 
 
# systemctl enable ''/absolute/path/foo''.service
 
   
 
=== リモートマシンで緊急モードを無効化 ===
 
=== リモートマシンで緊急モードを無効化 ===
607行目: 615行目:
 
== 参照 ==
 
== 参照 ==
   
  +
* [[Wikipedia:systemd]]
*[https://www.freedesktop.org/wiki/Software/systemd 公式ウェブサイト]
 
  +
* [https://systemd.io/ 公式ウェブサイト]
*[[Wikipedia:ja:systemd|Wikipedia の記事]]
 
  +
** [https://www.freedesktop.org/wiki/Software/systemd/Optimizations systemd の最適化]
*[http://0pointer.de/public/systemd-man/ Manual Pages]
 
*[https://freedesktop.org/wiki/Software/systemd/Optimizations systemd Optimizations]
+
** [https://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions systemd FAQ]
*[https://www.freedesktop.org/wiki/Software/systemd/FrequentlyAskedQuestions FAQ]
+
** [https://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks systemd のヒントとテクニック]
  +
* {{man|1|systemd}}
*[https://www.freedesktop.org/wiki/Software/systemd/TipsAndTricks Tips And Tricks]
 
  +
* その他のディストリビューション
*[http://0pointer.de/public/systemd-ebook-psankar.pdf systemd for Administrators (PDF)]
 
  +
** [[Gentoo:Systemd]]
*[https://fedoraproject.org/wiki/Systemd Fedora プロジェクトによる systemd の説明]
 
  +
** [[Fedora:Systemd]]
*[https://fedoraproject.org/wiki/How_to_debug_Systemd_problems systemd の問題をデバッグする方法]
 
  +
** [[Fedora:How to debug Systemd problems]]
*[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'' マガジンに記載された二部からなる紹介記事
 
  +
** [[Fedora:SysVinit to Systemd Cheatsheet]]
*[http://0pointer.de/blog/projects/systemd.html Lennart のブログ記事]
 
  +
** [[Debian:systemd]]
*[http://0pointer.de/blog/projects/systemd-update.html ステータスアップデート]
 
  +
* [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]
*[http://0pointer.de/blog/projects/systemd-update-2.html ステータスアップデート 2]
 
*[http://0pointer.de/blog/projects/systemd-update-3.html ステアップート 3]
+
* [https://containersolutions.github.io/runbooks/posts/linux/debug-systemd-service-units Systemd サバッグ]
*[http://0pointer.de/blog/projects/why.html 近況]
+
* [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://fedoraproject.org/wiki/SysVinit_to_Systemd_Cheatsheet Fedora の SysVinit と systemd のチートシート]
 
  +
* [https://dvdhrm.wordpress.com/2013/08/24/session-management-on-linux/ systemd-logind によるセッション管理]
*[[Emacs#Systemd ファイルのシンタックスハイライト|Emacs の Systemd ファイルのシンタックスハイライト]]
 
  +
* [[Emacs#Syntax highlighting for systemd Files|Emacs Systemd ファイルの構文強調表示]]
*[https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units digital ocean のチュートリアル]
 
  +
* [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-03-03|716611}}
+
{{TranslationStatus|Systemd|2022-10-27|753672}}

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 です。もし英語版に 変更 があれば、翻訳の同期を手伝うことができます。