blob: aece5365a2cdfdf7173aaed26bc5e1e4c0ced3d0 [file] [log] [blame]
Andrew Geisslera90a31a2016-12-13 16:16:28 -06001#pragma once
2
Andrew Geisslere426b582020-05-28 12:40:55 -05003#include "config.h"
4
Andrew Geissler928bbf12023-02-14 13:30:14 -06005#include "utils.hpp"
Andrew Geisslere426b582020-05-28 12:40:55 -05006
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -05007#include <cereal/cereal.hpp>
Andrew Geisslera90a31a2016-12-13 16:16:28 -06008#include <sdbusplus/bus.hpp>
William A. Kennington IIId998f822018-10-17 23:17:57 -07009#include <sdeventplus/clock.hpp>
10#include <sdeventplus/event.hpp>
11#include <sdeventplus/utility/timer.hpp>
Patrick Williams9a286db2024-01-17 06:29:47 -060012#include <xyz/openbmc_project/State/Chassis/server.hpp>
13#include <xyz/openbmc_project/State/PowerOnHours/server.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050014
15#include <chrono>
Patrick Williams6ed41ea2022-04-05 15:50:21 -050016#include <filesystem>
Andrew Geisslera90a31a2016-12-13 16:16:28 -060017
18namespace phosphor
19{
20namespace state
21{
22namespace manager
23{
24
Patrick Williamsf053e6f2022-07-22 19:26:54 -050025using ChassisInherit = sdbusplus::server::object_t<
Patrick Williams7e969cb2023-08-23 16:24:23 -050026 sdbusplus::server::xyz::openbmc_project::state::Chassis,
27 sdbusplus::server::xyz::openbmc_project::state::PowerOnHours>;
Patrick Williams8f8ba392017-05-05 15:47:39 -050028namespace sdbusRule = sdbusplus::bus::match::rules;
Patrick Williams6ed41ea2022-04-05 15:50:21 -050029namespace fs = std::filesystem;
Patrick Williams8f8ba392017-05-05 15:47:39 -050030
Andrew Geisslera90a31a2016-12-13 16:16:28 -060031/** @class Chassis
32 * @brief OpenBMC chassis state management implementation.
33 * @details A concrete implementation for xyz.openbmc_project.State.Chassis
34 * DBus API.
35 */
Patrick Williams8f8ba392017-05-05 15:47:39 -050036class Chassis : public ChassisInherit
Andrew Geisslera90a31a2016-12-13 16:16:28 -060037{
Andrew Geissler58a18012018-01-19 19:36:05 -080038 public:
39 /** @brief Constructs Chassis State Manager
40 *
41 * @note This constructor passes 'true' to the base class in order to
42 * defer dbus object registration until we can run
43 * determineInitialState() and set our properties
44 *
45 * @param[in] bus - The Dbus bus object
Andrew Geissler58a18012018-01-19 19:36:05 -080046 * @param[in] objPath - The Dbus object path
Potin Lai70f36d82022-03-15 10:25:39 +080047 * @param[in] id - Chassis id
Andrew Geissler58a18012018-01-19 19:36:05 -080048 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -050049 Chassis(sdbusplus::bus_t& bus, const char* objPath, size_t id) :
Patrick Williams76070742022-04-05 15:20:12 -050050 ChassisInherit(bus, objPath, ChassisInherit::action::defer_emit),
51 bus(bus),
Andrew Geissler58a18012018-01-19 19:36:05 -080052 systemdSignals(
53 bus,
54 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
55 sdbusRule::path("/org/freedesktop/systemd1") +
56 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
William A. Kennington IIIbd28f022022-11-22 17:11:49 -080057 [this](sdbusplus::message_t& m) { sysStateChange(m); }),
58 id(id),
59 pohTimer(
60 sdeventplus::Event::get_default(), [this](auto&) { pohCallback(); },
61 std::chrono::hours{1}, std::chrono::minutes{1})
Andrew Geissler58a18012018-01-19 19:36:05 -080062 {
Andrew Geissler928bbf12023-02-14 13:30:14 -060063 utils::subscribeToSystemdSignals(bus);
Andrew Geissler0029a5d2017-01-24 14:48:35 -060064
Potin Lai70f36d82022-03-15 10:25:39 +080065 createSystemdTargetTable();
66
Matt Spinler9eab9862018-07-11 14:13:52 -050067 restoreChassisStateChangeTime();
68
Andrew Geissler77a91832022-05-11 12:11:03 -040069 // No default in PDI so start at Good, skip D-Bus signal for now
70 currentPowerStatus(PowerStatus::Good, true);
Andrew Geissler58a18012018-01-19 19:36:05 -080071 determineInitialState();
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060072
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050073 restorePOHCounter(); // restore POHCounter from persisted file
74
Andrew Geissler58a18012018-01-19 19:36:05 -080075 // We deferred this until we could get our property correct
76 this->emit_object_added();
77 }
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060078
Andrew Geissler58a18012018-01-19 19:36:05 -080079 /** @brief Set value of RequestedPowerTransition */
80 Transition requestedPowerTransition(Transition value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060081
Andrew Geissler58a18012018-01-19 19:36:05 -080082 /** @brief Set value of CurrentPowerState */
83 PowerState currentPowerState(PowerState value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060084
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050085 /** @brief Get value of POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -050086 using ChassisInherit::pohCounter;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050087
88 /** @brief Increment POHCounter if Chassis Power state is ON */
89 void startPOHCounter();
90
Andrew Geissler58a18012018-01-19 19:36:05 -080091 private:
Potin Lai70f36d82022-03-15 10:25:39 +080092 /** @brief Create systemd target instance names and mapping table */
93 void createSystemdTargetTable();
94
Andrew Geissler58a18012018-01-19 19:36:05 -080095 /** @brief Determine initial chassis state and set internally */
96 void determineInitialState();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060097
Adriana Kobylak396ed8a2022-03-22 15:45:41 +000098 /** @brief Determine status of power into system by examining all the
99 * power-related interfaces of interest
100 */
Andrew Geissler8b1f8622022-01-28 16:37:07 -0600101 void determineStatusOfPower();
102
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000103 /** @brief Determine status of power provided by an Uninterruptible Power
104 * Supply into the system
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400105 *
106 * @return True if UPS power is good, false otherwise
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000107 */
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400108 bool determineStatusOfUPSPower();
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000109
110 /** @brief Determine status of power provided by the power supply units into
111 * the system
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400112 *
113 * @return True if PSU power is good, false otherwise
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000114 */
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400115 bool determineStatusOfPSUPower();
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000116
Matthew Barthbe6efab2022-03-01 13:21:45 -0600117 /** @brief Start the systemd unit requested
Andrew Geissler58a18012018-01-19 19:36:05 -0800118 *
Matthew Barthbe6efab2022-03-01 13:21:45 -0600119 * This function calls `StartUnit` on the systemd unit given.
Andrew Geissler58a18012018-01-19 19:36:05 -0800120 *
Matthew Barthbe6efab2022-03-01 13:21:45 -0600121 * @param[in] sysdUnit - Systemd unit
Andrew Geissler58a18012018-01-19 19:36:05 -0800122 */
Matthew Barthbe6efab2022-03-01 13:21:45 -0600123 void startUnit(const std::string& sysdUnit);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600124
Andrew Geissler77a91832022-05-11 12:11:03 -0400125 /** @brief Restart the systemd unit requested
126 *
127 * This function calls `RestartUnit` on the systemd unit given.
128 * This is useful when needing to restart a service that is already running
129 *
130 * @param[in] sysdUnit - Systemd unit to restart
131 */
132 void restartUnit(const std::string& sysdUnit);
133
Andrew Geissler58a18012018-01-19 19:36:05 -0800134 /**
135 * @brief Determine if target is active
136 *
137 * This function determines if the target is active and
138 * helps prevent misleading log recorded states.
139 *
140 * @param[in] target - Target string to check on
141 *
142 * @return boolean corresponding to state active
143 **/
144 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600145
Andrew Geissler58a18012018-01-19 19:36:05 -0800146 /** @brief Check if systemd state change is relevant to this object
147 *
148 * Instance specific interface to handle the detected systemd state
149 * change
150 *
151 * @param[in] msg - Data associated with subscribed signal
152 *
153 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500154 int sysStateChange(sdbusplus::message_t& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600155
Andrew Geissler58a18012018-01-19 19:36:05 -0800156 /** @brief Persistent sdbusplus DBus connection. */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500157 sdbusplus::bus_t& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600158
Andrew Geissler58a18012018-01-19 19:36:05 -0800159 /** @brief Used to subscribe to dbus systemd signals **/
160 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500161
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000162 /** @brief Watch for any changes to UPS properties **/
Andrew Geissler2cf2a262022-02-02 14:38:41 -0600163 std::unique_ptr<sdbusplus::bus::match_t> uPowerPropChangeSignal;
164
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000165 /** @brief Watch for any changes to PowerSystemInputs properties **/
166 std::unique_ptr<sdbusplus::bus::match_t> powerSysInputsPropChangeSignal;
167
Potin Lai70f36d82022-03-15 10:25:39 +0800168 /** @brief Chassis id. **/
169 const size_t id = 0;
170
171 /** @brief Transition state to systemd target mapping table. **/
172 std::map<Transition, std::string> systemdTargetTable;
173
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500174 /** @brief Used to Set value of POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500175 uint32_t pohCounter(uint32_t value) override;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500176
William A. Kennington IIId998f822018-10-17 23:17:57 -0700177 /** @brief Used by the timer to update the POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500178 void pohCallback();
William A. Kennington IIId998f822018-10-17 23:17:57 -0700179
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500180 /** @brief Used to restore POHCounter value from persisted file */
181 void restorePOHCounter();
182
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500183 /** @brief Serialize and persist requested POH counter.
184 *
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500185 * @return fs::path - pathname of persisted requested POH counter.
186 */
Allen.Wangba182f02022-03-23 19:01:53 +0800187 fs::path serializePOH();
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500188
Matt Spinler81957842018-07-11 10:37:12 -0500189 /** @brief Deserialize a persisted requested POH counter.
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500190 *
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500191 * @param[in] retCounter - deserialized POH counter value
192 *
193 * @return bool - true if the deserialization was successful, false
194 * otherwise.
195 */
Allen.Wangba182f02022-03-23 19:01:53 +0800196 bool deserializePOH(uint32_t& retCounter);
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500197
Matt Spinler9eab9862018-07-11 14:13:52 -0500198 /** @brief Sets the LastStateChangeTime property and persists it. */
199 void setStateChangeTime();
200
201 /** @brief Serialize the last power state change time.
202 *
203 * Save the time the state changed and the state itself.
204 * The state needs to be saved as well so that during rediscovery
205 * on reboots there's a way to know not to update the time again.
206 */
207 void serializeStateChangeTime();
208
209 /** @brief Deserialize the last power state change time.
210 *
211 * @param[out] time - Deserialized time
212 * @param[out] state - Deserialized power state
213 *
214 * @return bool - true if successful, false otherwise.
215 */
216 bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
217
218 /** @brief Restores the power state change time.
219 *
220 * The time is loaded into the LastStateChangeTime D-Bus property.
221 * On the very first start after this code has been applied but
222 * before the state has changed, the LastStateChangeTime value
223 * will be zero.
224 */
225 void restoreChassisStateChangeTime();
226
William A. Kennington IIId998f822018-10-17 23:17:57 -0700227 /** @brief Timer used for tracking power on hours */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500228 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer;
Ben Tyner2c36e5a2021-07-12 14:56:49 -0500229
230 /** @brief Function to check for a standby voltage regulator fault
231 *
232 * Determine if a standby voltage regulator fault was detected and
233 * return true or false accordingly.
234 *
235 * @return true if fault detected, else false
236 */
Pavithra Barithayaa1c0e5c2024-06-21 12:39:38 -0500237 static bool standbyVoltageRegulatorFault();
Andrew Geissler2cf2a262022-02-02 14:38:41 -0600238
239 /** @brief Process UPS property changes
240 *
241 * Instance specific interface to monitor for changes to the UPS
242 * properties which may impact CurrentPowerStatus
243 *
244 * @param[in] msg - Data associated with subscribed signal
245 *
246 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500247 void uPowerChangeEvent(sdbusplus::message_t& msg);
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000248
249 /** @brief Process PowerSystemInputs property changes
250 *
251 * Instance specific interface to monitor for changes to the
252 * PowerSystemInputs properties which may impact CurrentPowerStatus
253 *
254 * @param[in] msg - Data associated with subscribed signal
255 *
256 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500257 void powerSysInputsChangeEvent(sdbusplus::message_t& msg);
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600258};
259
260} // namespace manager
261} // namespace state
262} // namespace phosphor