みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoProject systemdでシステム起動時間計測

はじめに

前回、systemdのサービスを追加して、システム起動時にストレージの最後のパーティションを目一杯まで拡張するようにした。

このサービスはパーティションを拡張するためのシステムの初回起動時だけ実行されればよいのだが、 2回目以降のために、サービスを無効化するようなことはしていない。

起動時間に悪影響を及ぼさないのか確認してみる。

systemd-analyze

パーティションの拡張にはsystemdを使用しているため、sysvinitのことは除外する。

systemdでの起動時間計測といえばsystemd-bootchartが定番だったが、initプロセスを差し替える必要があったり使用するハードルが高かった。 現在systemdではsystemd-analyzeというツールを提供しており、これを使用することで特にinitプロセスの差し替えなどせずに起動時間を計測することができる。

systemd-analyzeを使用するにはlocal.confに次の内容を追加する。

IMAGE_INSTALL:append = " systemd-analyze"

起動時間の計測

初回

~# systemd-analyze
Startup finished in 3.320s (kernel) + 15.091s (userspace) = 18.411s
multi-user.target reached after 14.762s in userspace

~# systemd-analyze blame  | grep repart
 466ms repart.service

# systemd-analyze blame  | grep growfs
 1.913s systemd-growfs@data.service

2回目以降

# systemd-analyze
Startup finished in 3.560s (kernel) + 12.769s (userspace) = 16.330s
multi-user.target reached after 12.438s in userspace

# systemd-analyze blame  | grep repartw
 466ms repart.service

# systemd-analyze blame  | grep growfs
 164ms systemd-growfs@data.service

systemd-growfs@data.serviceは明らかに2回目以降の時間が短縮しているが、repart.serviceは初回と同じ時間かかっている。 500ミリ秒は無視できない数字だと思う。

repart.serviceの停止

$ systemctl disable repart.service

repart停止後の計測結果

# systemd-analyze
Startup finished in 3.321s (kernel) + 12.094s (userspace) = 15.415s
multi-user.target reached after 11.753s in userspace

root@raspberrypi4-64:~# systemd-analyze blame | grep repart
root@raspberrypi4-64:~# systemd-analyze blame | grep growfs
  59ms systemd-growfs@data.service

計測結果には多少の振れ幅があるが、起動時間が短縮されるのは確かなようだ。

repart.serviceを改造

初回起動時にパーティションを拡張したあと、自身のサービスをdisableするように改造してみる。

[Unit]
Description=Service to resizing parition
DefaultDependencies=no
Before=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/parted --script @repart-dev@ resizepart @repart-no@ 100%
ExecStart=systemctl disable repart.service

[Install]
WantedBy=local-fs.target

イメージを作り直し実機で実行してみる。

fdisk -l

改造後も意図通り、パーティションが拡張されていることが確認できる。

# fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 3768 MB, 3951034368 bytes, 7716864 sectors
120576 cylinders, 4 heads, 16 sectors/track
Units: sectors of 1 * 512 = 512 bytes

Device       Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type
/dev/mmcblk0p1 *  64,0,1      1023,3,32         8192     152543     144352 70.4M  c Win95 FAT32 (LBA)
/dev/mmcblk0p2    1023,3,32   1023,3,32       155648     624229     468582  228M 83 Linux
/dev/mmcblk0p3    1023,3,32   1023,3,32       624640     890879     266240  130M 83 Linux
/dev/mmcblk0p4    1023,3,32   1023,7,32       892928    7716863    6823936 3332M 83 Linux

repart.serviceのログ

repart.servceのログを確認すると、パーティション拡張処理は成功した上にサービスがdisabledになっていることが確認できる。

# systemctl status repart
* repart.service - Service to resizing parition
     Loaded: loaded (8;;file://raspberrypi4-64/lib/systemd/system/repart.service/lib/systemd/system/repart.service8;;; disabled; vendor preset: enabled)
     Active: inactive (dead)

Apr 28 17:42:27 raspberrypi4-64 systemctl[142]: Removed /etc/systemd/system/local-fs.target.wants/repart.service.
Apr 28 17:42:27 raspberrypi4-64 systemd[1]: repart.service: Deactivated successfully.
Apr 28 17:42:27 raspberrypi4-64 systemd[1]: Finished Service to resizing parition.

初回起動時のsystemd-anlyze

repart.serviceをdisableしてしまうので、systemd-analyze blameでは表示されなくなっているようだ。

# systemd-analyze
Startup finished in 3.321s (kernel) + 15.900s (userspace) = 19.222s
multi-user.target reached after 15.563s in userspace

# systemd-analyze blame  | grep repart
root@raspberrypi4-64:~#

# systemd-analyze blame  | grep growfs
2.465s systemd-growfs@data.service

2回目以降のsystemd-analyze

狙い通り起動時間が短縮されているようだ。

# systemd-analyze
Startup finished in 3.310s (kernel) + 12.155s (userspace) = 15.466s
multi-user.target reached after 11.823s in userspace

まとめ

initプロセスにsystemdを使用している場合、systemd-analyzeでシステムの起動時間を計測することができる。 起動後にコマンドを実行するだけなのでbootchartより簡単となっている。

前回、作成したrepart.serviceの時間を計測し、 本来実行が不要な2回目以降のシステム起動時間に及ぼす影響を調査したところ、 毎回パーティション拡張を実行した場合と同じ時間がかかることが判明した。

そのため、2回目以降はrepart.serviceが実行されないように改造し、 システム起動時間のパフォーマンスを向上した。