Topics で読み物として読む
この HLD は実装詳細を含みます。機能の概念・設定・運用を読み物として読みたい場合は Topics 13 章: DASH / SmartSwitch を参照。
裏取りステータス: discrepancy-found
HLD は v0.1 (2025-12) Initial Proposal。実装は HLD と乖離。sonic-platform-common module_base.py の set_admin_state_gracefully() / _graceful_shutdown_handler() および sonic-platform-daemons/sonic-chassisd/scripts/chassisd の submit_dpu_callback() は実在するが、HLD で提案されている独立した gnoi_reboot_daemon.py は sonic-platform-daemons に未取り込み。STATE_DB のフラグも HLD の CHASSIS_MODULE_INFO_TABLE / state_transition_in_progress ではなく CHASSIS_MODULE_TABLE の transition_in_progress (set_module_state_transition) と独立した gnoi_halt_in_progress フラグの 2 系統で実装されている。chassisd が直接 module.set_admin_state_gracefully を呼ぶ構成で、独立した gNOI 経路は実体がない。
Smart Switch DPU Graceful Shutdown(gnoi_reboot_daemon HALT)¶
概要¶
SmartSwitch では DPU の graceful reboot に続き graceful shutdown をサポートする1。"reboot の前半" に見えるが、CLI 起動経路、コードパス、PMON container の制限(docker / bash / hostexec 不可)から実装が分離される。chassisd が NPU 側で動き、各 DPU には gNOI Reboot RPC (HALT) を発行する gnoi_reboot_daemon.py 経由で並列に shutdown を投げる構成。
動作仕様¶
コンポーネント関係¶
flowchart LR
CLI["config chassis module shutdown DPUx"] --> CD[chassisd]
CD --> MB[module_base.py]
MB -->|"set_admin_state(down) /<br/>graceful_shutdown_handler"| ST[("STATE_DB<br/>CHASSIS_MODULE_INFO_TABLE")]
ST -- watch --> GD[gnoi_reboot_daemon.py]
GD -->|gNOI Reboot HALT| DPU[DPUx sysmgr]
DPU -->|DBUS reboot -p| KERN[DPU kernel]
GD -->|RebootStatus poll| DPU
GD --> ST
MB -->|poll until False| ST
MB --> MOD[module.py]
MOD --> PAPI[Platform API power_down]
Sequence¶
gnoi_reboot_daemon.py起動時にCHASSIS_MODULE_INFO_TABLEを subscribe(startup 系の遷移は no-op)1- ユーザが
config chassis module shutdown DPUxを発行 chassisd→module_base.set_admin_state(down)を呼出module_base.pyは DEVICE_METADATA のsubtype="SmartSwitch"かつswitch_type != dpuを確認。条件成立でgraceful_shutdown_handler()経路へ。それ以外は通常のmodule.set_admin_state(down)graceful_shutdown_handler()が STATE_DB のCHASSIS_MODULE_INFO_TABLE|DPUxにstate_transition_in_progress=True,transition_type=shutdownを書き込むgnoi_reboot_daemonは変化を検出し DPUx の sysmgr に gNOI Reboot RPCHALTを送る。sysmgr は DBUS でreboot -pを発行- daemon が
gnoi_client -rpc RebootStatusで polling - DPU が kernel shutdown 完了後、daemon が
state_transition_in_progress=Falseに戻す(タイムアウト時は失敗結果を書く) module_base.pyは 5 秒間隔で polling し False を確認、ログ出力- 最後に
module.py.set_admin_state(down)で platform API による power-down
CHASSIS_MODULE_INFO_TABLE スキーマ(STATE_DB)¶
key: CHASSIS_MODULE_INFO_TABLE|<MODULE>
| Field | 説明 |
|---|---|
state_transition_in_progress |
"True" で遷移中、"False"/不在で停止中 |
transition_start_time |
UTC 文字列 |
transition_type |
"shutdown" / "none"(reboot/startup は none) |
| 種別 | 設定者 | 解除者 |
|---|---|---|
| Startup | CLI / config load | online 到達時 |
| Shutdown | CLI / config load | gnoi_reboot_daemon が platform API 完了時 |
| Reboot | smartswitch_reboot_helper |
同左 |
並列実行と race condition¶
複数 DPU の graceful shutdown は並列に実行される1。module_base.py と smartswitch_reboot_helper が同 module の state_transition_in_progress に書き込みを競った場合、先に True に書いた側が勝つ。負け側は失敗扱いで再投を要求される。
| Scenario | 結果 |
|---|---|
| reboot 進行中に shutdown/startup | 後者が失敗。reboot 完了後再投 |
| graceful shutdown 進行中に reboot 要求 | reboot 失敗。shutdown 完走で目的達成のため reboot 不要 |
| startup 進行中に reboot | reboot 失敗 |
| switch-level reboot 進行中 | 全 module の True を一括取得。module-level 操作は失敗 |
| switch-level reboot が module-level 進行中に発行 | 進行中 module は skip、他は switch reboot で処理 |
Constraints の妙味¶
- PMON container には
docker,hostexec,bashが無い → gNOI 呼び出しを PMON 内 daemon に閉じる必要があった1 - gNOI 自体は host 側で
docker execベースに実行される設計だが、PMON は host に直接命令できないため STATE_DB IPC を介する pub/sub 経由で実行を委譲する形を採る
📋 検証エビデンス: sonic-net/SONiC/doc/smart-switch/graceful-shutdown/graceful-shutdown.md#L93-L103 (sha: 49bab5b5ff0e924f1ea52b3d9db0dfa4191a7c06)
出典:
sonic-net/SONiC/doc/smart-switch/graceful-shutdown/graceful-shutdown.md#L93-L103 (sha: 49bab5b5ff0e924f1ea52b3d9db0dfa4191a7c06)
抜粋:
This design enables the chassisd process running in the PMON container to invoke a gNOI-based reboot
when it triggers the "set_admin_state(down)" API of a DPU module, without relying on docker, bash,
or hostexec within the container.
判断根拠: PMON 制限下での実装方針と Redis pub/sub への分離の根拠。
CLI / CONFIG_DB / YANG¶
- CLI:
config chassis module shutdown DPUx(既存 chassis CLI 流用)1 - CONFIG_DB は本 HLD では追加なし。STATE_DB の
CHASSIS_MODULE_INFO_TABLEのフィールドが拡張される
制限事項¶
- module-level と switch-level の reboot/shutdown が衝突した場合、明示的な失敗で再投が必要
module_base.pyは 5 秒 poll で完了確認- DPU 側の sysmgr が gNOI HALT を受け DBUS →
reboot -pで完了する経路に依存 - v0.1 (2025-12) Initial で master 取り込み未確認
干渉する機能¶
- Smart Switch Reboot (
smartswitch_reboot_helper): 同じ STATE_DB フィールドで race - smartswitch-pmon HLD: chassisd / pmon の親設計
- Independent DPU Upgrade: shutdown 経路を再利用する可能性
- gNOI / gNMI: HALT を含む reboot RPC の依存
HLD と実装の差分
2026-05-09 時点の現行 master を裏取り。HLD と実装には次の乖離がある:
1. 独立 gnoi_reboot_daemon.py は実装されていない¶
- HLD 記述: PMON container に
gnoi_reboot_daemon.pyを新規追加し、STATE_DB pub/sub 経由で gNOI Reboot RPC (HALT) を投げる役割を担う。 - 実装位置:
sonic-platform-daemons/配下にgnoi_reboot_daemon.pyもsonic-pmonも存在しない(find -iname "*gnoi*"結果ゼロ)。代わりにsonic-chassisdのchassisd(sonic-platform-daemons/sonic-chassisd/scripts/chassisd) がmodule.set_admin_state_gracefullyを直接呼ぶ。 - 差分の中身:
HLD は「chassisd は state を書くだけ、別 daemon が gNOI を呼ぶ」と分離するが、実装は chassisd が
# sonic-chassisd/scripts/chassisd L256 try_get(self.chassis.get_module(module_index).set_admin_state_gracefully, admin_state, default=False) # L1362 try_get(module.set_admin_state_gracefully, admin_state, default=False) # L1373 module.clear_module_gnoi_halt_in_progress()module_baseの API を直接呼ぶ密結合 になっている。 - 読者への影響: HLD の図を信じて gnoi_reboot_daemon のログを探しても見つからない。pub/sub の経路(
CHASSIS_MODULE_INFO_TABLEへの書込 → daemon 検知)も存在せず、chassis_state_dbに書く前後でchassisdが直接 module API を呼ぶフロー。 - 回避策: 障害解析では
sonic-chassisdのログを最初に見る。gNOI Reboot RPC の発行サイトはmodule_base.py:601前後(_set_module_gnoi_halt_in_progressを呼んだ直後)。各 platform のmodule_base派生クラスがset_admin_state_gracefullyをどう override しているかが実体。
2. STATE_DB のフラグ命名・配置が HLD と異なる¶
- HLD 記述:
CHASSIS_MODULE_INFO_TABLE|<name>にstate_transition_in_progress等のフィールドを HSET する。 - 実装位置:
sonic-platform-common/sonic_platform_base/module_base.py:537-583_get_module_gnoi_halt_in_progress/_set_module_gnoi_halt_in_progress/clear_module_gnoi_halt_in_progressはgnoi_halt_in_progressという別フィールドを使う。module_base.pyのset_module_state_transition()(L624 付近)はCHASSIS_MODULE_TABLE|<name>(_INFO_抜き)にtransition_in_progress/transition_type/start_timeを HSET する。- 差分の中身:
HLD の
# module_base.py:566 — フラグ HSET state_db.hset(module_key, "gnoi_halt_in_progress", "True") # module_base.py:549 — 読み取り gnoi_halt_flag = state_db.hget(module_key, "gnoi_halt_in_progress")CHASSIS_MODULE_INFO_TABLE/state_transition_in_progressは実コードでは 2 系統に分割されている: (a)CHASSIS_MODULE_TABLE|<name>のtransition_in_progress(set_module_state_transition)、(b)CHASSIS_MODULE_TABLE|<name>のgnoi_halt_in_progressフラグ(HALT 完了通知用)。 - 読者への影響: 状態監視スクリプトを HLD のフィールド名で書くと取れない。reboot/shutdown 衝突検知も「片方が transition_in_progress フィールドを見れば良い」と思って書くと、
gnoi_halt_in_progressの有無を見逃して race を起こす可能性がある。 - 回避策:
- 状態確認:
redis-cli -n 6 hgetall 'CHASSIS_MODULE_TABLE|DPU0'でtransition_in_progress/transition_type/gnoi_halt_in_progressの 3 つを全部見る。 - 排他制御を独自実装する場合は両フラグを AND で評価する。
3. YANG 取り込みは確認できない¶
- HLD 記述: 新フィールドを
sonic-chassis-module.yangに追加する想定。 - 実装位置:
sonic-buildimage/src/sonic-yang-models/yang-models/sonic-chassis-module.yangにtransition_in_progress/gnoi_halt_in_progressフィールドの取り込みは確認できない。 - 読者への影響: ConfigMgmt / GNMI 経由でこれらフィールドへアクセスしようとしても YANG model 経由では到達できず、
sonic-db-cli等 raw アクセスのみが手段になる。 - 回避策: フィールドは Redis 直叩き(
redis-cli -n 6/sonic-db-cli STATE_DB)で扱う。
4. HLD は v0.1 (2025-12) Initial Proposal で master 取り込み未確認¶
- 上記乖離は HLD の v0.1 と現行実装の間で構造そのものがリファクタされたことを示唆する。設計趣旨(gNOI 経由で DPU を graceful に止める)は実装に活きているが、daemon 構成・テーブル構造は HLD と一致しない。
監査 round 2 追補(2026-05-11)¶
監査 round 2 で再裏取りした結果と、運用者向けの追加情報を補強する。本セクションは round 1 の差分記述に加え、行番号付きの再確認エビデンス・関連 Issue/PR の所在・追加の回避策コマンドをまとめる。
gnoi_reboot_daemon.pyは未実装 (find .cache/sonic-sources/sonic-platform-daemons -iname '*gnoi*'結果 0)。- 代替実装:
sonic-chassisd/scripts/chassisdL256/L1362 でmodule.set_admin_state_gracefully(admin_state)を直接呼び、L1373 でmodule.clear_module_gnoi_halt_in_progress()。 - gNOI Reboot RPC 発行サイトは
sonic_platform_base/module_base.py:601前後の_set_module_gnoi_halt_in_progress周辺。platform 派生クラスがset_admin_state_gracefullyを override。 - 関連 PR: smartswitch DPU graceful shutdown の chassisd 統合は merge 済み。独立 daemon 案は採用せず chassisd に統合された設計変更。
- 追加デバッグコマンド: shutdown フロー追跡 —
docker logs pmon 2>&1 | grep -E 'chassisd.*(graceful|halt|admin_state)'、redis-cli -n 6 hgetall 'CHASSIS_MODULE_INFO_TABLE|DPU0'で current state、redis-cli psubscribe '__keyspace@6__:CHASSIS_MODULE_INFO_TABLE*'で遷移を監視。
分類:
monitor: not_implemented— HLD の提案がコードベース master に未取り込み、または主要パスが完全に欠落している分類。本ページの仕様記述は将来仕様参考。
関連 GitHub Issue / PR¶
- sonic-buildimage #25554: Bug: gnoi-shutdown service blocks SYSTEM_READY on non-SmartSwitch platforms (closed) —
gnoi_reboot_daemon(gnoi-shutdown service) が SmartSwitch 以外で SYSTEM_READY を阻害する bug。HLD と現実装の境界条件の齟齬を示す。 - HALT 機能本体(DPU 個別停止)の取り込み PR は明示的に紐づくものが確認できず、SmartSwitch 系の複数 PR にまたがる。
確認コマンド¶
# 現行 master では gnoi_reboot_daemon は未取り込み。代替経路の確認:
find .cache/sonic-sources/sonic-platform-daemons -iname '*gnoi*' # 空であることを確認
# chassisd 経由の DPU shutdown 経路を log で追う
docker logs pmon 2>&1 | grep -E 'chassisd.*(graceful|halt|admin_state)'
# STATE_DB 側の遷移確認 (HLD の CHASSIS_MODULE_INFO_TABLE ではなく CHASSIS_MODULE_TABLE が実装名)
sonic-db-cli STATE_DB keys 'CHASSIS_MODULE_TABLE|*'
sonic-db-cli STATE_DB hgetall 'CHASSIS_MODULE_TABLE|DPU0'
# 旧 HLD のキーで参照しても何も出ない (乖離確認)
sonic-db-cli STATE_DB hgetall 'CHASSIS_MODULE_INFO_TABLE|DPU0'
# DPU shutdown 中の遷移をリアルタイム監視
redis-cli -n 6 psubscribe '__keyspace@6__:CHASSIS_MODULE_TABLE*'
# CLI からの shutdown 操作
config chassis module shutdown DPU0
show chassis modules status
引用元¶
このページを読んだ後の次アクション¶
読み手向け
- 本機能を実運用で使う場合: 実装が無いため、本機能に依存した運用は不可。代替機能 (下記リンク) で要件を満たせるか検討する
- upstream 動向を追う場合: 関連 issue / PR を sonic-net/SONiC で検索(HLD タイトル / CONFIG_DB テーブル名 / Orch クラス名で grep するのが速い)
- 代替手段 / 関連 reference: 本ページの frontmatter
relatedが空のため、Reference 索引 から関連テーブル / CLI / YANG を辿る
本ドキュメントの追跡
- monitor:
not_implemented/ last_verified:2026-05-11 - 次回再裏取りトリガ: quarterly。一覧は discrepancy-index を参照(運用詳細は repo の
meta/discrepancy-operations.md)