blob: 35a4bdd687f9b3debb2b4b53711b64d905dd7c6e [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>
Andrew Geissler36529022016-11-29 15:23:54 -06007#include <sdbusplus/bus.hpp>
Andrew Geissler7b90a622017-08-08 11:41:08 -05008#include <phosphor-logging/log.hpp>
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -05009#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
10#include <xyz/openbmc_project/Control/Boot/RebootAttempts/server.hpp>
11#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
Andrew Geissler36529022016-11-29 15:23:54 -060012#include "xyz/openbmc_project/State/Host/server.hpp"
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -050013#include "settings.hpp"
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050014#include "config.h"
Andrew Geissler36529022016-11-29 15:23:54 -060015
16namespace phosphor
17{
18namespace state
19{
20namespace manager
21{
22
Patrick Williamsd22706f2017-05-04 05:42:49 -050023using HostInherit = sdbusplus::server::object::object<
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050024 sdbusplus::xyz::openbmc_project::State::server::Host,
25 sdbusplus::xyz::openbmc_project::State::Boot::server::Progress,
26 sdbusplus::xyz::openbmc_project::Control::Boot::server::RebootAttempts,
27 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::Status>;
28
Andrew Geissler7b90a622017-08-08 11:41:08 -050029using namespace phosphor::logging;
30
Patrick Williamsd22706f2017-05-04 05:42:49 -050031namespace sdbusRule = sdbusplus::bus::match::rules;
Andrew Geissler033fc3b2017-08-30 15:11:44 -050032namespace fs = std::experimental::filesystem;
Patrick Williamsd22706f2017-05-04 05:42:49 -050033
Andrew Geissler36529022016-11-29 15:23:54 -060034/** @class Host
35 * @brief OpenBMC host state management implementation.
36 * @details A concrete implementation for xyz.openbmc_project.State.Host
37 * DBus API.
38 */
Patrick Williamsd22706f2017-05-04 05:42:49 -050039class Host : public HostInherit
Andrew Geissler36529022016-11-29 15:23:54 -060040{
41 public:
42 /** @brief Constructs Host State Manager
43 *
Andrew Geissleref3c1842016-12-01 12:33:09 -060044 * @note This constructor passes 'true' to the base class in order to
45 * defer dbus object registration until we can run
46 * determineInitialState() and set our properties
47 *
Andrew Geissler36529022016-11-29 15:23:54 -060048 * @param[in] bus - The Dbus bus object
49 * @param[in] busName - The Dbus name to own
50 * @param[in] objPath - The Dbus object path
51 */
52 Host(sdbusplus::bus::bus& bus,
Patrick Williamsd22706f2017-05-04 05:42:49 -050053 const char* busName,
54 const char* objPath) :
55 HostInherit(bus, objPath, true),
Andrew Geissleref621162016-12-08 12:56:21 -060056 bus(bus),
Patrick Williamsd22706f2017-05-04 05:42:49 -050057 systemdSignals(
58 bus,
59 sdbusRule::type::signal() +
60 sdbusRule::member("JobRemoved") +
61 sdbusRule::path("/org/freedesktop/systemd1") +
62 sdbusRule::interface(
63 "org.freedesktop.systemd1.Manager"),
64 std::bind(std::mem_fn(&Host::sysStateChange),
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -050065 this, std::placeholders::_1)),
66 settings(bus)
Andrew Geissleref3c1842016-12-01 12:33:09 -060067 {
Andrew Geissler4da7e002017-01-24 15:21:40 -060068 // Enable systemd signals
69 subscribeToSystemdSignals();
70
Andrew Geissleref3c1842016-12-01 12:33:09 -060071 // Will throw exception on fail
72 determineInitialState();
73
Dhruvaraj Subhashchandran2710e732017-06-19 06:43:22 -050074 attemptsLeft(BOOT_COUNT_MAX_ALLOWED);
75
Andrew Geissleref3c1842016-12-01 12:33:09 -060076 // We deferred this until we could get our property correct
77 this->emit_object_added();
78 }
79
Andrew Geissleref3c1842016-12-01 12:33:09 -060080 /** @brief Set value of HostTransition */
81 Transition requestedHostTransition(Transition value) override;
82
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -050083 /** @brief Set Value for boot progress */
84 ProgressStages bootProgress(ProgressStages value) override;
85
86 /** @brief Set Value for Operating System Status */
87 OSStatus operatingSystemState(OSStatus value) override;
88
Andrew Geissleref3c1842016-12-01 12:33:09 -060089 /** @brief Set value of CurrentHostState */
90 HostState currentHostState(HostState value) override;
Andrew Geissler36529022016-11-29 15:23:54 -060091
Andrew Geissler7b90a622017-08-08 11:41:08 -050092 /**
93 * @brief Set host reboot count to default
94 *
95 * OpenBMC software controls the number of allowed reboot attempts so
96 * any external set request of this property will be overridden by
97 * this function and set to the default.
98 *
99 * The only code responsible for decrementing the boot count resides
100 * within this process and that will use the sub class interface
101 * directly
102 *
103 * @param[in] value - Reboot count value, will be ignored
104 *
105 * @return Default number of reboot attempts left
106 */
107 uint32_t attemptsLeft(uint32_t value) override
108 {
109 log<level::DEBUG>("External request to reset reboot count");
110 return (sdbusplus::xyz::openbmc_project::Control::Boot::server::
111 RebootAttempts::attemptsLeft(BOOT_COUNT_MAX_ALLOWED));
112 }
113
Andrew Geissler36529022016-11-29 15:23:54 -0600114 private:
Andrew Geissler4da7e002017-01-24 15:21:40 -0600115 /**
116 * @brief subscribe to the systemd signals
117 *
118 * This object needs to capture when it's systemd targets complete
119 * so it can keep it's state updated
120 *
121 **/
122 void subscribeToSystemdSignals();
123
124 /**
125 * @brief Determine initial host state and set internally
126 *
127 * @return Will throw exceptions on failure
128 **/
129 void determineInitialState();
130
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600131 /** @brief Execute the transition request
132 *
133 * This function assumes the state has been validated and the host
134 * is in an appropriate state for the transition to be started.
135 *
136 * @param[in] tranReq - Transition requested
137 */
138 void executeTransition(Transition tranReq);
139
Michael Tritz206a8332017-02-06 16:01:23 -0600140 /**
Josh D. King929ef702017-03-02 10:58:11 -0600141 * @brief Determine if target is active
142 *
143 * This function determines if the target is active and
144 * helps prevent misleading log recorded states.
145 *
146 * @param[in] target - Target string to check on
147 *
148 * @return boolean corresponding to state active
149 **/
150 bool stateActive(const std::string& target);
151
152 /**
Michael Tritz206a8332017-02-06 16:01:23 -0600153 * @brief Determine if auto reboot flag is set
154 *
155 * @return boolean corresponding to current auto_reboot setting
156 **/
157 bool isAutoReboot();
158
Andrew Geissler4da7e002017-01-24 15:21:40 -0600159 /** @brief Check if systemd state change is relevant to this object
160 *
161 * Instance specific interface to handle the detected systemd state
162 * change
163 *
164 * @param[in] msg - Data associated with subscribed signal
Andrew Geissler4da7e002017-01-24 15:21:40 -0600165 *
166 */
Patrick Williamsd22706f2017-05-04 05:42:49 -0500167 void sysStateChange(sdbusplus::message::message& msg);
Andrew Geissler4da7e002017-01-24 15:21:40 -0600168
Andrew Geissler7b90a622017-08-08 11:41:08 -0500169 /** @brief Decrement reboot count
170 *
171 * This is used internally to this application to decrement the boot
172 * count on each boot attempt. The host will use the external
173 * attemptsLeft() interface to reset the count when a boot is successful
174 *
175 * @return number of reboot count attempts left
176 */
177 uint32_t decrementRebootCount();
178
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500179 // Allow cereal class access to allow these next two function to be
180 // private
181 friend class cereal::access;
182
183 /** @brief Function required by Cereal to perform serialization.
184 *
185 * @tparam Archive - Cereal archive type (binary in our case).
186 * @param[in] archive - reference to Cereal archive.
187 */
188 template<class Archive>
189 void save(Archive& archive) const
190 {
191 archive(convertForMessage(sdbusplus::xyz::openbmc_project::
192 State::server::Host::
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500193 requestedHostTransition()),
194 convertForMessage(sdbusplus::xyz::openbmc_project::
195 State::Boot::server::Progress::
196 bootProgress()),
197 convertForMessage(sdbusplus::xyz::openbmc_project::
198 State::OperatingSystem::server::Status::
199 operatingSystemState()));
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500200 }
201
202 /** @brief Function required by Cereal to perform deserialization.
203 *
204 * @tparam Archive - Cereal archive type (binary in our case).
205 * @param[in] archive - reference to Cereal archive.
206 */
207 template<class Archive>
208 void load(Archive& archive)
209 {
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500210 std::string reqTranState;
211 std::string bootProgress;
212 std::string osState;
213 archive(reqTranState, bootProgress, osState);
214 auto reqTran = Host::convertTransitionFromString(reqTranState);
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500215 // When restoring, set the requested state with persistent value
216 // but don't call the override which would execute it
217 sdbusplus::xyz::openbmc_project::State::server::Host::
218 requestedHostTransition(reqTran);
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500219 sdbusplus::xyz::openbmc_project::State::Boot::server::Progress::
220 bootProgress(
221 Host::convertProgressStagesFromString(bootProgress));
222 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::
223 Status::operatingSystemState(
224 Host::convertOSStatusFromString(osState));
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500225 }
226
227 /** @brief Serialize and persist requested host state
228 *
229 * @param[in] dir - pathname of file where the serialized host state will
230 * be placed.
231 *
232 * @return fs::path - pathname of persisted requested host state.
233 */
234 fs::path serialize(const fs::path& dir =
235 fs::path(HOST_STATE_PERSIST_PATH));
236
237 /** @brief Deserialze a persisted requested host state.
238 *
239 * @param[in] path - pathname of persisted host state file
240 *
241 * @return bool - true if the deserialization was successful, false
242 * otherwise.
243 */
244 bool deserialize(const fs::path& path);
245
Andrew Geissleref3c1842016-12-01 12:33:09 -0600246 /** @brief Persistent sdbusplus DBus bus connection. */
247 sdbusplus::bus::bus& bus;
Andrew Geissleref621162016-12-08 12:56:21 -0600248
Andrew Geissler4da7e002017-01-24 15:21:40 -0600249 /** @brief Used to subscribe to dbus systemd signals **/
Patrick Williamsd22706f2017-05-04 05:42:49 -0500250 sdbusplus::bus::match_t systemdSignals;
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -0500251
252 // Settings objects of interest
253 settings::Objects settings;
Andrew Geissler36529022016-11-29 15:23:54 -0600254};
255
256} // namespace manager
257} // namespace state
258} // namespace phosphor