KURO-BOX Pro で正しく電源オフにできるようにする

目次

はじめに

Debian 7 ぐらいの頃から KURO-BOX/Pro で標準 Debian インストーラを使っていますが、OSシャットダウン時に電源オフにならず、HDD ブートではないモードですぐに起動してしまう状態となっていました。 また、Buffalo LS-GL だと同様に電源オフにならず、異常音が鳴り続けるという状態でした。

機器の電源ボタン長押しすれば強制的に電源オフにできるのですが、いつまでもそうするのは面倒なのでちゃんと対応して解決することにしました。


解決方法

先に解決方法を書くと、OSシャットダウン時に microapl 経由でマイコンに電源オフの制御メッセージを送る systemd サービスを用意すれば良いです。

 1$ sudo tee /etc/systemd/system/poweroff-microapl.service << EOF > /dev/null
 2[Unit]
 3Description=Power off by miconapl
 4DefaultDependencies=no
 5After=final.target
 6Before=systemd-poweroff.service
 7
 8[Service]
 9Type=oneshot
10ExecStart=/bin/bash -c "sync && microapl -a shutdown_wait && microapl -a power_off"
11
12[Install]
13WantedBy=poweroff.target
14EOF
15
16
17$ sudo systemctl enable poweroff-microapl.service

Debian 12 で動作を確認しましたが、systemd が採用された Debian 8 以降なら動作すると思います。


解決プロセス

microapl をいろいろ試す

microapl コマンドをいろいろと試した結果、"shutdown_wait", "power_off" の順にマイコン制御メッセージを送れば、機器の電源がオフになることがわかりました。

1$ sudo microapl -a shutdown_wait
2$ sudo microapl -a power_off

ただし、OSシャットダウンが走らずにすぐに電源オフになるので、これはさすがに良くないです。

OSシャットダウン時のログを確認

OSシャットダウンの後に電源オフになってくれるのがベストなので、まずはそもそものOSシャットダウン時のログを確認してみます。 ログを確認しやすくするために journal を削除してから、OSをシャットダウンします。

1$ sudo systemctl stop systemd-journald
2$ sudo rm -rf /var/log/journal/*
3$ sudo systemctl start systemd-journald
4
5$ sudo systemctl poweroff

その後、電源ボタン長押しで電源オフにし、改めて起動してから journalctl で systemd のログを確認してみます。

1$ sudo journalctl

ターゲットユニットと重要そうなログは次のようになっていました。

 1Aug 11 09:52:13 kurobox systemd[1]: Stopped target graphical.target - Graphical Interface.
 2Aug 11 09:52:13 kurobox systemd[1]: Stopped target multi-user.target - Multi-User System.
 3Aug 11 09:52:13 kurobox systemd[1]: Stopped target getty.target - Login Prompts.
 4Aug 11 09:52:13 kurobox systemd[1]: Stopped target timers.target - Timer Units.
 5Aug 11 09:52:13 kurobox systemd[1]: Stopped target time-set.target - System Time Set.
 6Aug 11 09:52:16 kurobox systemd[1]: Stopped target network.target - Network.
 7Aug 11 09:52:17 kurobox systemd[1]: Stopped target remote-fs.target - Remote File Systems.
 8Aug 11 09:52:18 kurobox systemd[1]: Stopped target basic.target - Basic System.
 9Aug 11 09:52:18 kurobox systemd[1]: Stopped target paths.target - Path Units.
10Aug 11 09:52:18 kurobox systemd[1]: Stopped target slices.target - Slice Units.
11Aug 11 09:52:18 kurobox systemd[1]: Stopped target sockets.target - Socket Units.
12Aug 11 09:52:18 kurobox systemd[1]: Stopped target sysinit.target - System Initialization.
13Aug 11 09:52:18 kurobox systemd[1]: Stopped target cryptsetup.target - Local Encrypted Volumes.
14Aug 11 09:52:18 kurobox systemd[1]: Stopped target integritysetup.target - Local Integrity Protected Volumes.
15Aug 11 09:52:18 kurobox systemd[1]: Stopped target swap.target - Swaps.
16Aug 11 09:52:18 kurobox systemd[1]: Stopped target veritysetup.target - Local Verity Protected Volumes.
17Aug 11 09:52:20 kurobox systemd[1]: Stopped target local-fs.target - Local File Systems.
18Aug 11 09:52:20 kurobox kernel: EXT4-fs (sda1): unmounting filesystem.
19Aug 11 09:52:21 kurobox systemd[1]: Reached target umount.target - Unmount All Filesystems.
20Aug 11 09:52:21 kurobox systemd[1]: Stopped target local-fs-pre.target - Preparation for Local File Systems.
21Aug 11 09:52:21 kurobox systemd[1]: systemd-remount-fs.service: Deactivated successfully.
22Aug 11 09:52:21 kurobox systemd[1]: Stopped systemd-remount-fs.service - Remount Root and Kernel File Systems.
23Aug 11 09:52:21 kurobox systemd[1]: Reached target shutdown.target - System Shutdown.
24Aug 11 09:52:21 kurobox systemd[1]: Reached target final.target - Late Shutdown Services.
25Aug 11 09:52:21 kurobox systemd[1]: systemd-poweroff.service: Deactivated successfully.
26Aug 11 09:52:21 kurobox systemd[1]: Finished systemd-poweroff.service - System Power Off.
27Aug 11 09:52:21 kurobox systemd[1]: Reached target poweroff.target - System Power Off.
28Aug 11 09:52:21 kurobox systemd[1]: Shutting down.
29Aug 11 09:52:22 kurobox systemd-shutdown[1]: Syncing filesystems and block devices.
30Aug 11 09:52:22 kurobox systemd-shutdown[1]: Sending SIGTERM to remaining processes...
31Aug 11 09:52:22 kurobox systemd-journald[703]: Received SIGTERM from PID 1 (systemd-shutdow).
32Aug 11 09:52:22 kurobox systemd-journald[703]: Journal stopped

"systemctl halt" でOSシャットダウンした場合は、final.target に達した後、systemd-halt.service が開始されていました。

1Aug 11 10:46:00 kurobox systemd[1]: Reached target shutdown.target - System Shutdown.
2Aug 11 10:46:00 kurobox systemd[1]: Reached target final.target - Late Shutdown Services.
3Aug 11 10:46:00 kurobox systemd[1]: Starting systemd-halt.service - System Halt...
4Aug 11 10:46:00 kurobox systemd[1]: Shutting down.
5Aug 11 10:46:01 kurobox systemd-shutdown[1]: Syncing filesystems and block devices.
6Aug 11 10:46:01 kurobox systemd-shutdown[1]: Sending SIGTERM to remaining processes...
7Aug 11 10:46:01 kurobox systemd-journald[369]: Received SIGTERM from PID 1 (systemd-shutdow).
8Aug 11 10:46:01 kurobox systemd-journald[369]: Journal stopped

"systemctl reboot" で再起動した場合は、final.target の後に reboot.target に達していました。

 1Aug 11 10:38:56 kurobox systemd[1]: Reached target shutdown.target - System Shutdown.
 2Aug 11 10:38:56 kurobox systemd[1]: Reached target final.target - Late Shutdown Services.
 3Aug 11 10:38:57 kurobox systemd[1]: systemd-reboot.service: Deactivated successfully.
 4Aug 11 10:38:57 kurobox systemd[1]: Finished systemd-reboot.service - System Reboot.
 5Aug 11 10:38:57 kurobox systemd[1]: Reached target reboot.target - System Reboot.
 6Aug 11 10:38:57 kurobox systemd[1]: Shutting down.
 7Aug 11 10:38:57 kurobox systemd-shutdown[1]: Syncing filesystems and block devices.
 8Aug 11 10:38:58 kurobox systemd-shutdown[1]: Sending SIGTERM to remaining processes...
 9Aug 11 10:38:58 kurobox systemd-journald[896]: Received SIGTERM from PID 1 (systemd-shutdow).
10Aug 11 10:38:58 kurobox systemd-journald[896]: Journal stopped

これらを踏まえて、どのタイミングで microapl を実行するか考えてみます。

電源オフにする systemd サービスの作成

"systemctl poweroff" のときだけ電源をオフにしたいので、poweroff.target が引き起こされたときだけ microapl で電源オフにするというのが必然です。

また、OSシャットダウン処理のできるだけ最後のほうで microapl を実行するのが安全なので、最後のほうで実行されているユニットファイルの中身を見てみます

final.target, systemd-poweroff.service, poweroff.target の順に実行され、systemd-poweroff.service の中で poweroff-force されています。

そこで、poweroff の直前で microapl を実行するという考えで、次のユニットファイルを作成してみました。

 1[Unit]
 2Description=Power off by miconapl
 3DefaultDependencies=no
 4After=final.target
 5Before=systemd-poweroff.service
 6
 7[Service]
 8Type=oneshot
 9ExecStart=/bin/bash -c "sync && microapl -a shutdown_wait && microapl -a power_off"
10
11[Install]
12WantedBy=poweroff.target

このユニットファイルを作成して有効にして "systemctl poweroff" すると、期待通りのタイミングで実行され、機器の電源も無事にオフになりました。

1Aug 11 13:27:23 kurobox systemd[1]: Reached target shutdown.target - System Shutdown.
2Aug 11 13:27:23 kurobox systemd[1]: Reached target final.target - Late Shutdown Services.
3Aug 11 13:27:23 kurobox systemd[1]: Starting poweroff-microapl.service - Power off by miconapl...

systemd-poweroff.service 以降は実行されなくなりますが、これはしょうがないでしょう。 microapl を実行する前に sync を打っていますが、この時点で systemd-journald がまだ動作しているので念のためです。

なお、一応 poweroff.target の後に実行するようにしてもきちんと電源オフにできました。

 1[Unit]
 2Description=Power off by miconapl
 3DefaultDependencies=no
 4After=poweroff.target
 5
 6[Service]
 7Type=oneshot
 8ExecStart=/bin/bash -c "sync && microapl -a shutdown_wait && microapl -a power_off"
 9
10[Install]
11WantedBy=poweroff.target
1Aug 11 11:19:50 kurobox systemd[1]: Reached target shutdown.target - System Shutdown.
2Aug 11 11:19:50 kurobox systemd[1]: Reached target final.target - Late Shutdown Services.
3Aug 11 11:19:50 kurobox systemd[1]: systemd-poweroff.service: Deactivated successfully.
4Aug 11 11:19:50 kurobox systemd[1]: Finished systemd-poweroff.service - System Power Off.
5Aug 11 11:19:50 kurobox systemd[1]: Reached target poweroff.target - System Power Off.
6Aug 11 11:19:50 kurobox systemd[1]: Starting poweroff-microapl.service - Power off by miconapl...
7Aug 11 11:19:50 kurobox systemd[1]: Shutting down.

ただし、既に poweroff-force が実行されている状態なので、タイミングしだいで期待通り電源オフにならない可能性もあります。


不明点

期待通り電源オフにできるようになったものの、よくわからない点があります。

microapl や micro-evtd はルートパーティションにあるので、ルートパーティションがアンマウントされた後では正常に実行できないはずです。 final.target に達した時点で、ルートパーティションはアンマウント済だと思っていたのですが、そうではないということでしょうか…。