hiroの長い冒険日記

主にコンピュータ周辺の興味を持った内容を綴ります

systemd ... SysVinit との違いと動作について その8

当日記ではアフィリエイト広告を利用しています

lm-sensors を入れた際に、systemd unit も install されていた。
hiro20180901.hatenablog.com

$ dpkg -L lm-sensors
... 略 ...
/lib
/lib/systemd
/lib/systemd/system
/lib/systemd/system/lm-sensors.service
... 略 ...

multi-user.target を WantedBy するようになっていて、依存性で有効になっていた。新しい package を入れた際には、こういう風にして調べていくと分かってくる。

前回までに、systemd の service unit (130 units) について、機能を調べてみた。

hiro20180901.hatenablog.com

これで、mount unit と service unit について、ざっくりだが調べ終わった。次は、target unit について調べてみる。

target unit

単体で binary を実行するのではなく、複数の unit を取りまとめるのが target unit。また、並列で起動する中で同期 point を作る為にも使用されている。
equj65.net

$ systemctl list-unit-files *target 
UNIT FILE                 STATE   
basic.target              static  
bluetooth.target          static  
busnames.target           static  
cryptsetup-pre.target     static  
cryptsetup.target         static  
ctrl-alt-del.target       disabled
default.target            enabled 
emergency.target          static  
exit.target               disabled
final.target              static  
getty.target              static  
graphical.target          enabled 
halt.target               disabled
hibernate.target          static  
hybrid-sleep.target       static  
initrd-fs.target          static  
initrd-root-device.target static  
initrd-root-fs.target     static  
initrd-switch-root.target static  
initrd.target             static  
kexec.target              disabled
local-fs-pre.target       static  
local-fs.target           static  
multi-user.target         static  
network-online.target     static  
network-pre.target        static  
network.target            static  
nss-lookup.target         static  
nss-user-lookup.target    static  
paths.target              static  
poweroff.target           disabled
printer.target            static  
reboot.target             disabled
remote-fs-pre.target      static  
remote-fs.target          enabled 
rescue.target             disabled
rpcbind.target            static  
runlevel0.target          disabled
runlevel1.target          disabled
runlevel2.target          static  
runlevel3.target          static  
runlevel4.target          static  
runlevel5.target          enabled 
runlevel6.target          disabled
shutdown.target           static  
sigpwr.target             static  
sleep.target              static  
slices.target             static  
smartcard.target          static  
sockets.target            static  
sound.target              static  
suspend.target            static  
swap.target               static  
sysinit.target            static  
system-update.target      static  
time-sync.target          static  
timers.target             static  
umount.target             static  

58 unit files listed.

$ systemctl list-units *target 
UNIT                  LOAD   ACTIVE SUB    DESCRIPTION                                                                                                                                                                                       
basic.target          loaded active active Basic System                                                                                                                                                                                      
cryptsetup.target     loaded active active Encrypted Volumes                                                                                                                                                                                 
getty.target          loaded active active Login Prompts                                                                                                                                                                                     
graphical.target      loaded active active Graphical Interface                                                                                                                                                                               
local-fs-pre.target   loaded active active Local File Systems (Pre)                                                                                                                                                                          
local-fs.target       loaded active active Local File Systems                                                                                                                                                                                
multi-user.target     loaded active active Multi-User System                                                                                                                                                                                 
network-online.target loaded active active Network is Online                                                                                                                                                                                 
network.target        loaded active active Network                                                                                                                                                                                           
paths.target          loaded active active Paths                                                                                                                                                                                             
remote-fs.target      loaded active active Remote File Systems                                                                                                                                                                               
slices.target         loaded active active Slices                                                                                                                                                                                            
sockets.target        loaded active active Sockets                                                                                                                                                                                           
sound.target          loaded active active Sound Card                                                                                                                                                                                        
swap.target           loaded active active Swap                                                                                                                                                                                              
sysinit.target        loaded active active System Initialization                                                                                                                                                                             
time-sync.target      loaded active active System Time Synchronized                                                                                                                                                                          
timers.target         loaded active active Timers                                                                                                                                                                                            

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

18 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

58 units のうち、読み込まれているのは 18 units。また、次の9個の target unit は symbolic link となっている。

$ ls -l *target | grep -e '->' | awk '{print $9,$10,$11}'
ctrl-alt-del.target -> reboot.target
default.target -> graphical.target
runlevel0.target -> poweroff.target
runlevel1.target -> rescue.target
runlevel2.target -> multi-user.target
runlevel3.target -> multi-user.target
runlevel4.target -> multi-user.target
runlevel5.target -> graphical.target
runlevel6.target -> reboot.target

man systemd.special を見ると、幾つかの target unit は special systemd unit と呼ばれている。ArchLinux JP Project に日本語の man があったのでリンク:
man.kusakata.com

以下、個々の target unit について、上記リンク先の内容と target unit の中身を読んで理解した内容を記載した。特記無き場合は .target を省略している。target unit には順番があると思うが、とりあえず alphabet order で。

basic

  • 起動初期の sysinit や slices、sockets 等の unit 起動完了を待って、最終的な default.target までの間に起動させる service 等を順次起動させる。つまり、初期設定の完了を待ち、各種 daemon を起動できるような準備が出来てから次に進める為の target unit。
  • その為、各種 service unit に、basic.target への After 依存を自動的に追加する。daemon を入れて service unit を有効にすると、自動で起動するのは何故か疑問だったが、basic.target の After 依存があるからなのか。
  • basic.target の位置付けは man bootup と systemctl list-dependencies が分かりやすい。
  • man bootup は initrd 部分の理解にも参考になりそう。

bluetooth、printer、smartcard、sound

  • man systemd.special に拠ると、「デバイスの特殊なシステムユニット」らしい。依存性ではなく、デバイスが認識された時に有効になる。
  • 今の PC には Bluetooth device、printer、smartcard は乗っていないので static。
  • sound.target は有効になっている。kernel module が読み込まれて device が使えるようになると、sound.target が有効になって systemd の message が出力されている。

$ sudo journalctl
... 略 ...
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0: autoconfig for ALC887: line_outs=1 (0x14/0x0/0x0/0x0/0x0) type:line
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:    hp_outs=1 (0x1b/0x0/0x0/0x0/0x0)
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:    mono: mono_out=0x0
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:    dig-out=0x11/0x1e
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:    inputs:
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:      Front Mic=0x19
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:      Rear Mic=0x18
Apr 07 17:28:29 debian kernel: snd_hda_codec_realtek hdaudioC0D0:      Line=0x1a
Apr 07 17:28:29 debian kernel: input: HDA Intel MID Front Mic as /devices/pci0000:00/0000:00:1b.0/sound/card0/input8
Apr 07 17:28:29 debian kernel: input: HDA Intel MID Rear Mic as /devices/pci0000:00/0000:00:1b.0/sound/card0/input9
Apr 07 17:28:29 debian kernel: input: HDA Intel MID Line as /devices/pci0000:00/0000:00:1b.0/sound/card0/input10
Apr 07 17:28:29 debian kernel: input: HDA Intel MID Line Out as /devices/pci0000:00/0000:00:1b.0/sound/card0/input11
Apr 07 17:28:29 debian kernel: input: HDA Intel MID Front Headphone as /devices/pci0000:00/0000:00:1b.0/sound/card0/input12
Apr 07 17:28:29 debian kernel: media: Linux media interface: v0.10
Apr 07 17:28:29 debian systemd[1]: Reached target Sound Card.
... 略 ...

  • これらの target が有効になった事をきっかけとして、他の unit を動作させたり出来るのだろう。

busnames

用途不明。man systemd.special が Documentation になっているが、man page 内に記載なし。initramfs ?

cryptsetup-pre、cryptsetup

cryptsetup は暗号化ブロックデバイス向けの target。cryptdisks*.service も存在していたが、/dev/null への symbolic link だった。

pre が付くのは「特殊なパッシブターゲット」と呼ぶらしい。
popopopoon.hatenadiary.jp
man systemd.special の cryptsetup-pre.target より:

This passive target unit may be pulled in by services that want to run before any encrypted block device is set up. All encrypted block devices are set up after this
target has been reached. Since the shutdown order is implicitly the reverse start-up order between units, this target is particularly useful to ensure that a service
is shut down only after all encrypted block devices are fully stopped.

この target unit に関しては、

  • 起動時には暗号化ブロックデバイスが set up される前に有効になる
  • 停止時には暗号化ブロックデバイスが完全に stopped された後に無効になる

暗号化デバイスが使えるかどうかを明確に分けるための unit の模様。ブロックデバイスの暗号化を試す際に確認してみよう。

ctrl-alt-del

reboot への symbolic link。今は Windowslinux も安定しているのでやらないが、昔は暴走して反応がなくなった際に、このキー操作で reboot していた。

default

hiro20180901.hatenablog.com
その1 で調べた様に、default.target (実体は symbolic link) が有効となる様に依存性を解決しながら起動 process が進む。GUI なら graphical.target、CUI なら multi-user.target に link されている。

emergency、rescue

同名の service unit も存在していた。どちらも起動時に使用する。

  • emergency は init + sh。filesystem も mount しないし、他の service も起動しない。
  • 起動時に emergency 又は systemd.unit=emergency.unit を kernel option に追加すると、systemd-sulogin のみ起動して command prompt が表示される。systemd-sulogin を起動させるのは emergency.service の役割。emergency.service、emergency.target の両 unit 共に有効になった状態で起動する。
  • 仮想 ubuntu で試してみると、実際には root filesystem は mount されていた。-.mount も有効。これは前に emergency.service で試した時と同じ。

rescue との違い(man page):

同じような用途の rescue.target もありますが、こちらは基本的なサービスの起動とファイルシステムのマウントも行われます。

  • rescue の方が有効な unit の数は多い。emergency は数個。

exit

system や service を止める際に使われる unit。仮想 ubuntu で試してみると、root で systemctl exit を実行すると poweroff 状態となった。man page に container について記載されているので、そういう環境で便利な機能なのだろう。実 PC や仮想マシンでは poweroff.target との違いは分からない。

final

man page:

シャットダウン時に使われる特殊なターゲットユニットで、全ての通常サービスが終了して全てのマウントがアンマウントされた後に後のサービスを制御するのに使われます。

との事なので、shutdown の最後に何かを行っておきたい場合に、After 指定で動作させるのだろう。

$ grep -d skip final.target /lib/systemd/system/*
/lib/systemd/system/systemd-halt.service:Requires=shutdown.target umount.target final.target
/lib/systemd/system/systemd-halt.service:After=shutdown.target umount.target final.target
/lib/systemd/system/systemd-kexec.service:Requires=shutdown.target umount.target final.target
/lib/systemd/system/systemd-kexec.service:After=shutdown.target umount.target final.target
/lib/systemd/system/systemd-poweroff.service:Requires=shutdown.target umount.target final.target
/lib/systemd/system/systemd-poweroff.service:After=shutdown.target umount.target final.target
/lib/systemd/system/systemd-reboot.service:Requires=shutdown.target umount.target final.target
/lib/systemd/system/systemd-reboot.service:After=shutdown.target umount.target final.target

以下の service unit の Requires と After に含まれている。

  • systemd-halt.service
  • systemd-kexec.service
  • systemd-poweroff.service
  • systemd-reboot.service

final に加えて shutdown と umount も含まれているので、shutdown が選択されて filesystem を umount した後、同期 point としての final が成立してから各 service が起動するようになっている。

getty

man page:

静的に設定されたローカル TTY getty インスタンスを制御する特殊なターゲットユニット。

  • multi-user.target の wants に symbolic link されていて、依存性で有効になっている。
  • getty@.service の WantedBy に getty.target が入っているので、getty@.service (template unit) が有効になっている。起動直後は getty@tty1.service だけが有効だが、仮想端末を切り替えると tty2 以降も有効になる。

hiro20180901.hatenablog.com

  • getty.target.wants に getty-static.service が入っているが、tty[2-6] が getty@.service で使える状態になっているので getty-static.service は static。

graphical

  • GUI 環境の最終的な target unit。現在は default.target への link はこちらになっている。display-manager.service を Wants している。
  • display-manager.service は /etc/systemd 以下で lightdm.service に symbolic link されている。
  • 現環境では、依存性を解決しながら lightdm.service を起動する事が graphical.target = default.target の最終目標となっている。

halt

システムをシャットダウン・停止するための特殊なターゲットユニット。このターゲットとは poweroff.target とは違ってシステムの停止だけを行い電源は切りません。

reboot や poweroff と違って、halt を使う事はあるのだろうか? container かな?

hibernate、hybrid-sleep、sleep、suspend

この4つの target は、電源管理の為の物だろう。sleep 以外の3つは、service unit を経由して systemd-sleep command を呼び出している。 今の PC は Desktop であり、使用していないので今回は詳細は調べない。

initrd-fs、initrd-root-device、initrd-root-fs、initrd-switch-root、initrd

これらの initrd*.target は、起動時に grub から読み込まれる initramfs で使われていそうな気配。initramfs を分解して調べる際に追っかけてみる。

kexec

kernel を softboot する為の機能が kexec であり、新しい kernel で再起動させる為の target が kexec である。BIOS (UEFI) や grub を bypass して直接 kernel を起動できるので非常に高速。kexec-tools packages が必要。仮想 ubuntu で試してみた。
github.com

$ uname -a
Linux ubuntu 4.15.0-47-generic #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
# kexec -l /boot/vmlinuz-4.15.0-46-generic --initrd=/boot/initrd.img-4.15.0-46-generic --reuse-cmdline
# systemctl kexec
... 再起動 ...
$ uname -a
Linux ubuntu 4.15.0-46-generic #49-Ubuntu SMP Wed Feb 6 09:33:07 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

kexec command で vmlinuz と initrd を指定して、systemctl kexec を実行すると kernel が再読込されている。kernel を作り直して幾度も試す場合には便利。

local-fs-pre、local-fs

  • sysinit の Wants と After に swap 等と一緒に指定されているので、sysinit の前の local filesystem の mount unit の同期 point としての target unit だろう。全ての local filesystem を mount し終わった段階で同期 point として機能させるのだと思う。
  • cryptsetup と同様に特殊な passive unit も存在している。

multi-user

CUI 環境の最終的な target unit。graphical からも Requires されている。正常に起動して使える状態になった事を示す target unit だろう。

network-online、network-pre、network

  • network-online は、起動時に確実に network が設定されて外部への接続が可能な状態になった時に有効になる unit
  • network と network-pre は special passive unit。firewall 等の設定の為に network interface が有効になったタイミングを合わせる為に存在している。
  • systemctl status で確認すると、実 PC では network は active だが、network-pre と network-online は inactive。別の機会に確認すると、network-online が active になっていた。
  • network-online は apt-daily.service の Wants になっているので、apt-daily.timer が apt-daily.service を有効にした場合に network-online が有効になっていた。一度目の起動の際は有効、二度目は apt-daily.service が有効にならないので、network-online も有効にならない。
  • 仮想 Ubuntu の場合には、別の service が network-online を Wants しているので、常に有効になっている。
  • この辺りは、systemd-analyze で svg を出力して確認すると分かりやすい。

nss-lookup

man page より:

A target that should be used as synchronization point for all host/network name service lookups.

  • host name service、network name service が有効になるタイミングを合わせる為の同期用の target。
  • 実PC debian では有効になっていない。nss-lookup を Wants に含む unit が存在していない。
  • 仮想ubuntu では、systemd-resolved.service が有効で且つ Wants に nss-lookup が入っているので、依存関係で有効になっている。
  • 実PC debian の systemd-resolved.service が disabled で、且つ Wantsdbus が指定されているので、この状態では nss-lookup は無効のままだろう。

nss-user-lookup

man page より:

A target that should be used as synchronization point for all regular UNIX user/group name service lookups.

  • UNIX user name service、group name service が有効になるタイミングを合わせる為の同期用の target。
  • 仮想 ubuntu では有効だが、実PC debian では無効になっている。debian では After 指定のみ、ubuntu では accounts-daemon.service の Wants に入っている。
  • accountsservice は user account 情報の検索と操作をする dbus interface らしい。入れてなくても debian + LXDE は大丈夫なんだね。

paths

  • path unit を setup する special target unit。path unit は、特定の path を監視し、変化があった場合に action を実行する unit である。
  • 実PC debian には2つの path unit が存在している。systemd-ask-password-console.path と systemd-ask-password-wall.path。どちらも同名の service unit も存在する。
  • 両者とも、DefaultDependency=no で依存性を無くした上で、sysinit.target.wants 以下に symbolic link されている。
  • その結果、systemd-cgls で見ると、sysinit.target 以下にぶら下がる形で2つの path unit が存在している。
  • 今の状態の debian では、paths.target による path unit の有効化を利用していない。
  • 仮想 ubuntu では cups.path が存在し、parhs.target から起動されている。printer spooler として、特定の directory に書き込まれるのを監視して印刷 process が起動するのだろう。

poweroff、reboot

  • poweroff は shutdown & 電源OFF する為の special unit。systemctl poweroff で電源が落ちる。
  • reboot は shutdown & 再起動する為の special unit。systemctl reboot で再起動する。
  • /sbin/shutdown も /sbin/rebootも、/bin/systemctl への symbolic link であり、名前が shutdown の場合には systemctl poweroff 相当の動作、reboot の場合には systemctl reboot 相当の動作をするのだろう。

remote-fs-pre、remote-fs

cryptsetup、local-fs の remote 版の target。特殊な passive unit が存在するのも、停止時に役立つ為と思う。

rpcbind

ja.wikipedia.org

  • target unit file の中身を見ると、SysVinit の init script との互換性を取るために存在している模様。
  • systemd では socket unit で指定するやり方なのだろう。(cf. ssh.socket)

runlevel[0-6]

SysVinit の各 runlevel に相当する target unit。

runlevel0.target -> poweroff.target
runlevel1.target -> rescue.target
runlevel2.target -> multi-user.target
runlevel3.target -> multi-user.target
runlevel4.target -> multi-user.target
runlevel5.target -> graphical.target
runlevel6.target -> reboot.target

0 は poweroff、1 は single user 相当の rescue、[2-4] は multi-user、5 は graphical、6 は reboot への link。

shutdown

  • マシンを shutdown させる際に、disk への書き込み等の理由で正常に停止させたい service の unit file に、Conflicts と Before の依存性を追加しておくと、終了処理を確実に実施してくれる模様。
  • poweroff や reboot の前に、service unit を正常に終了させる為の同期 point となるのだろう。

sigpwr

man page より:

systemd が SIGPWRA プロセスシグナルを受信したときに起動される特殊なターゲットユニット。通常は電源が喪失したときにカーネルあるいは UPS デーモンによって送信されます。

UPS との連携で使用するのだろうか。所有していないので分からず。

slices

  • root slice (-.slice) と system.slice を有効にする為の target unit。slice は process を tree 状に管理し、control group (cgroup) を適用させる為の仕組み。
  • user.slice は存在しているが、どうやって有効にしているのだろうか ... dbus の service と systemd-logind.service の Wants になっていた。login と同時に有効になるのだろう。
  • slice unit は、unit file が存在していないのに有効になっている物が多数あるので、後で調べてみる。

sockets

A unit configuration file whose name ends in ".socket" encodes information about an IPC or network socket or a file system FIFO controlled and supervised by systemd, for socket-based activation.

  • socket unit は IPC (Interprocess communication:Wikipedia) や network socket、filesystem FIFO:Wikipedia に関する unit。
  • sockets.target は 全ての socket unit を有効にする為の special target unit。
  • systemd-analyze の結果を見ると、起動初期の段階で様々な socket unit を起動し、basic.target と同時期に sockets.target が有効になる。
  • man page には「全ての」socket unit を有効にすると書かれているが、ssh.socket は disabled で無効になっている。systemd-rfkill も wifi が無いので無効のまま。
  • socket unit は後でもう一度調べてみる。

swap

  • local-fs.target と同様に、swap を有効にする target unit。
  • sysinit から Wants されている。

man systemd.unit (Arch Linux JP Project):

スワップユニットはユニットファイルと /etc/fstab のどちらかで設定できます (詳しくは fstab(5) を参照)。/etc/fstab に列挙されたスワップは起動時およびシステムマネージャのリロード時に動的にネイティブのユニットに変換されます。

  • /etc/fstab から動的生成されている。

sysinit

  • basic.target の前段階、初期設定の終了の同期を取る為の unit が sysinit。cf. man bootup
  • kernel、initramfs から初期設定を並列に実行して、一旦 sysinit で完了待ち。
  • slice や socket、path、timer 等を有効にして basic で完了待ち。
  • 各種 service を有効にして multi-user か graphical に到達して起動完了、という流れだと思う。
  • kernel 起動から initramfs を追いかける際に、もう一度確認してみる。

system-update

  • system を offline update する為の target unit。多分 PC では使わないと思う。組込系で使う機能だろう。

time-sync

  • systemd-timesyncd.service から Wants されていて有効となる unit。

timers

  • 全ての timer unit を有効にする unit。
  • timer unit の詳細は後で調べる。

umount

man systemd.special:

システムのシャットダウン時に全てのマウント・自動マウントポイントをアンマウントする特殊なターゲットユニット。

システムのシャットダウン時にアンマウントするマウントはこのユニットの Conflicts 依存にマウントユニットを追加します。

  • shutdown の際に、全ての umount が終了したタイミングで同期を取るための unit。

結果

  • 58 個の target unit について、ざっくりとではあるが調べてみた。
  • 最初に考えた通り、順番が重要な感じだった。sysinit -> basic -> multi-user の順で、その間に各種の target が存在していた。
  • また、service unit と連携している target unit も多く存在していた。
  • 複数の unit を取りまとめる、また同期 point となる、という考え方も漠然とではあるが理解できたと思う。