| # Host State Module |
| |
| <!--* |
| # Document freshness: For more information, see go/fresh-source. |
| freshness: { owner: 'tlbmc-dev' reviewed: '2026-06-05' } |
| *--> |
| |
| ## Overview & Purpose |
| |
| The **Host State** subsystem in tlBMC is responsible for monitoring, reporting, |
| and actuating the physical power state (`PowerState`) and operating system |
| execution state (`OSState`) of the host machine. |
| |
| When integrated into a platform, this module acts as the authoritative source |
| for host power transitions and drives Redfish chassis power status and |
| `ComputerSystem` reset actions (such as `PowerOn`, `ForceOff`, |
| `GracefulShutdown`, and `GracefulRestart`). It provides a flexible architecture |
| supporting direct hardware actuation via GPIO pins as well as seamless software |
| integration via Linux `inotify` file watching for platforms utilizing external |
| power control agents. |
| |
| -------------------------------------------------------------------------------- |
| |
| ## Abstract `PowerControl` Interface |
| |
| At the core of the host state management architecture is the abstract |
| `PowerControl` interface defined in |
| [power_control.h](file:///google3/third_party/milotic/external/cc/tlbmc/host_state/power_control.h). |
| This interface establishes a unified contract for querying power status, |
| executing reset actions, and subscribing to state transition events. |
| |
| ### Key Control Methods |
| |
| * **`SystemResetRequest(ResetType reset_type, absl::Duration delay)`**: |
| Maps high-level Redfish actions to specific hardware/software actuation |
| sequences based on the requested `ResetType`: |
| * `RESET_TYPE_ON` / `FORCE_ON` $\rightarrow$ `PowerOnRequest()` |
| * `RESET_TYPE_FORCE_OFF` $\rightarrow$ `PowerOffRequest()` |
| * `RESET_TYPE_POWER_CYCLE` $\rightarrow$ `PowerCycleRequest()` |
| * `RESET_TYPE_FORCE_RESTART` $\rightarrow$ `ResetRequest()` |
| * `RESET_TYPE_GRACEFUL_SHUTDOWN` $\rightarrow$ |
| `GracefulPowerOffRequest()` |
| * `RESET_TYPE_GRACEFUL_RESTART` $\rightarrow$ |
| `GracefulPowerCycleRequest()` |
| * **`GetHostState()`**: Returns the complete current `HostState` protobuf |
| containing the host identifier, current `PowerState`, and current `OSState`. |
| |
| ### Event Subscription Methods |
| |
| Subsystems and external services can register thread-safe callbacks triggered |
| during critical host transitions: |
| |
| * **`RegisterHostPowerOnToOffCallback`**: Invoked when the chassis transitions |
| from powered-on to off. |
| * **`RegisterHostPowerOffToOnCallback`**: Invoked when the chassis asserts |
| power-ok and transitions from off to powered-on. |
| * **`RegisterHostOSInactiveToStandbyCallback`**: Invoked when host POST |
| completes successfully. |
| * **`RegisterHostOSStandbyToInactiveCallback`**: Invoked when OS execution |
| halts or resets. |
| |
| -------------------------------------------------------------------------------- |
| |
| ## Hardware Actuation Mode (`PowerControlGpio`) |
| |
| The **`PowerControlGpio`** implementation |
| ([power_control.cc](file:///google3/third_party/milotic/external/cc/tlbmc/host_state/power_control.cc)) |
| interacts directly with physical board logic to govern host state transitions |
| and actuate hardware signals. |
| |
| ### State Machine Transitions |
| |
| `PowerControlGpio` maintains an active internal state machine representing the |
| chassis state: |
| |
| * `POWER_STATE_ON`: Physical power is established and verified. |
| * `POWER_STATE_WAIT_FOR_POWER_OK`: Power-on initiated; awaiting board |
| assertion of physical power good. |
| * `POWER_STATE_OFF`: System is fully powered down. |
| * `POWER_STATE_TRANSITION_TO_OFF`: Actively asserting force-off pulse. |
| * `POWER_STATE_GRACEFUL_TRANSITION_TO_OFF`: Actively awaiting graceful ACPI |
| shutdown. |
| * `POWER_STATE_CYCLE_OFF`: Intermediate off state during a power cycle before |
| re-initiating power-on. |
| * `POWER_STATE_TRANSITION_TO_CYCLE_OFF`: Initiating hard cycle shutdown. |
| * `POWER_STATE_GRACEFUL_TRANSITION_TO_CYCLE_OFF`: Awaiting ACPI graceful |
| shutdown prior to power cycle. |
| * `POWER_STATE_CHECK_FOR_WARM_RESET`: POST complete deasserted; verifying if |
| host triggered a warm reset rather than full shutdown. |
| |
| ### GPIO Actuation & Monitoring |
| |
| * **Output Control Pins**: Actuates hardware lines via precise time-duration |
| pulses using `GpioCollector::SetActiveForDuration`: |
| * `power_out_gpio_name`: Asserted to trigger power button presses |
| (`PowerPulseMs` for standard toggle, `ForceOffPulseMs` for hard power |
| cut). |
| * `reset_out_gpio_name`: Asserted to trigger warm hardware reset |
| (`ResetPulseMs`). |
| * **Input Sensing Handlers**: Subscribes to hardware line status shifts: |
| * `PowerOkHandler`: Monitors `power_ok_gpio_name`. Rising edges transition |
| the host to `POWER_STATE_ON`. Falling edges trigger power-loss callbacks |
| and drop state to `POWER_STATE_OFF` or `POWER_STATE_CYCLE_OFF`. |
| * `PostCompleteHandler`: Monitors `post_complete_gpio_name`. Rising edges |
| set OS execution to `OS_STATE_STANDBY`. Falling edges transition OS |
| execution to `OS_STATE_INACTIVE` and activate warm reset verification. |
| |
| ### Watchdog & Steady Timers |
| |
| The hardware controller utilizes asynchronous `boost::asio::steady_timer` |
| instances managed by `PowerControlThreadManager`: |
| |
| * **`PowerCycleTimer` (`PowerCycleMs` = 5000ms)**: Enforces a steady |
| off-duration delay before re-enabling power during a reboot cycle. |
| * **`PowerOKWatchdogTimer` (`PowerOKWatchdogMs` = 8000ms)**: Fires when |
| power-on is requested. If `power_ok_gpio_name` fails to assert before |
| expiration, aborts and resets state to `POWER_STATE_OFF`. |
| * **`GracefulPowerOffTimer` (`GracefulPowerOffS` = 300s)**: Sets a maximum |
| timeout window for OS-cooperative ACPI shutdowns. |
| * **`WarmResetCheckTimer` (`WarmResetCheckMs` = 500ms)**: Distinguishes |
| between intentional host reboot events and system crashes upon POST drop. |
| |
| -------------------------------------------------------------------------------- |
| |
| ## File/inotify Integration Mode (`PowerControlInotify`) |
| |
| For platforms where host power state is managed by external daemons or openbmc |
| legacy layers, **`PowerControlInotify`** |
| ([host_state_collector.cc](file:///google3/third_party/milotic/external/cc/tlbmc/host_state/host_state_collector.cc)) |
| operates as a zero-hardware integration bridge. |
| |
| ### Linux `inotify` Monitoring |
| |
| Instead of polling or reading GPIO lines, `PowerControlInotify` establishes |
| non-blocking file descriptors using `inotify_init1` and attaches |
| `IN_CLOSE_WRITE` watches directly to status JSON files (`host_power_file_path` |
| and `os_state_file_path`). Asynchronous reads are dispatched over |
| `boost::asio::posix::stream_descriptor`. |
| |
| ### D-Bus OpenBMC State Parsing |
| |
| Upon detection of an `IN_CLOSE_WRITE` event, the module parses the file payload |
| as JSON and evaluates canonical D-Bus state strings: |
| |
| * **Power State (`PowerState`)**: |
| * `xyz.openbmc_project.State.Chassis.PowerState.On` $\rightarrow$ |
| `HOST_POWER_STATE_ON` |
| * `xyz.openbmc_project.State.Chassis.PowerState.Off` $\rightarrow$ |
| `HOST_POWER_STATE_OFF` |
| * **OS Status (`OperatingSystemState`)**: |
| * `xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Standby` |
| $\rightarrow$ `OS_STATE_STANDBY` |
| * `xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive` |
| $\rightarrow$ `OS_STATE_INACTIVE` |
| |
| Transitions automatically fire registered callback collections |
| (`host_power_on_to_off_callbacks_`, etc.). |
| |
| ### Robust Initialization Retries |
| |
| If target synchronization files do not exist during early boot, the module |
| utilizes `TaskScheduler::ScheduleOneShotAsync` to execute configurable |
| exponential retries (default 5 attempts, 10-second intervals) until the |
| integration path establishes. |
| |
| -------------------------------------------------------------------------------- |
| |
| ## Protobuf Schema Reference |
| |
| The primary configurations governing host state collection and actuation reside |
| within |
| [power_control.proto](file:///google3/third_party/milotic/external/cc/tlbmc/configs/power_control.proto). |
| |
| ### `PowerControlConfig` Schema Table |
| |
| Field Name | Type | Default | Description |
| :-------------------------------- | :-------------------- | :--------------------------------------- | :---------- |
| `host_id` | `string` | empty | Unique identifier for the target host instance (e.g., `"system"`). |
| `chassis_id` | `string` | empty | Target chassis physical identifier (e.g., `"chassis_1"`). |
| `power_ok_gpio_name` | `string` | empty | Input GPIO line name detecting physical host power assertion. |
| `post_complete_gpio_name` | `string` | empty | Input GPIO line name detecting operating system POST readiness. |
| `power_out_gpio_name` | `string` | empty | Output GPIO pin line triggering power button actuation. |
| `reset_out_gpio_name` | `string` | empty | Output GPIO pin line triggering hardware warm reset actuation. |
| `timer_map` | `map<string, uint32>` | standard defaults | Custom override durations for pulse widths and watchdogs in milliseconds. |
| `host_power_file_path` | `string` | `"/var/lib/power-control/state.json"` | Target file path monitored via `inotify` for physical power changes. |
| `os_state_file_path` | `string` | `"/var/lib/power-control/os-state.json"` | Target file path monitored via `inotify` for OS state transitions. |
| `host_power_related_state_config` | `RelatedStateConfig` | none | Mapping linking physical power status to downstream Redfish resource dependencies. |
| `os_state_related_state_config` | `RelatedStateConfig` | none | Mapping linking OS execution status to processor and memory resource active visibility. |
| |
| -------------------------------------------------------------------------------- |
| |
| ## Platform Configuration Examples |
| |
| Platform integrators activate and tailor host state handling by supplying an |
| explicit `power_control_configs.textproto` bundle loaded automatically by |
| `ProtoConfigParser`. |
| |
| ### Example 1: Direct Hardware GPIO Mode |
| |
| ```protobuf |
| # proto-file: third_party/milotic/external/cc/tlbmc/configs/power_control.proto |
| # proto-message: PowerControlConfigs |
| |
| hotswap_pin_name: "FM_HOTSWAP_PWR_CYCLE_R" |
| |
| power_control_configs { |
| host_id: "system1" |
| chassis_id: "chassis_1" |
| power_ok_gpio_name: "PWRGD_CPU0_PLD" |
| post_complete_gpio_name: "POST_DONE" |
| power_out_gpio_name: "PWR_BTN_N" |
| reset_out_gpio_name: "RESET_BTN_N" |
| timer_map: { key: "ForceOffPulseMs" value: 5000 } |
| timer_map: { key: "GracefulPowerOffS" value: 300 } |
| timer_map: { key: "PowerCycleMs" value: 5000 } |
| timer_map: { key: "PowerOKWatchdogMs" value: 8000 } |
| timer_map: { key: "PowerPulseMs" value: 1000 } |
| timer_map: { key: "ResetPulseMs" value: 100 } |
| } |
| ``` |
| |
| ### Example 2: File-Based `inotify` Bridge Mode |
| |
| ```protobuf |
| # proto-file: third_party/milotic/external/cc/tlbmc/configs/power_control.proto |
| # proto-message: PowerControlConfigs |
| |
| power_control_configs { |
| host_id: "system" |
| chassis_id: "chassis_main" |
| |
| host_power_file_path: "/var/lib/power-control/state.json" |
| os_state_file_path: "/var/lib/power-control/os-state.json" |
| |
| host_power_related_state_config { |
| host_id: "system" |
| resource_identifiers: "/phys/M2_0" |
| related_state: RELATED_STATE_HOST_POWER |
| expected_uptime { seconds: 30 } |
| } |
| |
| os_state_related_state_config { |
| host_id: "system" |
| resource_identifiers: "/phys/CPU0" |
| resource_identifiers: "/phys/DIMM0" |
| related_state: RELATED_STATE_OS_STATE |
| } |
| } |
| ``` |
| |
| -------------------------------------------------------------------------------- |
| |
| ## Code References |
| |
| * **Main Interfaces**: |
| * [power_control.h](file:///google3/third_party/milotic/external/cc/tlbmc/host_state/power_control.h) |
| * [host_state_collector.h](file:///google3/third_party/milotic/external/cc/tlbmc/host_state/host_state_collector.h) |
| * **Primary Implementations**: |
| * [power_control.cc](file:///google3/third_party/milotic/external/cc/tlbmc/host_state/power_control.cc) |
| * [host_state_collector.cc](file:///google3/third_party/milotic/external/cc/tlbmc/host_state/host_state_collector.cc) |
| * **Configuration & Schemas**: |
| * [power_control.proto](file:///google3/third_party/milotic/external/cc/tlbmc/configs/power_control.proto) |
| * [proto_config_parser.cc](file:///google3/third_party/milotic/external/cc/tlbmc/configs/proto_config_parser.cc) |