はじめに
世界は今、新型コロナウィルス禍で始まった半導体不足に包まれています。そんな中、Raspberry PiやArduino、Tinker Boardに代表されるシングルボードコンピューターで要件を満たせることも多くなってきました。
価格が安く、ARM版Linuxに対応していることで、初期導入コストも交換コストも安価に仕上げられるので、これからの需要はますます増えていくと想定しています。
一方で、シングルボードコンピューターはやはり性能面で劣ります。特に、電源OFFから起動し、アプリケーションが動作するまでの時間が問題になることが多いため、今回、起動時間の改善をしてみました。
利用OS
本記事では、「Ubuntu 18.04.6 LTS (Bionic Beaver)」を以下からダウンロードし、利用することにしました。
今回はUbuntuとしましたが、Debianも結局は派生なので、ひとつずつプロセスを確認、停止していけば同じだと思います。
初期状態
インストール後、起動するとGUI(グラフィカルユーザーインターフェース)で起動しました。
起動時間は、電源投入後、40秒ほどでした。
そして、「systemd-analyze blame」コマンドや「systemd-analyze critical-chain」コマンドを利用し、起動完了までに長時間を要している各プロセスの時間を見てみました。
systemd-analyze blame
6.608s NetworkManager-wait-online.service
2.343s dev-mmcblk1p9.device
1.581s accounts-daemon.service
1.226s avahi-daemon.service
1.103s apport.service
863ms networkd-dispatcher.service
833ms udisks2.service
680ms bluetooth.service
673ms snapd.service
664ms upower.service
660ms systemd-resolved.service
576ms NetworkManager.service
536ms ua-timer.service
519ms polkit.service
432ms systemd-timesyncd.service
372ms switcheroo-control.service
334ms wpa_supplicant.service
331ms systemd-udev-trigger.service
301ms systemd-logind.service
292ms systemd-journald.service
289ms keyboard-setup.service
273ms systemd-udevd.service
259ms ModemManager.service
244ms snapd.seeded.service
212ms systemd-journal-flush.service
204ms [email protected]
195ms e2scrub_reap.service
190ms gdm.service
167ms sys-kernel-debug.mount
167ms sys-kernel-tracing.mount
152ms dev-mqueue.mount
124ms rsyslog.service
118ms packagekit.service
110ms colord.service
108ms systemd-modules-load.service
104ms [email protected]
100ms systemd-remount-fs.service
95ms sys-fs-fuse-connections.mount
86ms sys-kernel-config.mount
78ms pppd-dns.service
60ms kerneloops.service
58ms systemd-sysusers.service
57ms systemd-random-seed.service
57ms alsa-restore.service
54ms systemd-sysctl.service
39ms systemd-update-utmp-runlevel.service
39ms systemd-user-sessions.service
39ms setvtrgb.service
30ms systemd-tmpfiles-setup-dev.service
30ms systemd-update-utmp.service
29ms systemd-tmpfiles-setup.service
28ms systemd-rfkill.service
27ms binfmt-support.service
25ms rtkit-daemon.service
25ms openvpn.service
24ms console-setup.service
24ms plymouth-read-write.service
21ms snapd.socket
19ms plymouth-quit-wait.service
systemd-analyze critical-chain
graphical.target @10.144s
└─multi-user.target @10.143s
└─kerneloops.service @10.080s +60ms
└─network-online.target @10.068s
└─NetworkManager-wait-online.service @3.454s +6.608s
└─NetworkManager.service @2.850s +576ms
└─dbus.service @2.836s
└─basic.target @2.071s
└─sockets.target @2.066s
└─snapd.socket @1.998s +21ms
└─sysinit.target @1.842s
└─systemd-timesyncd.service @1.408s +432ms
└─systemd-tmpfiles-setup.service @1.354s +29ms
└─systemd-journal-flush.service @1.135s +212ms
└─systemd-journald.service @803ms +292ms
└─systemd-journald.socket @714ms
└─system.slice @379ms
└─-.slice @378ms
ゴールが見えれば簡単です。あとは、起動シーケンスから不要プロセスを一つずつ止めていくだけです。
最適化開始
まずは、停止していきます。要件としては以下です。
- グラフィカルユーザーインターフェース不要
- ネットワーク接続不要
- 起動シーケンスの処理時間短縮が最優先
アプリケーションでネットワーク接続が必要になるのであれば、そのアプリケーションの起動シーケンス内に対応すれば良い、ということにします。
ここからは、各プロセスについての理解と停止対象プロセスです。
停止するプロセス
NetworkManager-wait-online.service
概要・理由
- ネットワーク
- WantsやRequiresで他サービスから指定されればいずれにしても起動する
- network-online.targetにより、ネットワークが必要な際には結局は起動される
停止コマンド
sudo systemctl disable NetworkManager-wait-online.service
avahi-daemon.service
概要・理由
- Bonjour(Apple)向けのサービスのため
停止コマンド
sudo systemctl disable avahi-daemon.service
apport.service
概要・理由
- Ubuntuへの送信するための、Ubuntu専用障害時ダンプサービスであり、DebianではExperimental扱いの別のサービスのため
停止コマンド
sudo systemctl disable apport.service
networkd-dispatcher.service
停止コマンド
sudo systemctl disable networkd-dispatcher.service
bluetooth.service
概要・理由
- Bluetooth起動サービスのため、必要であれば起動すればよい
停止コマンド
sudo systemctl disable bluetooth.service
systemd-resolved.service
概要・理由
- ローカル DNS スタブリスナによるネットワーク名前解決をローカルアプリケーションに提供している
停止コマンド
sudo systemctl disable systemd-resolved.service
NetworkManager.service
概要・理由
- ネットワーク接続は、利用するアプリケーション起動時に含めるため
停止コマンド
sudo systemctl disable NetworkManager.service
ua-timer.service
概要・理由
- タイマーサービスの利用は行わないため
停止コマンド
sudo systemctl disable ua-timer.service
wpa_supplicant.service
概要・理由
- 無線LAN暗号化だが、無線は基本利用しないため
- 停止しても起動してくる・・・
停止コマンド
sudo systemctl disable wpa_supplicant.service
keyboard-setup.service
概要・理由
- キーボードのセットアップのためのサービスは不要のため
停止コマンド
sudo systemctl disable keyboard-setup.service
ModemManager.service
概要・理由
- ダイヤルアップ(モデム)を利用することがないため
停止コマンド
sudo systemctl disable ModemManager.service
snapd.seeded.service
概要・理由
- クロスプラットフォームパッケージ管理関連のため
停止コマンド
sudo snapd.seeded.service
e2scrub_reap.service
概要・理由
- LVMマウント時にe2fsckを実行するプロセスのため、不要
停止コマンド
sudo systemctl disable e2scrub_reap.service
sys-kernel-debug.mount
概要・理由
- kernelによるマウントのデバッグなので、高速化のためには不要
停止コマンド
sys-kernel-tracing.mount
概要・理由
- kernelによるマウントのデバッグなので、高速化のためには不要
停止コマンド
sudo systemctl disable sys-kernel-tracing.mount
packagekit.service
概要・理由
- GNOMEのパッケージ管理のため
停止コマンド
sudo systemctl disable packagekit.service
pppd-dns.service
概要・理由
- PPPoE接続は利用しないため
停止コマンド
sudo systemctl disable pppd-dns.service
systemd-update-utmp-runlevel.service
概要・理由
- SysV経由でのランレベルサポートは不要のため
停止コマンド
sudo systemctl disable systemd-update-utmp-runlevel.service
systemd-update-utmp.service
概要・理由
- SysV経由でのランレベルサポートは不要のため
停止コマンド
sudo systemctl disable systemd-update-utmp.service
systemd-rfkill.service
概要・理由
- RFKill は、コンピュータシステムの無線送信器が、クエリ、アクティベート、非アクティブ化されるインターフェースを提供する Linux カーネルのサブシステム
- 無線送信器が非アクティブ化されると、それらはソフトウェアが再アクティベートできる状態 (ソフトブロック) に置かれるか、またはソフトウェアが再アクティベートできない状態 (ハードブロック) に置かれる。
停止コマンド
sudo systemctl disable systemd-rfkill.service
rtkit-daemon.service
概要・理由
- リアルタイムスケジューリングは不要のため
停止コマンド
sudo systemctl disable rtkit-daemon.service
openvpn.service
概要・理由
- OpenVPNは不要のため
停止コマンド
sudo systemctl disable openvpn.service
plymouth-read-write.service
概要・理由
- GUIは極力排除したいため
- Red Hat Enterprise Linux 系列のグラフィカルなブートシステム・ロガー、カーネルベースモード設定 (KMS) およびダイレクトレンダリングマネージャー (DRM) を使用している
- このサービスはGDM経由でグラフィカルユーザーインターフェース(GUI)を利用するのであれば停止しても起動する。起動速度を優先するのであればグラフィカルユーザーインターフェース(GUI)でのログインを「sudo systemd set-default multi-user.target」でコマンドラインインターフェース(CUI)に切り替えたのち、、以下削除コマンドを行う
停止コマンド
sudo apt-get purge --remove plymouth
snapd.socket
概要・理由
- クロスプラットフォームパッケージ管理関連は停止、必要なときに起動すれば良いため
停止コマンド
sudo systemctl disable snapd.socket
plymouth-quit-wait.service
概要・理由
- GUIは極力排除したいため
- Red Hat Enterprise Linux 系列のグラフィカルなブートシステム・ロガー、カーネルベースモード設定 (KMS) およびダイレクトレンダリングマネージャー (DRM) を使用している
- このサービスはGDM経由でグラフィカルユーザーインターフェース(GUI)を利用するのであれば停止しても起動する。起動速度を優先するのであればグラフィカルユーザーインターフェース(GUI)でのログインを「sudo systemd set-default multi-user.target」でコマンドラインインターフェース(CUI)に切り替えたのち、、以下削除コマンドを行う
停止コマンド
sudo apt-get purge --remove plymouth
維持するプロセス
dev-mmcblk1p9.device
概要・理由
- 今回の要件が、eMMC起動のため、起動時に必要
accounts-daemon.service
概要・理由
- Gnome等GUIを利用するのであれば必要だが、最終的にはランレベル3(multi-user.target)で起動するため、ここでは設定不要
udisks2.service
概要・理由
- ブロックデバイス管理のために必要なため
upower.service
概要・理由
- 電源管理システムのため
polkit.service
概要・理由
- GNOMEなどのデスクトップ操作の権限を設定するセキュリティツール
systemd-timesyncd.service
概要・理由
- 時刻同期サービスのため
switcheroo-control.service
概要・理由
- DBus経由で、GPUが複数う搭載しているかチェックするサービスであり、DBus関連は維持した方が安全のため
systemd-udev-trigger.service
概要・理由
- initramfs (INITial RAM File System; 初期 RAM ファイルシステム) は小さな cpio アーカイブで、カーネルが RAM ディスク内に読み込むことができる仕組み
- ルートファイルシステムがマウントできるようになり、オペレーティングシステムが開始できるようになるには、カーネルはルートファイルシステムの存在するデバイスにアクセスするためのドライバを読み込む必要がある
- ドライバは特殊なハードディスク向けのドライバであったり、ネットワーク経由でアクセスする場合はネットワークドライバであったりする場合もあり、ルートファイルシステムに対して必要なモジュールは、 initramfs 内にある init が読み込みまれる
- 必要なモジュールが読み込まれると、 udev が initramfs に対して必要なデバイスを提供するようになる
systemd-logind.service
概要・理由
- ユーザーログイン管理を実施するため
systemd-journald.service
概要・理由
- システム監査ログ保存、rsyslogと連携しているため
systemd-udevd.service
概要・理由
- jarnaldと連携しているため
systemd-journal-flush.service
概要・理由
- journal管理・ログ削除のため
[email protected]
概要・理由
- GDM含め、ユーザー管理を行うサービスを起動するユーザーサービスのため
gdm.service
概要・理由
- Gnome等GUIを利用するのであれば必要だが、最終的にはランレベル3(multi-user.target)で起動するため、ここでは設定不要
dev-mqueue.mount
概要・理由
- POSIX準拠のプロセス間メッセージングのため
rsyslog.service
概要・理由
- journal連携のため
colord.service
概要・理由
- DBus経由で接続するデバイスとのカラープロファイル管理を行う可能性があるため
systemd-modules-load.service
概要・理由
- 静的設定に基づく、起動の初期段階でカーネルモジュールをロードするサービスのため
systemd-remount-fs.service
概要・理由
- fstabで列挙されている、systemd-gpt-auto-generatorにより検知されたパーティションテーブルを起動初期でマウントするためのサービスのため
sys-fs-fuse-connections.mount
概要・理由
- FUSE Control File Systemを利用し、FUSE のカーネルモジュールとデーモンの通信をサポートするサービスのため
sys-kernel-config.mount
概要・理由
- kernel設定ファイルのマウント・ロードを行うため
kerneloops.service
概要・理由
- kernel panicが発生した際の自動再起動を行うサービスのため
systemd-sysusers.service
概要・理由
- ユーザー・グループ管理のため
systemd-random-seed.service
概要・理由
- ハードウェア乱数生成器のための乱数生成に必要なため
alsa-restore.service
概要・理由
- サウンドカードのデバイスドライバを提供する Open Sound System (OSSv3) を置き換えるために開発された Linux カーネルコンポーネント(Advanced Linux Sound Architecture (ALSA)のため
systemd-sysctl.service
概要・理由
- systemctlのための呼び出しサービスのため
systemd-user-sessions.service
概要・理由
- 起動後のユーザーログインを許可し、シャットダウン時のユーザーログインを制限するサービスのため
setvtrgb.service
概要・理由
- 仮想コンソールのカラーマップ設定のため
systemd-tmpfiles-setup-dev.service
概要・理由
- システムによる一時ファイルに関わるため
systemd-tmpfiles-setup.service
概要・理由
- システムによる一時ファイルに関わるため
binfmt-support.service
概要・理由
- システム管理者がファイル拡張子をベースにして各種バイナリ 形式をインタプリタに登録し、該当するファイルが実行された時には適切なインタプリタが呼び出されるように設定しているため
console-setup.service
概要・理由
- コンソールに対して X Window System と同じキーボード設定(スキー ム)を提供しているため
CUIモードに切り替え、再起動
ここまで設定を終えたら、グラフィカルユーザーインターフェース(GUI)での起動を、コマンドラインインターフェース(CUI)での起動に切り替えます。
sudo systemd set-default multi-user.target
その後、sudo rebootとすれば、再起動します。
結果
これで、だいぶ起動が早くなりました。
コマンドラインインターフェース(CUI)ではありますが、電源投入後14秒でログイン画面が表示されました。
今回のところは、これで十分かなと思います。
さいごに
ハイバネーションからの起動等、もっとやり込めば突き詰められます。
ですが、各プロセスが何をしているのかを理解し、LinuxベースのOSを利用する上で不要なものだけを削除する、という観点をで設定した方が、その後の運用・開発に役に立つと思い、このようにしました。
今回はUbuntuとしましたが、Debianも結局は派生なので、ひとつずつプロセスを確認、停止していけば同じだと思います。
コメント