blob: af22ade2174cc0a496fbabe207d3b44c1e2ac98e [file] [log] [blame]
Andrew Geissler36529022016-11-29 15:23:54 -06001#pragma once
2
Andrew Geisslere426b582020-05-28 12:40:55 -05003#include "config.h"
4
5#include "settings.hpp"
6#include "xyz/openbmc_project/State/Host/server.hpp"
7
Andrew Geissler033fc3b2017-08-30 15:11:44 -05008#include <cereal/access.hpp>
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +05309#include <cereal/cereal.hpp>
Andrew Geissler7b90a622017-08-08 11:41:08 -050010#include <phosphor-logging/log.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050011#include <sdbusplus/bus.hpp>
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050012#include <xyz/openbmc_project/Control/Boot/RebootAttempts/server.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050013#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050014#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050015
16#include <experimental/filesystem>
17#include <functional>
18#include <string>
Andrew Geissler36529022016-11-29 15:23:54 -060019
20namespace phosphor
21{
22namespace state
23{
24namespace manager
25{
26
Patrick Williamsd22706f2017-05-04 05:42:49 -050027using HostInherit = sdbusplus::server::object::object<
Andrew Geissler58a18012018-01-19 19:36:05 -080028 sdbusplus::xyz::openbmc_project::State::server::Host,
29 sdbusplus::xyz::openbmc_project::State::Boot::server::Progress,
30 sdbusplus::xyz::openbmc_project::Control::Boot::server::RebootAttempts,
31 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::Status>;
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050032
Andrew Geissler7b90a622017-08-08 11:41:08 -050033using namespace phosphor::logging;
34
Patrick Williamsd22706f2017-05-04 05:42:49 -050035namespace sdbusRule = sdbusplus::bus::match::rules;
Andrew Geissler033fc3b2017-08-30 15:11:44 -050036namespace fs = std::experimental::filesystem;
Patrick Williamsd22706f2017-05-04 05:42:49 -050037
Andrew Geissler36529022016-11-29 15:23:54 -060038/** @class Host
39 * @brief OpenBMC host state management implementation.
40 * @details A concrete implementation for xyz.openbmc_project.State.Host
41 * DBus API.
42 */
Patrick Williamsd22706f2017-05-04 05:42:49 -050043class Host : public HostInherit
Andrew Geissler36529022016-11-29 15:23:54 -060044{
Andrew Geissler58a18012018-01-19 19:36:05 -080045 public:
46 /** @brief Constructs Host State Manager
47 *
48 * @note This constructor passes 'true' to the base class in order to
49 * defer dbus object registration until we can run
50 * determineInitialState() and set our properties
51 *
52 * @param[in] bus - The Dbus bus object
Andrew Geissler58a18012018-01-19 19:36:05 -080053 * @param[in] objPath - The Dbus object path
54 */
Andrew Geissler769a62f2019-12-06 13:36:08 -060055 Host(sdbusplus::bus::bus& bus, const char* objPath) :
Andrew Geissler58a18012018-01-19 19:36:05 -080056 HostInherit(bus, objPath, true), bus(bus),
Andrew Geisslere4039a82020-02-11 15:51:59 -060057 systemdSignalJobRemoved(
Andrew Geissler58a18012018-01-19 19:36:05 -080058 bus,
59 sdbusRule::type::signal() + sdbusRule::member("JobRemoved") +
60 sdbusRule::path("/org/freedesktop/systemd1") +
61 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
Andrew Geisslere4039a82020-02-11 15:51:59 -060062 std::bind(std::mem_fn(&Host::sysStateChangeJobRemoved), this,
Andrew Geissler58a18012018-01-19 19:36:05 -080063 std::placeholders::_1)),
Andrew Geissler47b96122020-02-11 16:13:13 -060064 systemdSignalJobNew(
65 bus,
66 sdbusRule::type::signal() + sdbusRule::member("JobNew") +
67 sdbusRule::path("/org/freedesktop/systemd1") +
68 sdbusRule::interface("org.freedesktop.systemd1.Manager"),
69 std::bind(std::mem_fn(&Host::sysStateChangeJobNew), this,
70 std::placeholders::_1)),
Andrew Geissler58a18012018-01-19 19:36:05 -080071 settings(bus)
72 {
73 // Enable systemd signals
74 subscribeToSystemdSignals();
Andrew Geissler4da7e002017-01-24 15:21:40 -060075
Andrew Geissler58a18012018-01-19 19:36:05 -080076 // Will throw exception on fail
77 determineInitialState();
Andrew Geissleref3c1842016-12-01 12:33:09 -060078
Andrew Geissler58a18012018-01-19 19:36:05 -080079 attemptsLeft(BOOT_COUNT_MAX_ALLOWED);
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050080
Andrew Geissler58a18012018-01-19 19:36:05 -080081 // We deferred this until we could get our property correct
82 this->emit_object_added();
83 }
Andrew Geissleref3c1842016-12-01 12:33:09 -060084
Andrew Geissler58a18012018-01-19 19:36:05 -080085 /** @brief Set value of HostTransition */
86 Transition requestedHostTransition(Transition value) override;
Andrew Geissleref3c1842016-12-01 12:33:09 -060087
Andrew Geissler58a18012018-01-19 19:36:05 -080088 /** @brief Set Value for boot progress */
89 ProgressStages bootProgress(ProgressStages value) override;
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -050090
Andrew Geissler58a18012018-01-19 19:36:05 -080091 /** @brief Set Value for Operating System Status */
92 OSStatus operatingSystemState(OSStatus value) override;
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -050093
Andrew Geissler58a18012018-01-19 19:36:05 -080094 /** @brief Set value of CurrentHostState */
95 HostState currentHostState(HostState value) override;
Andrew Geissler36529022016-11-29 15:23:54 -060096
Andrew Geissler58a18012018-01-19 19:36:05 -080097 /**
98 * @brief Set host reboot count to default
99 *
100 * OpenBMC software controls the number of allowed reboot attempts so
101 * any external set request of this property will be overridden by
102 * this function and set to the default.
103 *
104 * The only code responsible for decrementing the boot count resides
105 * within this process and that will use the sub class interface
106 * directly
107 *
108 * @param[in] value - Reboot count value, will be ignored
109 *
110 * @return Default number of reboot attempts left
111 */
112 uint32_t attemptsLeft(uint32_t value) override
113 {
Andrew Geissler769a62f2019-12-06 13:36:08 -0600114 // value is ignored in this implementation
115 (void)(value);
Andrew Geissler58a18012018-01-19 19:36:05 -0800116 log<level::DEBUG>("External request to reset reboot count");
117 return (sdbusplus::xyz::openbmc_project::Control::Boot::server::
Andrew Geissler7b90a622017-08-08 11:41:08 -0500118 RebootAttempts::attemptsLeft(BOOT_COUNT_MAX_ALLOWED));
Andrew Geissler58a18012018-01-19 19:36:05 -0800119 }
Andrew Geissler7b90a622017-08-08 11:41:08 -0500120
Andrew Geissler58a18012018-01-19 19:36:05 -0800121 private:
122 /**
123 * @brief subscribe to the systemd signals
124 *
125 * This object needs to capture when it's systemd targets complete
126 * so it can keep it's state updated
127 *
128 **/
129 void subscribeToSystemdSignals();
Andrew Geissler4da7e002017-01-24 15:21:40 -0600130
Andrew Geissler58a18012018-01-19 19:36:05 -0800131 /**
132 * @brief Determine initial host state and set internally
133 *
134 * @return Will throw exceptions on failure
135 **/
136 void determineInitialState();
Andrew Geissler4da7e002017-01-24 15:21:40 -0600137
Andrew Geissler58a18012018-01-19 19:36:05 -0800138 /** @brief Execute the transition request
139 *
140 * This function assumes the state has been validated and the host
141 * is in an appropriate state for the transition to be started.
142 *
143 * @param[in] tranReq - Transition requested
144 */
145 void executeTransition(Transition tranReq);
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600146
Andrew Geissler58a18012018-01-19 19:36:05 -0800147 /**
148 * @brief Determine if target is active
149 *
150 * This function determines if the target is active and
151 * helps prevent misleading log recorded states.
152 *
153 * @param[in] target - Target string to check on
154 *
155 * @return boolean corresponding to state active
156 **/
157 bool stateActive(const std::string& target);
Josh D. King929ef702017-03-02 10:58:11 -0600158
Andrew Geissler58a18012018-01-19 19:36:05 -0800159 /**
160 * @brief Determine if auto reboot flag is set
161 *
162 * @return boolean corresponding to current auto_reboot setting
163 **/
164 bool isAutoReboot();
Michael Tritz206a8332017-02-06 16:01:23 -0600165
Andrew Geissler58a18012018-01-19 19:36:05 -0800166 /** @brief Check if systemd state change is relevant to this object
167 *
168 * Instance specific interface to handle the detected systemd state
169 * change
170 *
171 * @param[in] msg - Data associated with subscribed signal
172 *
173 */
Andrew Geisslere4039a82020-02-11 15:51:59 -0600174 void sysStateChangeJobRemoved(sdbusplus::message::message& msg);
Andrew Geissler4da7e002017-01-24 15:21:40 -0600175
Andrew Geissler47b96122020-02-11 16:13:13 -0600176 /** @brief Check if JobNew systemd signal is relevant to this object
177 *
178 * In certain instances phosphor-state-manager needs to monitor for the
179 * entry into a systemd target. This function will be used for these cases.
180 *
181 * Instance specific interface to handle the detected systemd state
182 * change
183 *
184 * @param[in] msg - Data associated with subscribed signal
185 *
186 */
187 void sysStateChangeJobNew(sdbusplus::message::message& msg);
188
Andrew Geissler58a18012018-01-19 19:36:05 -0800189 /** @brief Decrement reboot count
190 *
191 * This is used internally to this application to decrement the boot
192 * count on each boot attempt. The host will use the external
193 * attemptsLeft() interface to reset the count when a boot is successful
194 *
195 * @return number of reboot count attempts left
196 */
197 uint32_t decrementRebootCount();
Andrew Geissler7b90a622017-08-08 11:41:08 -0500198
Andrew Geissler58a18012018-01-19 19:36:05 -0800199 // Allow cereal class access to allow these next two function to be
200 // private
201 friend class cereal::access;
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500202
Andrew Geissler58a18012018-01-19 19:36:05 -0800203 /** @brief Function required by Cereal to perform serialization.
204 *
205 * @tparam Archive - Cereal archive type (binary in our case).
206 * @param[in] archive - reference to Cereal archive.
207 * @param[in] version - Class version that enables handling
208 * a serialized data across code levels
209 */
210 template <class Archive>
211 void save(Archive& archive, const std::uint32_t version) const
212 {
Andrew Geissler769a62f2019-12-06 13:36:08 -0600213 // version is not used currently
214 (void)(version);
Andrew Geissler58a18012018-01-19 19:36:05 -0800215 archive(convertForMessage(sdbusplus::xyz::openbmc_project::State::
216 server::Host::requestedHostTransition()),
217 convertForMessage(sdbusplus::xyz::openbmc_project::State::Boot::
218 server::Progress::bootProgress()),
219 convertForMessage(
220 sdbusplus::xyz::openbmc_project::State::OperatingSystem::
221 server::Status::operatingSystemState()));
222 }
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500223
Andrew Geissler58a18012018-01-19 19:36:05 -0800224 /** @brief Function required by Cereal to perform deserialization.
225 *
226 * @tparam Archive - Cereal archive type (binary in our case).
227 * @param[in] archive - reference to Cereal archive.
228 * @param[in] version - Class version that enables handling
229 * a serialized data across code levels
230 */
231 template <class Archive>
232 void load(Archive& archive, const std::uint32_t version)
233 {
Andrew Geissler769a62f2019-12-06 13:36:08 -0600234 // version is not used currently
235 (void)(version);
Andrew Geissler58a18012018-01-19 19:36:05 -0800236 std::string reqTranState;
237 std::string bootProgress;
238 std::string osState;
239 archive(reqTranState, bootProgress, osState);
240 auto reqTran = Host::convertTransitionFromString(reqTranState);
241 // When restoring, set the requested state with persistent value
242 // but don't call the override which would execute it
243 sdbusplus::xyz::openbmc_project::State::server::Host::
244 requestedHostTransition(reqTran);
245 sdbusplus::xyz::openbmc_project::State::Boot::server::Progress::
246 bootProgress(Host::convertProgressStagesFromString(bootProgress));
247 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::
248 Status::operatingSystemState(
249 Host::convertOSStatusFromString(osState));
250 }
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500251
Andrew Geissler58a18012018-01-19 19:36:05 -0800252 /** @brief Serialize and persist requested host state
253 *
254 * @param[in] dir - pathname of file where the serialized host state will
255 * be placed.
256 *
257 * @return fs::path - pathname of persisted requested host state.
258 */
259 fs::path serialize(const fs::path& dir = fs::path(HOST_STATE_PERSIST_PATH));
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500260
Andrew Geissler58a18012018-01-19 19:36:05 -0800261 /** @brief Deserialze a persisted requested host state.
262 *
263 * @param[in] path - pathname of persisted host state file
264 *
265 * @return bool - true if the deserialization was successful, false
266 * otherwise.
267 */
268 bool deserialize(const fs::path& path);
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500269
Andrew Geissler58a18012018-01-19 19:36:05 -0800270 /** @brief Persistent sdbusplus DBus bus connection. */
271 sdbusplus::bus::bus& bus;
Andrew Geissleref621162016-12-08 12:56:21 -0600272
Andrew Geisslere4039a82020-02-11 15:51:59 -0600273 /** @brief Used to subscribe to dbus systemd JobRemoved signal **/
274 sdbusplus::bus::match_t systemdSignalJobRemoved;
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -0500275
Andrew Geissler47b96122020-02-11 16:13:13 -0600276 /** @brief Used to subscribe to dbus systemd JobNew signal **/
277 sdbusplus::bus::match_t systemdSignalJobNew;
278
Andrew Geissler58a18012018-01-19 19:36:05 -0800279 // Settings objects of interest
280 settings::Objects settings;
Andrew Geissler36529022016-11-29 15:23:54 -0600281};
282
283} // namespace manager
284} // namespace state
285} // namespace phosphor