blob: 6b5e97e5e1fc711b250ceb1fc6673b3359f7be9c [file] [log] [blame]
Andrew Geissler36529022016-11-29 15:23:54 -06001#pragma once
2
Michael Tritz206a8332017-02-06 16:01:23 -06003#include <string>
Patrick Williamsd22706f2017-05-04 05:42:49 -05004#include <functional>
Andrew Geissler033fc3b2017-08-30 15:11:44 -05005#include <experimental/filesystem>
6#include <cereal/access.hpp>
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +05307#include <cereal/cereal.hpp>
Andrew Geissler36529022016-11-29 15:23:54 -06008#include <sdbusplus/bus.hpp>
Andrew Geissler7b90a622017-08-08 11:41:08 -05009#include <phosphor-logging/log.hpp>
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050010#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
11#include <xyz/openbmc_project/Control/Boot/RebootAttempts/server.hpp>
12#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
Andrew Geissler36529022016-11-29 15:23:54 -060013#include "xyz/openbmc_project/State/Host/server.hpp"
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -050014#include "settings.hpp"
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050015#include "config.h"
Andrew Geissler36529022016-11-29 15:23:54 -060016
17namespace phosphor
18{
19namespace state
20{
21namespace manager
22{
23
Patrick Williamsd22706f2017-05-04 05:42:49 -050024using HostInherit = sdbusplus::server::object::object<
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050025 sdbusplus::xyz::openbmc_project::State::server::Host,
26 sdbusplus::xyz::openbmc_project::State::Boot::server::Progress,
27 sdbusplus::xyz::openbmc_project::Control::Boot::server::RebootAttempts,
28 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::Status>;
29
Andrew Geissler7b90a622017-08-08 11:41:08 -050030using namespace phosphor::logging;
31
Patrick Williamsd22706f2017-05-04 05:42:49 -050032namespace sdbusRule = sdbusplus::bus::match::rules;
Andrew Geissler033fc3b2017-08-30 15:11:44 -050033namespace fs = std::experimental::filesystem;
Patrick Williamsd22706f2017-05-04 05:42:49 -050034
Andrew Geissler36529022016-11-29 15:23:54 -060035/** @class Host
36 * @brief OpenBMC host state management implementation.
37 * @details A concrete implementation for xyz.openbmc_project.State.Host
38 * DBus API.
39 */
Patrick Williamsd22706f2017-05-04 05:42:49 -050040class Host : public HostInherit
Andrew Geissler36529022016-11-29 15:23:54 -060041{
42 public:
43 /** @brief Constructs Host State Manager
44 *
Andrew Geissleref3c1842016-12-01 12:33:09 -060045 * @note This constructor passes 'true' to the base class in order to
46 * defer dbus object registration until we can run
47 * determineInitialState() and set our properties
48 *
Andrew Geissler36529022016-11-29 15:23:54 -060049 * @param[in] bus - The Dbus bus object
50 * @param[in] busName - The Dbus name to own
51 * @param[in] objPath - The Dbus object path
52 */
53 Host(sdbusplus::bus::bus& bus,
Patrick Williamsd22706f2017-05-04 05:42:49 -050054 const char* busName,
55 const char* objPath) :
56 HostInherit(bus, objPath, true),
Andrew Geissleref621162016-12-08 12:56:21 -060057 bus(bus),
Patrick Williamsd22706f2017-05-04 05:42:49 -050058 systemdSignals(
59 bus,
60 sdbusRule::type::signal() +
61 sdbusRule::member("JobRemoved") +
62 sdbusRule::path("/org/freedesktop/systemd1") +
63 sdbusRule::interface(
64 "org.freedesktop.systemd1.Manager"),
65 std::bind(std::mem_fn(&Host::sysStateChange),
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -050066 this, std::placeholders::_1)),
67 settings(bus)
Andrew Geissleref3c1842016-12-01 12:33:09 -060068 {
Andrew Geissler4da7e002017-01-24 15:21:40 -060069 // Enable systemd signals
70 subscribeToSystemdSignals();
71
Andrew Geissleref3c1842016-12-01 12:33:09 -060072 // Will throw exception on fail
73 determineInitialState();
74
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050075 attemptsLeft(BOOT_COUNT_MAX_ALLOWED);
76
Andrew Geissleref3c1842016-12-01 12:33:09 -060077 // We deferred this until we could get our property correct
78 this->emit_object_added();
79 }
80
Andrew Geissleref3c1842016-12-01 12:33:09 -060081 /** @brief Set value of HostTransition */
82 Transition requestedHostTransition(Transition value) override;
83
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -050084 /** @brief Set Value for boot progress */
85 ProgressStages bootProgress(ProgressStages value) override;
86
87 /** @brief Set Value for Operating System Status */
88 OSStatus operatingSystemState(OSStatus value) override;
89
Andrew Geissleref3c1842016-12-01 12:33:09 -060090 /** @brief Set value of CurrentHostState */
91 HostState currentHostState(HostState value) override;
Andrew Geissler36529022016-11-29 15:23:54 -060092
Andrew Geissler7b90a622017-08-08 11:41:08 -050093 /**
94 * @brief Set host reboot count to default
95 *
96 * OpenBMC software controls the number of allowed reboot attempts so
97 * any external set request of this property will be overridden by
98 * this function and set to the default.
99 *
100 * The only code responsible for decrementing the boot count resides
101 * within this process and that will use the sub class interface
102 * directly
103 *
104 * @param[in] value - Reboot count value, will be ignored
105 *
106 * @return Default number of reboot attempts left
107 */
108 uint32_t attemptsLeft(uint32_t value) override
109 {
110 log<level::DEBUG>("External request to reset reboot count");
111 return (sdbusplus::xyz::openbmc_project::Control::Boot::server::
112 RebootAttempts::attemptsLeft(BOOT_COUNT_MAX_ALLOWED));
113 }
114
Andrew Geissler36529022016-11-29 15:23:54 -0600115 private:
Andrew Geissler4da7e002017-01-24 15:21:40 -0600116 /**
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();
124
125 /**
126 * @brief Determine initial host state and set internally
127 *
128 * @return Will throw exceptions on failure
129 **/
130 void determineInitialState();
131
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600132 /** @brief Execute the transition request
133 *
134 * This function assumes the state has been validated and the host
135 * is in an appropriate state for the transition to be started.
136 *
137 * @param[in] tranReq - Transition requested
138 */
139 void executeTransition(Transition tranReq);
140
Michael Tritz206a8332017-02-06 16:01:23 -0600141 /**
Josh D. King929ef702017-03-02 10:58:11 -0600142 * @brief Determine if target is active
143 *
144 * This function determines if the target is active and
145 * helps prevent misleading log recorded states.
146 *
147 * @param[in] target - Target string to check on
148 *
149 * @return boolean corresponding to state active
150 **/
151 bool stateActive(const std::string& target);
152
153 /**
Michael Tritz206a8332017-02-06 16:01:23 -0600154 * @brief Determine if auto reboot flag is set
155 *
156 * @return boolean corresponding to current auto_reboot setting
157 **/
158 bool isAutoReboot();
159
Andrew Geissler4da7e002017-01-24 15:21:40 -0600160 /** @brief Check if systemd state change is relevant to this object
161 *
162 * Instance specific interface to handle the detected systemd state
163 * change
164 *
165 * @param[in] msg - Data associated with subscribed signal
Andrew Geissler4da7e002017-01-24 15:21:40 -0600166 *
167 */
Patrick Williamsd22706f2017-05-04 05:42:49 -0500168 void sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler4da7e002017-01-24 15:21:40 -0600169
Andrew Geissler7b90a622017-08-08 11:41:08 -0500170 /** @brief Decrement reboot count
171 *
172 * This is used internally to this application to decrement the boot
173 * count on each boot attempt. The host will use the external
174 * attemptsLeft() interface to reset the count when a boot is successful
175 *
176 * @return number of reboot count attempts left
177 */
178 uint32_t decrementRebootCount();
179
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500180 // Allow cereal class access to allow these next two function to be
181 // private
182 friend class cereal::access;
183
184 /** @brief Function required by Cereal to perform serialization.
185 *
186 * @tparam Archive - Cereal archive type (binary in our case).
187 * @param[in] archive - reference to Cereal archive.
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +0530188 * @param[in] version - Class version that enables handling
189 * a serialized data across code levels
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500190 */
191 template<class Archive>
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +0530192 void save(Archive& archive, const std::uint32_t version) const
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500193 {
194 archive(convertForMessage(sdbusplus::xyz::openbmc_project::
195 State::server::Host::
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500196 requestedHostTransition()),
197 convertForMessage(sdbusplus::xyz::openbmc_project::
198 State::Boot::server::Progress::
199 bootProgress()),
200 convertForMessage(sdbusplus::xyz::openbmc_project::
201 State::OperatingSystem::server::Status::
202 operatingSystemState()));
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500203 }
204
205 /** @brief Function required by Cereal to perform deserialization.
206 *
207 * @tparam Archive - Cereal archive type (binary in our case).
208 * @param[in] archive - reference to Cereal archive.
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +0530209 * @param[in] version - Class version that enables handling
210 * a serialized data across code levels
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500211 */
212 template<class Archive>
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +0530213 void load(Archive& archive, const std::uint32_t version)
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500214 {
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500215 std::string reqTranState;
216 std::string bootProgress;
217 std::string osState;
218 archive(reqTranState, bootProgress, osState);
219 auto reqTran = Host::convertTransitionFromString(reqTranState);
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500220 // When restoring, set the requested state with persistent value
221 // but don't call the override which would execute it
222 sdbusplus::xyz::openbmc_project::State::server::Host::
223 requestedHostTransition(reqTran);
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500224 sdbusplus::xyz::openbmc_project::State::Boot::server::Progress::
225 bootProgress(
226 Host::convertProgressStagesFromString(bootProgress));
227 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::
228 Status::operatingSystemState(
229 Host::convertOSStatusFromString(osState));
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500230 }
231
232 /** @brief Serialize and persist requested host state
233 *
234 * @param[in] dir - pathname of file where the serialized host state will
235 * be placed.
236 *
237 * @return fs::path - pathname of persisted requested host state.
238 */
239 fs::path serialize(const fs::path& dir =
240 fs::path(HOST_STATE_PERSIST_PATH));
241
242 /** @brief Deserialze a persisted requested host state.
243 *
244 * @param[in] path - pathname of persisted host state file
245 *
246 * @return bool - true if the deserialization was successful, false
247 * otherwise.
248 */
249 bool deserialize(const fs::path& path);
250
Andrew Geissleref3c1842016-12-01 12:33:09 -0600251 /** @brief Persistent sdbusplus DBus bus connection. */
252 sdbusplus::bus::bus& bus;
Andrew Geissleref621162016-12-08 12:56:21 -0600253
Andrew Geissler4da7e002017-01-24 15:21:40 -0600254 /** @brief Used to subscribe to dbus systemd signals **/
Patrick Williamsd22706f2017-05-04 05:42:49 -0500255 sdbusplus::bus::match_t systemdSignals;
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -0500256
257 // Settings objects of interest
258 settings::Objects settings;
Andrew Geissler36529022016-11-29 15:23:54 -0600259};
260
261} // namespace manager
262} // namespace state
263} // namespace phosphor