blob: 7e9c7b98ece383e30c79049340fd61cad99a822a [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
5#include "xyz/openbmc_project/State/Chassis/server.hpp"
6#include "xyz/openbmc_project/State/PowerOnHours/server.hpp"
7
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -05008#include <cereal/cereal.hpp>
Andrew Geisslera90a31a2016-12-13 16:16:28 -06009#include <sdbusplus/bus.hpp>
William A. Kennington IIId998f822018-10-17 23:17:57 -070010#include <sdeventplus/clock.hpp>
11#include <sdeventplus/event.hpp>
12#include <sdeventplus/utility/timer.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050013
14#include <chrono>
Patrick Williams6ed41ea2022-04-05 15:50:21 -050015#include <filesystem>
Andrew Geisslera90a31a2016-12-13 16:16:28 -060016
17namespace phosphor
18{
19namespace state
20{
21namespace manager
22{
23
Patrick Williamsf053e6f2022-07-22 19:26:54 -050024using ChassisInherit = sdbusplus::server::object_t<
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050025 sdbusplus::xyz::openbmc_project::State::server::Chassis,
26 sdbusplus::xyz::openbmc_project::State::server::PowerOnHours>;
Patrick Williams8f8ba392017-05-05 15:47:39 -050027namespace sdbusRule = sdbusplus::bus::match::rules;
Patrick Williams6ed41ea2022-04-05 15:50:21 -050028namespace fs = std::filesystem;
Patrick Williams8f8ba392017-05-05 15:47:39 -050029
Andrew Geisslera90a31a2016-12-13 16:16:28 -060030/** @class Chassis
31 * @brief OpenBMC chassis state management implementation.
32 * @details A concrete implementation for xyz.openbmc_project.State.Chassis
33 * DBus API.
34 */
Patrick Williams8f8ba392017-05-05 15:47:39 -050035class Chassis : public ChassisInherit
Andrew Geisslera90a31a2016-12-13 16:16:28 -060036{
Andrew Geissler58a18012018-01-19 19:36:05 -080037 public:
38 /** @brief Constructs Chassis State Manager
39 *
40 * @note This constructor passes 'true' to the base class in order to
41 * defer dbus object registration until we can run
42 * determineInitialState() and set our properties
43 *
44 * @param[in] bus - The Dbus bus object
Andrew Geissler58a18012018-01-19 19:36:05 -080045 * @param[in] objPath - The Dbus object path
Potin Lai70f36d82022-03-15 10:25:39 +080046 * @param[in] id - Chassis id
Andrew Geissler58a18012018-01-19 19:36:05 -080047 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -050048 Chassis(sdbusplus::bus_t& bus, const char* objPath, size_t id) :
Patrick Williams76070742022-04-05 15:20:12 -050049 ChassisInherit(bus, objPath, ChassisInherit::action::defer_emit),
50 bus(bus),
Andrew Geissler58a18012018-01-19 19:36:05 -080051 systemdSignals(
52 bus,
53 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
54 sdbusRule::path("/org/freedesktop/systemd1") +
55 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
William A. Kennington IIIbd28f022022-11-22 17:11:49 -080056 [this](sdbusplus::message_t& m) { sysStateChange(m); }),
57 id(id),
58 pohTimer(
59 sdeventplus::Event::get_default(), [this](auto&) { pohCallback(); },
60 std::chrono::hours{1}, std::chrono::minutes{1})
Andrew Geissler58a18012018-01-19 19:36:05 -080061 {
62 subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060063
Potin Lai70f36d82022-03-15 10:25:39 +080064 createSystemdTargetTable();
65
Matt Spinler9eab9862018-07-11 14:13:52 -050066 restoreChassisStateChangeTime();
67
Andrew Geissler77a91832022-05-11 12:11:03 -040068 // No default in PDI so start at Good, skip D-Bus signal for now
69 currentPowerStatus(PowerStatus::Good, true);
Andrew Geissler58a18012018-01-19 19:36:05 -080070 determineInitialState();
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060071
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050072 restorePOHCounter(); // restore POHCounter from persisted file
73
Andrew Geissler58a18012018-01-19 19:36:05 -080074 // We deferred this until we could get our property correct
75 this->emit_object_added();
76 }
Andrew Geisslerdff50ed2016-12-13 20:39:04 -060077
Andrew Geissler58a18012018-01-19 19:36:05 -080078 /** @brief Set value of RequestedPowerTransition */
79 Transition requestedPowerTransition(Transition value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060080
Andrew Geissler58a18012018-01-19 19:36:05 -080081 /** @brief Set value of CurrentPowerState */
82 PowerState currentPowerState(PowerState value) override;
Andrew Geisslera90a31a2016-12-13 16:16:28 -060083
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050084 /** @brief Get value of POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -050085 using ChassisInherit::pohCounter;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -050086
87 /** @brief Increment POHCounter if Chassis Power state is ON */
88 void startPOHCounter();
89
Andrew Geissler58a18012018-01-19 19:36:05 -080090 private:
Potin Lai70f36d82022-03-15 10:25:39 +080091 /** @brief Create systemd target instance names and mapping table */
92 void createSystemdTargetTable();
93
Andrew Geissler58a18012018-01-19 19:36:05 -080094 /** @brief Determine initial chassis state and set internally */
95 void determineInitialState();
Andrew Geissler0029a5d2017-01-24 14:48:35 -060096
Adriana Kobylak396ed8a2022-03-22 15:45:41 +000097 /** @brief Determine status of power into system by examining all the
98 * power-related interfaces of interest
99 */
Andrew Geissler8b1f8622022-01-28 16:37:07 -0600100 void determineStatusOfPower();
101
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000102 /** @brief Determine status of power provided by an Uninterruptible Power
103 * Supply into the system
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400104 *
105 * @return True if UPS power is good, false otherwise
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000106 */
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400107 bool determineStatusOfUPSPower();
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000108
109 /** @brief Determine status of power provided by the power supply units into
110 * the system
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400111 *
112 * @return True if PSU power is good, false otherwise
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000113 */
Andrew Geissler66aacdc2022-05-11 08:31:47 -0400114 bool determineStatusOfPSUPower();
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000115
Andrew Geissler58a18012018-01-19 19:36:05 -0800116 /**
117 * @brief subscribe to the systemd signals
118 *
119 * This object needs to capture when it's systemd targets complete
120 * so it can keep it's state updated
121 *
122 **/
123 void subscribeToSystemdSignals();
Andrew Geissler0029a5d2017-01-24 14:48:35 -0600124
Matthew Barthbe6efab2022-03-01 13:21:45 -0600125 /** @brief Start the systemd unit requested
Andrew Geissler58a18012018-01-19 19:36:05 -0800126 *
Matthew Barthbe6efab2022-03-01 13:21:45 -0600127 * This function calls `StartUnit` on the systemd unit given.
Andrew Geissler58a18012018-01-19 19:36:05 -0800128 *
Matthew Barthbe6efab2022-03-01 13:21:45 -0600129 * @param[in] sysdUnit - Systemd unit
Andrew Geissler58a18012018-01-19 19:36:05 -0800130 */
Matthew Barthbe6efab2022-03-01 13:21:45 -0600131 void startUnit(const std::string& sysdUnit);
Andrew Geisslerce80f242017-01-24 13:25:33 -0600132
Andrew Geissler77a91832022-05-11 12:11:03 -0400133 /** @brief Restart the systemd unit requested
134 *
135 * This function calls `RestartUnit` on the systemd unit given.
136 * This is useful when needing to restart a service that is already running
137 *
138 * @param[in] sysdUnit - Systemd unit to restart
139 */
140 void restartUnit(const std::string& sysdUnit);
141
Andrew Geissler58a18012018-01-19 19:36:05 -0800142 /**
143 * @brief Determine if target is active
144 *
145 * This function determines if the target is active and
146 * helps prevent misleading log recorded states.
147 *
148 * @param[in] target - Target string to check on
149 *
150 * @return boolean corresponding to state active
151 **/
152 bool stateActive(const std::string& target);
Josh D. King697474c2017-03-02 11:15:55 -0600153
Andrew Geissler58a18012018-01-19 19:36:05 -0800154 /** @brief Check if systemd state change is relevant to this object
155 *
156 * Instance specific interface to handle the detected systemd state
157 * change
158 *
159 * @param[in] msg - Data associated with subscribed signal
160 *
161 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500162 int sysStateChange(sdbusplus::message_t& msg);
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600163
Andrew Geissler58a18012018-01-19 19:36:05 -0800164 /** @brief Persistent sdbusplus DBus connection. */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500165 sdbusplus::bus_t& bus;
Andrew Geissler2ec3a7e2016-12-13 22:01:28 -0600166
Andrew Geissler58a18012018-01-19 19:36:05 -0800167 /** @brief Used to subscribe to dbus systemd signals **/
168 sdbusplus::bus::match_t systemdSignals;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500169
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000170 /** @brief Watch for any changes to UPS properties **/
Andrew Geissler2cf2a262022-02-02 14:38:41 -0600171 std::unique_ptr<sdbusplus::bus::match_t> uPowerPropChangeSignal;
172
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000173 /** @brief Watch for any changes to PowerSystemInputs properties **/
174 std::unique_ptr<sdbusplus::bus::match_t> powerSysInputsPropChangeSignal;
175
Potin Lai70f36d82022-03-15 10:25:39 +0800176 /** @brief Chassis id. **/
177 const size_t id = 0;
178
179 /** @brief Transition state to systemd target mapping table. **/
180 std::map<Transition, std::string> systemdTargetTable;
181
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500182 /** @brief Used to Set value of POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500183 uint32_t pohCounter(uint32_t value) override;
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500184
William A. Kennington IIId998f822018-10-17 23:17:57 -0700185 /** @brief Used by the timer to update the POHCounter */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500186 void pohCallback();
William A. Kennington IIId998f822018-10-17 23:17:57 -0700187
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500188 /** @brief Used to restore POHCounter value from persisted file */
189 void restorePOHCounter();
190
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500191 /** @brief Serialize and persist requested POH counter.
192 *
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500193 * @return fs::path - pathname of persisted requested POH counter.
194 */
Allen.Wangba182f02022-03-23 19:01:53 +0800195 fs::path serializePOH();
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500196
Matt Spinler81957842018-07-11 10:37:12 -0500197 /** @brief Deserialize a persisted requested POH counter.
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500198 *
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500199 * @param[in] retCounter - deserialized POH counter value
200 *
201 * @return bool - true if the deserialization was successful, false
202 * otherwise.
203 */
Allen.Wangba182f02022-03-23 19:01:53 +0800204 bool deserializePOH(uint32_t& retCounter);
Nagaraju Goruganticb781fe2018-04-06 13:41:01 -0500205
Matt Spinler9eab9862018-07-11 14:13:52 -0500206 /** @brief Sets the LastStateChangeTime property and persists it. */
207 void setStateChangeTime();
208
209 /** @brief Serialize the last power state change time.
210 *
211 * Save the time the state changed and the state itself.
212 * The state needs to be saved as well so that during rediscovery
213 * on reboots there's a way to know not to update the time again.
214 */
215 void serializeStateChangeTime();
216
217 /** @brief Deserialize the last power state change time.
218 *
219 * @param[out] time - Deserialized time
220 * @param[out] state - Deserialized power state
221 *
222 * @return bool - true if successful, false otherwise.
223 */
224 bool deserializeStateChangeTime(uint64_t& time, PowerState& state);
225
226 /** @brief Restores the power state change time.
227 *
228 * The time is loaded into the LastStateChangeTime D-Bus property.
229 * On the very first start after this code has been applied but
230 * before the state has changed, the LastStateChangeTime value
231 * will be zero.
232 */
233 void restoreChassisStateChangeTime();
234
William A. Kennington IIId998f822018-10-17 23:17:57 -0700235 /** @brief Timer used for tracking power on hours */
Patrick Williams45a1ed72021-04-30 21:02:43 -0500236 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pohTimer;
Ben Tyner2c36e5a2021-07-12 14:56:49 -0500237
238 /** @brief Function to check for a standby voltage regulator fault
239 *
240 * Determine if a standby voltage regulator fault was detected and
241 * return true or false accordingly.
242 *
243 * @return true if fault detected, else false
244 */
245 bool standbyVoltageRegulatorFault();
Andrew Geissler2cf2a262022-02-02 14:38:41 -0600246
247 /** @brief Process UPS property changes
248 *
249 * Instance specific interface to monitor for changes to the UPS
250 * properties which may impact CurrentPowerStatus
251 *
252 * @param[in] msg - Data associated with subscribed signal
253 *
254 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500255 void uPowerChangeEvent(sdbusplus::message_t& msg);
Adriana Kobylak396ed8a2022-03-22 15:45:41 +0000256
257 /** @brief Process PowerSystemInputs property changes
258 *
259 * Instance specific interface to monitor for changes to the
260 * PowerSystemInputs properties which may impact CurrentPowerStatus
261 *
262 * @param[in] msg - Data associated with subscribed signal
263 *
264 */
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500265 void powerSysInputsChangeEvent(sdbusplus::message_t& msg);
Andrew Geisslera90a31a2016-12-13 16:16:28 -0600266};
267
268} // namespace manager
269} // namespace state
270} // namespace phosphor