Open3
systemd
systemd
- systemd は、init システムの1つである。
- init システムとは、Linux カーネルに最初に起動されるプロセスのことであり、システムが利用可能な状態になるための起動処理を行うプログラムのことであり、PID は 1 になる。
- systemd は、SysV init (System V init または init とも) の後継の init システムという位置付けになっている。
Units
- systemd は、unit (ユニット) という単位で、リソースやサービスを管理する。
- unit のタイプには、以下のようなものがある。
- service (サービス): systemd によって管理・監督されるサービスのために使う。
- socket (ソケット): 複数の unit をグループ化して、unit の順序関係を同期させるために使う。
- device (デバイス)
- mount (マウント)
- automount (自動マウント)
- swap (スワップ)
- target (ターゲット)
- path (パス)
- timer (タイマー)
- slice (スライス)
- scope (スコープ)
- unit は ini 形式のプレーンテキストファイルで記述される。
-
[Unit]
セクション: unit のタイプに依存しない一般的な情報。-
Description=
: 人間用の unit の短いタイトル。 -
Documentation=
: unit のドキュメントへの URI (複数ある場合は、スペース区切り) 。 -
Wants=
: 他の unit への弱い依存関係。(詳細は次のコメント) -
Requires=
: 他の unit への強い依存関係。(詳細は次のコメント) Upholds=
-
After=
: どの unit よりも後に起動したいかを記述する。 -
Before=
: どの unit よりも前に起動したいかを記述する。
-
-
[Install]
セクション: unit のインストールに関する情報 (systemctl enable
/systemctl disable
コマンドの時に使用され、実行時には利用されない)-
WantedBy=
:systemctl enable
実行時に.wants/
ディレクトリ配下にシンボリックリンクが作成される。 -
RequiredBy=
:systemctl enable
実行時に.requries/
ディレクトリ配下にシンボリックリンクが作成される。 -
UpheldBy=
:systemctl enable
実行時に.upholds/
ディレクトリ配下にシンボリックリンクが作成される。
-
-
[Service]
セクション-
Type=
: サービスの開始の完了をマネージャーに通知するメカニズム-
simple
: メインのサービスプロセスがfork()
された直後 (新しいプロセスがexecve()
で対象のサービスバイナリを呼び出すよりも前) に、ユニットが開始されたと判断する。 -
exec
: メインのサービスバイナリが実行された直後 (新しいプロセスがfork()
されて、対象のサービスバイナリをexecve()
できた後) に、ユニットが開始されたと判断する。 -
forking
: マネージャーによってfork()
されたプロセスが終了した後 (exit()
した後) に、ユニットが開始されたと判断する。マネージャーによってfork()
されたプロセス (サービスの親プロセス) が、その後のメインサービスとなる子プロセスや必要なリソースをセットアップして終了する場合に用いる。 -
oneshot
: dbus
notify
notify-reload
idle
-
-
ExecStart=
: サービス開始時に実行されるコマンド -
ExecStartPre=
: -
ExecStartPost=
:
-
-
- 実行環境設定 (
[Service]
,[Socket]
,[Mount]
または[Swap]
)-
Environment=
: 実行されるプロセスの環境変数を設定する。 -
EnvironmentFile=
: 実行されるプロセスの環境変数をファイルから読み込み設定する。
-
systemctl
- systemd を管理するための CLI ツール
- unit ファイルコマンド
-
systemctl list-unit-files [PATTERN...]
: システムにインストールされている unit ファイルをリストする
-
参考リンク
- System and Service Manager
- systemd wiki
- systemd man
- Fedora Magazine
- What is an init system? - Fedora Magazine
- systemd unit file basics - Fedora Magazine
- systemd: Converting sysvinit scripts - Fedora Magazine
- systemd: Using the journal - Fedora Magazine
- systemd: Masking units - Fedora Magazine
- systemd: Unit dependencies and order - Fedora Magazine
- Systemd Timers for Scheduling Tasks - Fedora Magazine
- Understanding and administering systemd :: Fedora Docs
- Introduction to systemd Basics
依存関係 (requirement dependencies) と順序関係 (ordering dependencies)
- 依存関係と順序関係は、直交 (orthogonal) している。
- 例:
foo.service
が正常に動作するためにbar.service
が必要であっても、bar.service
がfoo.service
より先に起動してないといけないとは限らない。順序関係が必要なければ、これらを並行で起動させることができ、システムの起動時間の短縮に繋がる場合がある。
- 例:
依存関係 (requirement dependency) の記述の仕方
Wants=
/ WantedBy=
- 弱い依存関係を設定するために使用する。
- 対象のユニットが起動される場合は、
Wants=
にリストされたユニットも起動される。 -
Wants=
にリストされたユニットが正常に起動できたかどうかに関わらず、対象のユニットは起動される。 -
WantedBy=
は、Wants=
の逆を意味していて、リストされているユニットから依存されていることを意味する。
Requires=
/ RequiredBy=
-
Wants=
より強い依存関係を設定するために使用する。 - 対象のユニットが起動される場合は、
Requires=
にリストされたユニットも起動される。 -
Requires=
にリストされたユニットが正常に起動できず、その起動に失敗したユニットがAfter=
にも含まれていた場合は、対象のユニットは起動されない。 -
After=
に含まれているがどうかに関わらず、Requires=
にリストされたユニットが停止 or 再起動された場合には、対象のユニットも停止 or 再起動される。 -
RequiredBy=
は、Requires=
の逆を意味していて、リストされているユニットから依存されていることを意味する。
順序関係 (ordering dependency) の記述の仕方
Before=
-
Before=
にリストされたユニットよりも先に、対象のユニットが起動されなければならない。
After=
-
After=
にリストされたユニットよりも後に、対象のユニットが起動されなければならない。
確認方法
依存関係の確認方法
指定したユニットが依存しているユニットをリストする。
$ sudo systemctl list-dependencies [<unit>...]
指定したユニットに依存しているユニットをリストする。
$ sudo systemctl list-dependencies --reverse [<unit>...]
順序関係の確認方法
指定したユニットよりも後に起動すべきユニットをリストする。
$ sudo systemctl list-dependencies --before [<unit>...]
指定したユニットよりも前に起動しているべきユニットをリストする。
$ sudo systemctl list-dependencies --after [<unit>...]
Hands-On
Amazon Linux 2023 AMI で色々実際に確認していく。
ちゃんと systemd は PID 1 で起動してる。
$ ps x -q 1
PID TTY STAT TIME COMMAND
1 ? Ss 0:03 /usr/lib/systemd/systemd --switched-root --system --deserialize=32
kernel のコマンドラインには init=
は指定されていないので、/sbin/init
が呼び出されているはず。
$ cat /proc/cmdline
BOOT_IMAGE=(hd0,gpt1)/boot/vmlinuz-6.1.75-99.163.amzn2023.x86_64 root=UUID=f2901285-17a4-4f0e-b17b-213de684d2c7 ro console=tty0 console=ttyS0,115200n8 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0 selinux=1 security=selinux quiet
/sbin/init
は、systemd
へのシンボリックリンクになっている。
$ ls -l /sbin/init
lrwxrwxrwx. 1 root root 22 Jan 17 22:52 /sbin/init -> ../lib/systemd/systemd
しかし、/lib/systemd/systemd
が /usr/lib/systemd/systemd
へのシンボリックリンクになっているわけではない。ただし、/lib
が /usr/lib
へのシンボリックリンクになっているので、/lib/systemd/systemd
と /usr/lib/systemd/systemd
は同じファイルである。
$ ls -l /lib/systemd/systemd
-rwxr-xr-x. 1 root root 102904 Jan 17 22:52 /lib/systemd/systemd
$ ls -l /lib
lrwxrwxrwx. 1 root root 7 Jan 30 2023 /lib -> usr/lib
$ realpath /sbin/init
/usr/lib/systemd/systemd
デフォルトのターゲットは graphical.target
になっており、default.target
はちゃんと graphical.target
へのシンボリックリンクになっている。
$ systemctl get-default
graphical.target
$ ls -l /usr/lib/systemd/system/default.target
lrwxrwxrwx. 1 root root 16 Jan 17 22:52 /usr/lib/systemd/system/default.target -> graphical.target
graphical.target
の中身は以下の通り。
$ systemctl cat graphical.target
# /usr/lib/systemd/system/graphical.target
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
システムには 316 個の unit ファイルが入ってた。
$ systemctl list-unit-files
UNIT FILE STATE PRESET
boot-efi.automount generated -
# snipped
update-motd.timer enabled enabled
316 unit files listed.