1# Phosphor State Manager Documentation
2
3This repository contains the software responsible for tracking and controlling
4the state of different objects within OpenBMC. This currently includes the BMC,
5Chassis, Host, and Hypervisor. The most critical feature of
6phosphor-state-manager software is its support for requests to power on and off
7the system by the user.
8
9This software also enforces any restore policy (i.e. auto power on system after
10a system power event or bmc reset) and ensures its states are updated correctly
11in situations where the BMC is rebooted and the chassis or host are in
12on/running states.
13
14This repository also provides a command line tool, obmcutil, which provides
15basic command line support to query and control phosphor-state-manager
16applications running within an OpenBMC system. This tool itself runs within an
17OpenBMC system and utilizes D-Bus APIs. These D-Bus APIs are used for
18development and debug and are not intended for end users.
19
20As with all OpenBMC applications, interfaces and properties within
21phosphor-state-manager are D-Bus interfaces. These interfaces are then used
22by external interface protocols, such as Redfish and IPMI, to report and
23control state to/by the end user.
24
25## State Tracking and Control
26
27phosphor-state-manager makes extensive use of systemd. There is a writeup
28[here][1] with an overview of systemd and its use by OpenBMC.
29
30phosphor-state-manager follows some basics design guidelines in its
31implementation and use of systemd:
32- Keep the different objects as independent as possible (host, chassis, bmc)
33- Use systemd targets for everything and keep the code within
34  phosphor-state-manager minimal
35- Ensure it can support required external interfaces, but don't necessarily
36  create 1x1 mappings otherwise every external interface will end up with its
37  own special chassis or host state request
38- If something like a hard power off can be done by just turning off the
39  chassis, don't provide a command in the host to do the same thing
40
41phosphor-state-manager implements states and state requests as defined in
42phosphor-dbus-interfaces for each object it supports.
43- [bmc][2]: The BMC has very minimal states. It is `Ready` once all services
44  within the default.target have executed. The only state change request you
45  can make of the BMC is for it to reboot itself.
46  - CurrentBMCState: NotReady, Ready
47  - RequestedBMCTransition: Reboot
48- [chassis][3]: The chassis represents the physical hardware in which the system
49  is contained. It usually has the power supplies, fans, and other hardware
50  associated with it. It can be either `On` or `Off`.
51  - CurrentPowerState: On, Off
52  - RequestedPowerTransition: On, Off
53- [host][4]: The host represents the software running on the system. In most
54  cases this is an operating system of some sort. The host can be `Off`,
55  `Running`, `TransitioningToRunning`, `TransitioningToOff`,
56  `Quiesced`(error condition), or in `DiagnosticMode`(collecting diagnostic
57  data for a failure)
58  - CurrentHostState: Off, Running, TransitioningToRunning, TransitioningToOff,
59    Quiesced, DiagnosticMode
60  - RequestedHostTransition: Off, On, Reboot, GracefulWarmReboot,
61    ForceWarmReboot
62- [hypervisor][4]: The hypervisor is an optional package systems can install
63  which tracks the state of the hypervisor on the system. This state manager
64  object implements a limited subset of the host D-Bus interface.
65  - CurrentHostState: Standby, TransitionToRunning, Running, Off, Quiesced
66  - RequestedHostTransition: On
67
68As noted above, phosphor-state-manager provides a command line tool,
69[obmcutil][5], which takes a `state` parameter. This will use D-Bus commands to
70retrieve the above states and present them to the user. It also provides other
71commands which will send the appropriate D-Bus commands to the above properties
72to power on/off the chassis and host (see `obmcutil --help` within an OpenBMC
73system).
74
75The above objects also implement other D-Bus objects like power on hours, boot
76progress, reboot attempts, and operating system status. These D-Bus objects are
77also defined out in the phosphor-dbus-interfaces repository.
78
79## Restore Policy on Power Events
80
81The [RestorePolicy][6] defines the behavior the user wants when the BMC is
82reset. If the chassis or host is on/running then this service will not run.
83If they are off then the `RestorePolicy` will be read and executed by
84phosphor-state-manager code.
85
86## BMC Reset with Host and/or Chassis On
87
88In situations where the BMC is reset and the chassis and host are on and
89running, its critical that the BMC software do two things:
90- Never impact the state of the system (causing a power off of a running system
91is very bad)
92- Ensure the BMC, Chassis, and Host states accurately represent the state of the
93system.
94
95Note that some of this logic is provided via service files in system-specific
96meta layers. That is because the logic to determine if the chassis is on or
97if the host is running can vary from system to system. The requirement to
98create the files defined below and ensure the common targets go active is a
99must for anyone wishing to enable this feature.
100
101phosphor-state-manager discovers state vs. trying to cache and save states. This
102ensure it's always getting the most accurate state information. It discovers the
103chassis state by checking the `pgood` value from the power application. If it
104determines that power is on then it will do the following:
105- Create a file called /run/openbmc/chassis@0-on
106  - The presence of this file tells the services to alter their behavior because
107    the chassis is already powered on
108- Start the obmc-chassis-poweron@0.target
109  - The majority of services in this target will "fake start" due to the file
110    being present. They will report to systemd that they started and ran
111    successfully but they actually do nothing. This is what you would want in
112    this case. Power is already on so you don't want to run the services to turn
113    power on. You do want to get the obmc-chassis-poweron@0.target in the Active
114    state though so that the chassis object within phosphor-state-manager will
115    correctly report that the chassis is `On`
116- Start a service to check if the host is on
117
118The chassis@0-on file is removed once the obmc-chassis-poweron@0.target becomes
119active (i.e. all service have been successfully started which are wanted or
120required by this target).
121
122The logic to check if the host is on sends a command to the host, and if a
123response is received then similar logic to chassis is done:
124- Create a file called /run/openbmc/host@0-on
125- Start the obmc-host-start@0.target
126  - Similar to above, most services will not run due to the file being created
127    and their service files implementing a
128    "ConditionPathExists=!/run/openbmc/host@0-request"
129
130The host@0-on file is removed once the obmc-host-start@0.target and
131obmc-host-startmin@0.target become active (i.e. all service have been
132successfully started which are wanted or required by these targets).
133
134## Building the Code
135```
136To build this package, do the following steps:
137
138    1. meson build
139    2. ninja -C build
140
141To clean the repository again run `rm -rf build`.
142```
143
144[1]: https://github.com/openbmc/docs/blob/master/architecture/openbmc-systemd.md
145[2]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/State/BMC.interface.yaml
146[3]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/State/Chassis.interface.yaml
147[4]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/State/Host.interface.yaml
148[5]: https://github.com/openbmc/phosphor-state-manager/blob/master/obmcutil
149[6]: https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Control/Power/RestorePolicy.interface.yaml
150