AW-INC. 研究開発室

with secure communication

MS-02 ULTRA を電源断から Wake on LAN で起こし、遠隔でスリープさせる

本記事にはアフィリエイト広告(Amazon アソシエイト)が含まれます。

実測日: Mon Sep 28 2026 09:00:00 GMT+0900 (Japan Standard Time)

MS-02 ULTRA は、10GbE を備えたミニ PC としては大きな RAM を積めるので、LLM のコンパイルや量子化のような長時間の処理に向く。
一方で、使わない時間も電源を入れておくには消費電力が大きい。
本記事では、電源を落とした状態(S5)から Wake on LAN で起こし、処理が終わったら遠隔でスリープさせる運用で踏んだ落とし穴を示す。

S5 からの Wake on LAN

対象は Realtek の 10GbE ポートである。
同じ LAN の Rock 5B から magic packet を撃つと、48〜50 秒で Windows 側の SSH(port 2222)が、64〜66 秒で WSL2 側の SSH(port 22)が応答した。
2 回試して 2 回とも 1 発で成功した。
高速スタートアップは無効(HiberbootEnabled=0)だが、ファームウェア側で S5 からの wake が有効になっている。

cold boot では WSL2 は自動起動しない。
port 2222 が応答したら、Windows 側から WSL2 の sshd を立てる。

wsl -d Ubuntu-24.04 -u root -- systemctl restart ssh

無操作 5 時間で勝手に寝る電源プラン

ある日、WoL で起こしてから 5 時間後に、走らせていた処理が止まった。
イベントログには 42(スリープ入り)と、その 3 秒後に 107(復帰)が残っていた。
原因は電源プランで、STANDBYIDLE と HIBERNATEIDLE の AC 側がどちらも 18,000 秒(5 時間)だった。

WSL2 側でどれだけ CPU を回しても、Windows の無操作判定はリセットされない。
Windows から見ると、画面もキーボードも触られていない状態が続いているからである。
長時間のビルド中に砂時計が進み続け、5 時間で寝る。

AC 側だけ 0(無効)にした。

powercfg /setacvalueindex SCHEME_CURRENT SUB_SLEEP STANDBYIDLE 0
powercfg /setacvalueindex SCHEME_CURRENT SUB_SLEEP HIBERNATEIDLE 0
powercfg /setactive SCHEME_CURRENT

この例では処理は凍結されただけで死なず、復帰後に完走した。
しかし復帰に失敗すれば走行を失うので、5 時間を超える処理の前には必ず確認している。

遠隔でスリープさせる手順

ssh 越しに .NET の SetSuspendState を呼び、S3 を明示する。

ssh ms02.win 'powershell -NoProfile -Command "Add-Type -AssemblyName System.Windows.Forms; Start-Sleep -Seconds 3; [System.Windows.Forms.Application]::SetSuspendState([System.Windows.Forms.PowerState]::Suspend, $false, $false)"'

ssh は Terminated(exit 143)で終わる。
それが正常で、Windows 側と WSL2 側の両方が ssh に応答しなくなれば S3 に入っている。

rundll32.exe powrprof.dll,SetSuspendState 0,1,0 は使わない。
この呼び方は引数を無視し、休止状態が有効な機械では休止状態に入る。
RAM を 109 GB 使っている状態で撃つと、109 GB をディスクに書き出すことになる。
.NET の PowerState::Suspend は S3 を要求するので、こちらを使う。

スリープ中の時計は止まる

S3 の間、WSL2 の VM は止まり、CLOCK_MONOTONIC も /proc/uptime も凍結する。
実測では壁時計 38 分 21 秒に対し、単調時計は 6 分しか進まなかった。
systemd の ActiveEnterTimestamp は壁時計なので、所要時間の算出に使えない。
処理にかかった時間は CPU 時間(systemctl show -p CPUUsageNSec)で見る。

走行中の process は凍結されるだけで生き残る。
7 時間 52 分と 32 分の 2 例で確認した。

勝手に起きないための確認

寝かせる前に powercfg /devicequery wake_armed を見る。
期待は NIC 3 枚(Intel I226-LM、Realtek 10GbE、Wi-Fi 7 BE200)だけで、USB の xHCI が入っていると勝手に起きる。
Get-NetAdapterPowerManagement で WakeOnMagicPacket=Enabled かつ WakeOnPattern=Disabled なら、magic packet では起きて SSH や ARP では起きない。

調査はイベントログが早い

電源まわりの調査は、System ログの ID で区分できる。

Get-WinEvent -FilterHashtable @{LogName='System';Id=@(41,42,107,109,1074,6008)}

42 はスリープ入り、107 は復帰、1074 は利用者が落とした、41 と 6008 は異常断である。
ssh 経由で日本語が化けるときは、-EncodedCommand に UTF-16LE の base64 を渡す。

WSL2 が 30 秒ごとに落ちる現象

おまけとして、wsl --shutdown では止まらない現象を 1 つ記録しておく。
WSL2 のログに Operation canceled @p9io.cpp:258 (AcceptAsync) が出た直後、systemd-logind: The system will power off now! が続き、30〜45 秒間隔で distro が落ち続けた。
/mnt/c への 9p 接続が Windows 側から落とされ、logind が distro を止める流れである。
wsl --shutdown と distro の再起動では再発したが、Windows ごと S5 へ落として WoL で起こすと止まった。
遠隔で完結するので、同じ症状を見たら試す価値がある。

なお、mirrored networking で port 22 だけが外から届かなくなる現象は別物である。
WSL2 は再起動しておらず sshd も内部では動いているので、Windows 側から systemctl restart ssh を 1 回打てば復旧する。
「ssh が届かない」と「止まっている」を区別しないと、動いている処理を失う。

この記事で扱った機材

MS-02 ULTRA(ミニ PC)

10GbE と 2.5GbE を備えたミニ PC。S5 からの Wake on LAN が効くので、電源を落としたまま遠隔で運用できる。


投稿日

カテゴリー:

投稿者: