# Supermicro SYS-4028GR-TXRT がシャットダウン後に復活するので、ipmitool で電源を切るようにした

2026-10-06

自宅ラボ環境の GPU サーバーが、シャットダウンしても止まらなくなりました。
GPU Console（GPU サーバーの環境を管理するために自作した Web UI）で Graceful Shutdown を押すと、電源はいったん落ちます。
ところが、数秒後には再び起動します。
SSH から `systemctl poweroff` を実行しても同じでした。

先に結論を書くと、OS の終了処理を済ませたあとに `ipmitool` で BMC へ電源断を指示するようにしたところ、電源 OFF のまま止まるようになりました。
自動で起動してしまう原因そのものは、まだ特定できていません。

## 電源はいったん切れている

対象は Supermicro の `SYS-4028GR-TXRT` で、マザーボードは `X10DGO-T` です。
調査した時点の BIOS は `2.0a`、BMC ファームウェアは `2.03`、通常起動の Linux カーネルは `7.0.0-34-generic` でした。

GPU Console の Graceful Shutdown は、内部で次の IPMI コマンドを送っています。

```sh
ipmitool chassis power soft
```

`soft` は ACPI 経由で OS に終了を求める操作で、`off` は OS の終了処理を待たずに電源を切る操作です。
この違いは [ipmitool の公式マニュアル](https://github.com/ipmitool/ipmitool/blob/master/doc/ipmitool.1.in) に書かれています。

最初は GPU Console 側の不具合を疑いました。
そこで、外部ホストから BMC の電源状態を監視しながら、GPU Console と同じコマンドと OS の `systemctl poweroff` の両方で電源を切ってみました。

| 操作 | OFF を検出 | 再び ON を検出 | OFF だった時間 |
|---|---|---|---|
| GPU Console と同じ `chassis power soft` | 03:48:24.208 | 03:48:28.629 | 約 4.4 秒 |
| OS の `systemctl poweroff` | 03:51:04.781 | 03:51:08.811 | 約 4.0 秒 |

時刻は調査日の UTC です。
どちらの試験でも電源を切るコマンドは 1 回だけ送り、最初の試験の間は GPU Console の画面にある電源ボタンにも触れていません。

どちらの経路でも、電源は一度 OFF になってから 4 秒ほどで ON に戻っていました。

## 起動のきっかけになりそうな設定を確かめる

まず、自動起動のきっかけになりそうな設定を確認しました。

- 接続中の NIC の Wake-on-LAN は無効
- BMC の Power Restore Policy は `always-off`
- BIOS の Restore on AC Power Loss は `Stay Off`
- BMC と systemd の watchdog は無効
- RTC に起動予約はない

未接続の NIC だけは WOL が有効だったので、ACPI、PCIe、USB の wake とまとめて一時的に無効にしました。
それでも結果は変わりません。
ほかにも条件を変えて試した結果が次の表です。

| 試した条件 | 結果 |
|---|---|
| ACPI、PCIe、USB の wake と、両 NIC の WOL を無効化 | 約 4.0 秒後に自動起動 |
| BMC を cold reset してから poweroff | 約 4.1 秒後に自動起動 |
| 旧カーネル `7.0.0-29-generic` で poweroff | 約 4.1 秒後に自動起動 |
| NVIDIA 関連サービスを止め、ドライバをすべてアンロード | 約 4.1 秒後に自動起動 |

旧カーネルでも、NVIDIA 関連のサービスとドライバを止めた状態でも、約 4 秒後に起動しました。
新しいカーネルだけで起きる症状ではなく、稼働中の NVIDIA ドライバが引き起こしている可能性も低そうです。
試験のために変えた wake の設定と起動カーネルは、あとで元に戻しました。

OS のログを見ると、`poweroff.target` までは到達しています。
journal が止まったあとの出力もシリアルコンソールで採取したところ、最後の行は次のとおりでした。

```text
Powering off.
[131.033911] reboot: Power down
```

接頭辞は `reboot:` ですが、メッセージは `Power down` なので、カーネルは電源断を選んでいます。
BIOS、BMC、基板のどこで起動がかかっているのかは、このログからは分かりません。

## halt してから BMC で切ると止まる

次に、OS の停止と電源断を別々に行ってみました。
まず SSH から OS を停止します。

```sh
sudo systemctl halt
```

停止が終わったのを確かめてから、別の管理ホストから BMC に電源断を指示します。
接続先とユーザー名は例です。

```sh
ipmitool -I lanplus -H <BMCのアドレス> -U <管理ユーザー> -a chassis power off
```

halt の完了後に BMC へ `off` を送ると、観測した 60 秒間は OFF のままでした。
その後はこちらから Power On して試験を終えました。

このときは halt から 45 秒待ってから `off` を送りましたが、停止にかかる時間は動いている処理によって変わります。
`off` は OS を正常に終了させるコマンドではないので、手で送るなら秒数を決め打ちせず、KVM やシリアルコンソールで停止の完了を確かめてからにします。

毎回これを手で行う代わりに、通常の poweroff の最後で、OS 自身から BMC へ `off` を送らせることにしました。

## systemd の最終フックから ipmitool を呼ぶ

使ったのは systemd のシャットダウンフックです。
次の場所に実行可能なスクリプトを置きました。

```text
/usr/lib/systemd/system-shutdown/bmc-poweroff
```

このディレクトリにある実行ファイルは、サービスが止まったあと、電源を切る直前に呼ばれます。
引数には `poweroff`、`halt`、`reboot` などの操作名が渡され、複数のフックは並列に実行されます（[systemd の公式ドキュメント](https://github.com/systemd/systemd/blob/main/man/systemd-poweroff.service.xml)）。

今回のフックは `poweroff` のときだけ動き、次の順に処理します。

1. 既存の fwupd と mdadm の終了処理が終わるのを待つ
2. 永続ストレージに書き込み可能なマウントが残っていないこと、swap が止まっていることを確かめる
3. `sync` を完了させる
4. ローカルの IPMI インターフェースを復旧する
5. BMC に電源断を 1 回だけ送る

最後に送るのは次のコマンドです。

```sh
ipmitool -I open chassis power off
```

`-I open` はローカルの IPMI デバイスを使う指定なので、ネットワーク越しの認証情報は要りません（[ipmitool の公式マニュアル](https://github.com/ipmitool/ipmitool/blob/master/doc/ipmitool.1.in)）。
終了処理の待機やストレージの確認に失敗したときは、BMC への `off` は送らず、通常の poweroff の経路に戻します。

フックの全体は [bmc-poweroff.sh](/articles/supermicro-sys-4028gr-ipmitool-shutdown/bmc-poweroff.sh) に置きました。
使うときは拡張子を外して `/usr/lib/systemd/system-shutdown/bmc-poweroff` に置き、実行権限を付けます。
ログはコンソールとシリアルポートの `/dev/ttyS1` に書き出しているので、シリアルポートの番号は機体に合わせて変えてください。

この形に落ち着くまでに、試験で 2 回つまずきました。

### 終わったはずのフックを待っていた

最初の試験では、fwupd の処理がまだ残っていると判定して通常の poweroff に戻り、元どおり自動起動しました。
待っていたプロセスを調べると、実行中ではなく、終了済みのゾンビプロセスになっていました。
並列に動くフックは systemd が回収するまでプロセス情報が残るので、プロセス名だけで判定すると、終了処理がまだ続いているように見えます。
プロセスの状態も見るようにして、終了済みの `Z` と `X` は待つ対象から外しました。

### シャットダウン中に /dev/ipmi0 が消えていた

次の試験では、ルートファイルシステムが読み取り専用になり、swap も止まったところまでは確認できました。
ところが、最後の `ipmitool` が失敗しました。
この環境の `openipmi.service` は、停止するときに `ipmi_devintf` をアンロードします。
そのため、普段は存在する `/dev/ipmi0` が、最終フックの時点ではなくなっていました。
フックの中で `ipmi_si` と `ipmi_devintf` を読み込み直し、必要なら `/proc/devices` から取ったメジャー番号で `/dev/ipmi0` を作り直すようにしました。

## 普段のシャットダウンで止まるようになった

直したあと、普段どおりの操作で試しました。

```sh
sudo systemctl poweroff
```

コンソールには、`ipmitool` の次の応答が出ました。

```text
Chassis Power Control: Down/Off
```

外部からの監視では、05:04:52.813 から 05:05:53.964 までの約 61 秒間、OFF のままでした。
GPU Console と同じ `chassis power soft` でも、最終フックから `off` が送られ、60 秒以上 OFF のままになることを確かめました。
どちらの試験も、最後はこちらから起動しています。

今の電源断の流れは次のとおりです。

```text
Graceful Shutdown / systemctl poweroff
  → OS のサービス停止・ストレージ終了処理
  → 最終フックでローカル IPMI を復旧
  → BMC に chassis power off
  → 電源 OFF を維持
```

フックで電源を切ったあとに起動し直しても、停止前に動いていた 7 個のコンテナと、Open WebUI、ComfyUI、llama-server は元どおり復帰しました。

フックを止めたいときは、実行権限を外します。

```sh
sudo chmod -x /usr/lib/systemd/system-shutdown/bmc-poweroff
```

ただし、そうすると通常の poweroff に戻るので、この機体では自動起動が再発する可能性があります。

## 原因はまだ分かっていない

通常の poweroff と、OS を止めてから BMC へ `off` を送る場合とで、結果が分かれることまでは確認できました。
ただし、この違いが BIOS、BMC、基板のどこで生じているかは特定できていません。
観測も 60 秒程度なので、長く止めておいた場合や、繰り返し実行した場合の挙動もまだ確かめていません。

現在は、GPU Console の Graceful Shutdown からこのフックを経由して電源を切っています。
