blob: 119c6ad81fe9ec5c37e7b01b11a3556c03018c3c [file] [log] [blame]
Andrew Geisslere426b582020-05-28 12:40:55 -05001#include "config.h"
2
3#include "host_state_manager.hpp"
4
Andrew Geissler0d1c3f12021-07-27 16:21:01 -04005#include "host_check.hpp"
Andrew Geissler1ab2b6c2022-03-10 16:16:15 -06006#include "utils.hpp"
Andrew Geissler0d1c3f12021-07-27 16:21:01 -04007
Andrew Geissler131d04a2021-03-12 11:02:41 -06008#include <stdio.h>
Andrew Geisslere426b582020-05-28 12:40:55 -05009#include <systemd/sd-bus.h>
10
11#include <cereal/archives/json.hpp>
12#include <cereal/cereal.hpp>
13#include <cereal/types/string.hpp>
14#include <cereal/types/tuple.hpp>
15#include <cereal/types/vector.hpp>
16#include <phosphor-logging/elog-errors.hpp>
Andrew Geissler8ffdb262021-09-20 15:25:19 -050017#include <phosphor-logging/lg2.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050018#include <sdbusplus/exception.hpp>
19#include <sdbusplus/server.hpp>
20#include <xyz/openbmc_project/Common/error.hpp>
21#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
22
Andrew Geissler131d04a2021-03-12 11:02:41 -060023#include <filesystem>
Andrew Geisslere426b582020-05-28 12:40:55 -050024#include <fstream>
Andrew Geissler36529022016-11-29 15:23:54 -060025#include <iostream>
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -060026#include <map>
27#include <string>
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -050028
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +053029// Register class version with Cereal
Andrew Geissler769a62f2019-12-06 13:36:08 -060030CEREAL_CLASS_VERSION(phosphor::state::manager::Host, CLASS_VERSION)
Andrew Geissler36529022016-11-29 15:23:54 -060031
32namespace phosphor
33{
34namespace state
35{
36namespace manager
37{
38
Andrew Geissler8ffdb262021-09-20 15:25:19 -050039PHOSPHOR_LOG2_USING;
40
Andrew Geissler7b90a622017-08-08 11:41:08 -050041// When you see server:: or reboot:: you know we're referencing our base class
Andrew Geissler3e3b84b2016-12-02 15:46:17 -060042namespace server = sdbusplus::xyz::openbmc_project::State::server;
Andrew Geissler7b90a622017-08-08 11:41:08 -050043namespace reboot = sdbusplus::xyz::openbmc_project::Control::Boot::server;
Dhruvaraj Subhashchandrana3b8d7e2017-08-10 05:40:04 -050044namespace bootprogress = sdbusplus::xyz::openbmc_project::State::Boot::server;
45namespace osstatus =
46 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server;
Andrew Geissler1e3bf942016-12-13 15:32:22 -060047using namespace phosphor::logging;
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -050048namespace fs = std::experimental::filesystem;
Andrew Geissler2f60aae2019-09-12 13:25:21 -050049using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Andrew Geissler1e3bf942016-12-13 15:32:22 -060050
Andrew Geissler4f309e82017-05-24 15:18:01 -050051// host-shutdown notifies host of shutdown and that leads to host-stop being
52// called so initiate a host shutdown with the -shutdown target and consider the
53// host shut down when the -stop target is complete
54constexpr auto HOST_STATE_SOFT_POWEROFF_TGT = "obmc-host-shutdown@0.target";
Josh D. Kingca357922017-04-11 13:44:09 -050055constexpr auto HOST_STATE_POWEROFF_TGT = "obmc-host-stop@0.target";
56constexpr auto HOST_STATE_POWERON_TGT = "obmc-host-start@0.target";
Andrew Geissler969b2612018-03-29 10:16:51 -070057constexpr auto HOST_STATE_POWERON_MIN_TGT = "obmc-host-startmin@0.target";
Andrew Geisslera27a6e82017-07-27 16:44:43 -050058constexpr auto HOST_STATE_REBOOT_TGT = "obmc-host-reboot@0.target";
Andrew Geissler40dd6e72020-02-07 14:31:12 -060059constexpr auto HOST_STATE_WARM_REBOOT = "obmc-host-warm-reboot@0.target";
60constexpr auto HOST_STATE_FORCE_WARM_REBOOT =
61 "obmc-host-force-warm-reboot@0.target";
Andrew Geissler47b96122020-02-11 16:13:13 -060062constexpr auto HOST_STATE_DIAGNOSTIC_MODE =
63 "obmc-host-diagnostic-mode@0.target";
Andrew Geissler40dd6e72020-02-07 14:31:12 -060064
Josh D. Kingcc3fb5d2017-04-19 15:45:10 -050065constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-host-quiesce@0.target";
Andrew Geissler4da7e002017-01-24 15:21:40 -060066
Josh D. King929ef702017-03-02 10:58:11 -060067constexpr auto ACTIVE_STATE = "active";
68constexpr auto ACTIVATING_STATE = "activating";
69
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -060070/* Map a transition to it's systemd target */
Andrew Geissler58a18012018-01-19 19:36:05 -080071const std::map<server::Host::Transition, std::string> SYSTEMD_TARGET_TABLE = {
72 {server::Host::Transition::Off, HOST_STATE_SOFT_POWEROFF_TGT},
73 {server::Host::Transition::On, HOST_STATE_POWERON_TGT},
Andrew Geissler40dd6e72020-02-07 14:31:12 -060074 {server::Host::Transition::Reboot, HOST_STATE_REBOOT_TGT},
Andrew Geissler7fdad602020-06-22 13:46:16 -050075// Some systems do not support a warm reboot so just map the reboot
76// requests to our normal cold reboot in that case
77#if ENABLE_WARM_REBOOT
Andrew Geissler40dd6e72020-02-07 14:31:12 -060078 {server::Host::Transition::GracefulWarmReboot, HOST_STATE_WARM_REBOOT},
79 {server::Host::Transition::ForceWarmReboot, HOST_STATE_FORCE_WARM_REBOOT}};
Andrew Geissler7fdad602020-06-22 13:46:16 -050080#else
81 {server::Host::Transition::GracefulWarmReboot, HOST_STATE_REBOOT_TGT},
82 {server::Host::Transition::ForceWarmReboot, HOST_STATE_REBOOT_TGT}};
83#endif
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -060084
Andrew Geissler58a18012018-01-19 19:36:05 -080085constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
86constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -060087constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
88
Josh D. King929ef702017-03-02 10:58:11 -060089constexpr auto SYSTEMD_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
90constexpr auto SYSTEMD_INTERFACE_UNIT = "org.freedesktop.systemd1.Unit";
91
Andrew Geissler4da7e002017-01-24 15:21:40 -060092void Host::subscribeToSystemdSignals()
93{
Andrew Geissler58a18012018-01-19 19:36:05 -080094 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
95 SYSTEMD_INTERFACE, "Subscribe");
Andrew Geissler2f60aae2019-09-12 13:25:21 -050096 try
97 {
98 this->bus.call_noreply(method);
99 }
Patrick Williams0a675212021-09-02 09:49:43 -0500100 catch (const sdbusplus::exception::exception& e)
Andrew Geissler2f60aae2019-09-12 13:25:21 -0500101 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500102 error("Failed to subscribe to systemd signals: {ERROR}", "ERROR", e);
Andrew Geissler2f60aae2019-09-12 13:25:21 -0500103 elog<InternalFailure>();
104 }
Andrew Geissler4da7e002017-01-24 15:21:40 -0600105 return;
106}
107
Andrew Geissleref3c1842016-12-01 12:33:09 -0600108void Host::determineInitialState()
109{
Andrew Geissleref3c1842016-12-01 12:33:09 -0600110
Andrew Geissler0d1c3f12021-07-27 16:21:01 -0400111 if (stateActive(HOST_STATE_POWERON_MIN_TGT) || isHostRunning())
Andrew Geissleref3c1842016-12-01 12:33:09 -0600112 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500113 info("Initial Host State will be Running");
Andrew Geissler97924142017-01-24 16:10:18 -0600114 server::Host::currentHostState(HostState::Running);
115 server::Host::requestedHostTransition(Transition::On);
Andrew Geissleref3c1842016-12-01 12:33:09 -0600116 }
117 else
118 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500119 info("Initial Host State will be Off");
Andrew Geissler97924142017-01-24 16:10:18 -0600120 server::Host::currentHostState(HostState::Off);
121 server::Host::requestedHostTransition(Transition::Off);
Andrew Geissleref3c1842016-12-01 12:33:09 -0600122 }
123
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500124 if (!deserialize(HOST_STATE_PERSIST_PATH))
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -0500125 {
Andrew Geissler58a18012018-01-19 19:36:05 -0800126 // set to default value.
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -0500127 server::Host::requestedHostTransition(Transition::Off);
128 }
Andrew Geissleref3c1842016-12-01 12:33:09 -0600129
130 return;
131}
132
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600133void Host::executeTransition(Transition tranReq)
134{
135 auto sysdUnit = SYSTEMD_TARGET_TABLE.find(tranReq)->second;
136
Andrew Geissler58a18012018-01-19 19:36:05 -0800137 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
138 SYSTEMD_INTERFACE, "StartUnit");
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600139
140 method.append(sysdUnit);
141 method.append("replace");
142
Andrew Geissler4da7e002017-01-24 15:21:40 -0600143 this->bus.call_noreply(method);
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600144
145 return;
146}
147
Josh D. King929ef702017-03-02 10:58:11 -0600148bool Host::stateActive(const std::string& target)
149{
Patrick Williams2975e262020-05-13 18:01:09 -0500150 std::variant<std::string> currentState;
Josh D. King929ef702017-03-02 10:58:11 -0600151 sdbusplus::message::object_path unitTargetPath;
152
Andrew Geissler58a18012018-01-19 19:36:05 -0800153 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
154 SYSTEMD_INTERFACE, "GetUnit");
Josh D. King929ef702017-03-02 10:58:11 -0600155
156 method.append(target);
Josh D. King929ef702017-03-02 10:58:11 -0600157
Anthony Wilson32c532e2018-10-25 21:56:07 -0500158 try
Josh D. King929ef702017-03-02 10:58:11 -0600159 {
Anthony Wilson32c532e2018-10-25 21:56:07 -0500160 auto result = this->bus.call(method);
161 result.read(unitTargetPath);
162 }
Patrick Williams0a675212021-09-02 09:49:43 -0500163 catch (const sdbusplus::exception::exception& e)
Anthony Wilson32c532e2018-10-25 21:56:07 -0500164 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500165 error("Error in GetUnit call: {ERROR}", "ERROR", e);
Josh D. King929ef702017-03-02 10:58:11 -0600166 return false;
167 }
168
Andrew Geissler58a18012018-01-19 19:36:05 -0800169 method = this->bus.new_method_call(
170 SYSTEMD_SERVICE,
171 static_cast<const std::string&>(unitTargetPath).c_str(),
172 SYSTEMD_PROPERTY_IFACE, "Get");
Josh D. King929ef702017-03-02 10:58:11 -0600173
174 method.append(SYSTEMD_INTERFACE_UNIT, "ActiveState");
Josh D. King929ef702017-03-02 10:58:11 -0600175
Anthony Wilson32c532e2018-10-25 21:56:07 -0500176 try
Josh D. King929ef702017-03-02 10:58:11 -0600177 {
Anthony Wilson32c532e2018-10-25 21:56:07 -0500178 auto result = this->bus.call(method);
179 result.read(currentState);
180 }
Patrick Williams0a675212021-09-02 09:49:43 -0500181 catch (const sdbusplus::exception::exception& e)
Anthony Wilson32c532e2018-10-25 21:56:07 -0500182 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500183 error("Error in ActiveState Get: {ERROR}", "ERROR", e);
Josh D. King929ef702017-03-02 10:58:11 -0600184 return false;
185 }
186
Patrick Williams37413dc2020-05-13 11:29:54 -0500187 const auto& currentStateStr = std::get<std::string>(currentState);
William A. Kennington III7a0689a2018-11-12 17:19:33 -0800188 return currentStateStr == ACTIVE_STATE ||
189 currentStateStr == ACTIVATING_STATE;
Josh D. King929ef702017-03-02 10:58:11 -0600190}
191
Michael Tritz206a8332017-02-06 16:01:23 -0600192bool Host::isAutoReboot()
193{
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -0500194 using namespace settings;
Michael Tritz206a8332017-02-06 16:01:23 -0600195
Andrew Geissler7f620832020-10-23 08:25:52 -0500196 /* The logic here is to first check the one-time AutoReboot setting.
197 * If this property is true (the default) then look at the persistent
198 * user setting in the non one-time object, otherwise honor the one-time
199 * setting and do not auto reboot.
200 */
201 auto methodOneTime = bus.new_method_call(
Andrew Geissler58a18012018-01-19 19:36:05 -0800202 settings.service(settings.autoReboot, autoRebootIntf).c_str(),
Andrew Geissler7f620832020-10-23 08:25:52 -0500203 settings.autoRebootOneTime.c_str(), SYSTEMD_PROPERTY_IFACE, "Get");
204 methodOneTime.append(autoRebootIntf, "AutoReboot");
205
206 auto methodUserSetting = bus.new_method_call(
207 settings.service(settings.autoReboot, autoRebootIntf).c_str(),
208 settings.autoReboot.c_str(), SYSTEMD_PROPERTY_IFACE, "Get");
209 methodUserSetting.append(autoRebootIntf, "AutoReboot");
Michael Tritz206a8332017-02-06 16:01:23 -0600210
Anthony Wilson32c532e2018-10-25 21:56:07 -0500211 try
Michael Tritz206a8332017-02-06 16:01:23 -0600212 {
Andrew Geissler7f620832020-10-23 08:25:52 -0500213 auto reply = bus.call(methodOneTime);
Patrick Williams2975e262020-05-13 18:01:09 -0500214 std::variant<bool> result;
Anthony Wilson32c532e2018-10-25 21:56:07 -0500215 reply.read(result);
Patrick Williams37413dc2020-05-13 11:29:54 -0500216 auto autoReboot = std::get<bool>(result);
Andrew Geissler7f620832020-10-23 08:25:52 -0500217
218 if (!autoReboot)
219 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500220 info("Auto reboot (one-time) disabled");
Andrew Geissler7f620832020-10-23 08:25:52 -0500221 return false;
222 }
223 else
224 {
225 // one-time is true so read the user setting
226 reply = bus.call(methodUserSetting);
227 reply.read(result);
228 autoReboot = std::get<bool>(result);
229 }
230
Anthony Wilson32c532e2018-10-25 21:56:07 -0500231 auto rebootCounterParam = reboot::RebootAttempts::attemptsLeft();
232
233 if (autoReboot)
Saqib Khancbe08d12017-03-10 01:29:20 -0600234 {
Anthony Wilson32c532e2018-10-25 21:56:07 -0500235 if (rebootCounterParam > 0)
236 {
237 // Reduce BOOTCOUNT by 1
Andrew Geisslerad65b2d2021-09-21 12:53:29 -0500238 info(
239 "Auto reboot enabled and boot count at {BOOTCOUNT}, rebooting",
240 "BOOTCOUNT", rebootCounterParam);
Anthony Wilson32c532e2018-10-25 21:56:07 -0500241 return true;
242 }
Anthony Wilson32c532e2018-10-25 21:56:07 -0500243 else
244 {
Andrew Geissler43284792021-09-23 10:32:15 -0500245 // We are at 0 so reset reboot counter and go to quiesce state
246 info("Auto reboot enabled but HOST BOOTCOUNT already set to 0");
247 attemptsLeft(BOOT_COUNT_MAX_ALLOWED);
Andrew Geissler1ab2b6c2022-03-10 16:16:15 -0600248
249 // Generate log since we will now be sitting in Quiesce
250 const std::string errorMsg =
251 "xyz.openbmc_project.State.Error.HostQuiesce";
252 utils::createError(this->bus, errorMsg,
253 sdbusplus::xyz::openbmc_project::Logging::
254 server::Entry::Level::Critical);
Anthony Wilson32c532e2018-10-25 21:56:07 -0500255 return false;
256 }
Saqib Khand5ac6352017-04-04 09:53:59 -0500257 }
258 else
259 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500260 info("Auto reboot disabled.");
Saqib Khancbe08d12017-03-10 01:29:20 -0600261 return false;
262 }
Michael Tritz206a8332017-02-06 16:01:23 -0600263 }
Patrick Williams0a675212021-09-02 09:49:43 -0500264 catch (const sdbusplus::exception::exception& e)
Saqib Khand5ac6352017-04-04 09:53:59 -0500265 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500266 error("Error in AutoReboot Get, {ERROR}", "ERROR", e);
Saqib Khand5ac6352017-04-04 09:53:59 -0500267 return false;
268 }
Michael Tritz206a8332017-02-06 16:01:23 -0600269}
270
Andrew Geisslere4039a82020-02-11 15:51:59 -0600271void Host::sysStateChangeJobRemoved(sdbusplus::message::message& msg)
Andrew Geissler4da7e002017-01-24 15:21:40 -0600272{
Andrew Geissler58a18012018-01-19 19:36:05 -0800273 uint32_t newStateID{};
Andrew Geissler4da7e002017-01-24 15:21:40 -0600274 sdbusplus::message::object_path newStateObjPath;
275 std::string newStateUnit{};
276 std::string newStateResult{};
277
Andrew Geissler58a18012018-01-19 19:36:05 -0800278 // Read the msg and populate each variable
Patrick Williamsd22706f2017-05-04 05:42:49 -0500279 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
Andrew Geissler4da7e002017-01-24 15:21:40 -0600280
Andrew Geissler58a18012018-01-19 19:36:05 -0800281 if ((newStateUnit == HOST_STATE_POWEROFF_TGT) &&
Andrew Geissler969b2612018-03-29 10:16:51 -0700282 (newStateResult == "done") &&
283 (!stateActive(HOST_STATE_POWERON_MIN_TGT)))
Andrew Geissleref621162016-12-08 12:56:21 -0600284 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500285 info("Received signal that host is off");
Andrew Geissler4da7e002017-01-24 15:21:40 -0600286 this->currentHostState(server::Host::HostState::Off);
Dhruvaraj Subhashchandrana3b8d7e2017-08-10 05:40:04 -0500287 this->bootProgress(bootprogress::Progress::ProgressStages::Unspecified);
288 this->operatingSystemState(osstatus::Status::OSStatus::Inactive);
Andrew Geissleref621162016-12-08 12:56:21 -0600289 }
Andrew Geissler969b2612018-03-29 10:16:51 -0700290 else if ((newStateUnit == HOST_STATE_POWERON_MIN_TGT) &&
Andrew Geissler58a18012018-01-19 19:36:05 -0800291 (newStateResult == "done") &&
Andrew Geissler969b2612018-03-29 10:16:51 -0700292 (stateActive(HOST_STATE_POWERON_MIN_TGT)))
Andrew Geissler58a18012018-01-19 19:36:05 -0800293 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500294 info("Received signal that host is running");
Andrew Geissler58a18012018-01-19 19:36:05 -0800295 this->currentHostState(server::Host::HostState::Running);
Andrew Geissler131d04a2021-03-12 11:02:41 -0600296
297 // Remove temporary file which is utilized for scenarios where the
298 // BMC is rebooted while the host is still up.
299 // This file is used to indicate to host related systemd services
300 // that the host is already running and they should skip running.
301 // Once the host state is back to running we can clear this file.
302 auto size = std::snprintf(nullptr, 0, HOST_RUNNING_FILE, 0);
303 size++; // null
304 std::unique_ptr<char[]> hostFile(new char[size]);
305 std::snprintf(hostFile.get(), size, HOST_RUNNING_FILE, 0);
306 if (std::filesystem::exists(hostFile.get()))
307 {
308 std::filesystem::remove(hostFile.get());
309 }
Andrew Geissler58a18012018-01-19 19:36:05 -0800310 }
311 else if ((newStateUnit == HOST_STATE_QUIESCE_TGT) &&
Josh D. King29d025d2017-04-27 12:40:22 -0500312 (newStateResult == "done") &&
313 (stateActive(HOST_STATE_QUIESCE_TGT)))
Andrew Geissler58a18012018-01-19 19:36:05 -0800314 {
315 if (Host::isAutoReboot())
316 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500317 info("Beginning reboot...");
Andrew Geissler58a18012018-01-19 19:36:05 -0800318 Host::requestedHostTransition(server::Host::Transition::Reboot);
319 }
320 else
321 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500322 info("Maintaining quiesce");
Andrew Geissler58a18012018-01-19 19:36:05 -0800323 this->currentHostState(server::Host::HostState::Quiesced);
324 }
325 }
Andrew Geissleref621162016-12-08 12:56:21 -0600326}
327
Andrew Geissler47b96122020-02-11 16:13:13 -0600328void Host::sysStateChangeJobNew(sdbusplus::message::message& msg)
329{
330 uint32_t newStateID{};
331 sdbusplus::message::object_path newStateObjPath;
332 std::string newStateUnit{};
333
334 // Read the msg and populate each variable
335 msg.read(newStateID, newStateObjPath, newStateUnit);
336
337 if (newStateUnit == HOST_STATE_DIAGNOSTIC_MODE)
338 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500339 info("Received signal that host is in diagnostice mode");
Andrew Geissler47b96122020-02-11 16:13:13 -0600340 this->currentHostState(server::Host::HostState::DiagnosticMode);
341 }
342}
343
Andrew Geissler7b90a622017-08-08 11:41:08 -0500344uint32_t Host::decrementRebootCount()
345{
346 auto rebootCount = reboot::RebootAttempts::attemptsLeft();
Andrew Geissler58a18012018-01-19 19:36:05 -0800347 if (rebootCount > 0)
Andrew Geissler7b90a622017-08-08 11:41:08 -0500348 {
Andrew Geissler58a18012018-01-19 19:36:05 -0800349 return (reboot::RebootAttempts::attemptsLeft(rebootCount - 1));
Andrew Geissler7b90a622017-08-08 11:41:08 -0500350 }
351 return rebootCount;
352}
353
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500354fs::path Host::serialize(const fs::path& dir)
355{
356 std::ofstream os(dir.c_str(), std::ios::binary);
357 cereal::JSONOutputArchive oarchive(os);
358 oarchive(*this);
359 return dir;
360}
361
362bool Host::deserialize(const fs::path& path)
363{
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500364 try
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500365 {
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500366 if (fs::exists(path))
367 {
368 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
369 cereal::JSONInputArchive iarchive(is);
370 iarchive(*this);
371 return true;
372 }
373 return false;
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500374 }
Patrick Williams8583b3b2021-10-06 12:19:20 -0500375 catch (const cereal::Exception& e)
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500376 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500377 error("deserialize exception: {ERROR}", "ERROR", e);
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500378 fs::remove(path);
379 return false;
380 }
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500381}
382
Andrew Geissleref3c1842016-12-01 12:33:09 -0600383Host::Transition Host::requestedHostTransition(Transition value)
384{
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500385 info("Host state transition request of {REQ}", "REQ", value);
Andrew Geissler7b90a622017-08-08 11:41:08 -0500386 // If this is not a power off request then we need to
387 // decrement the reboot counter. This code should
388 // never prevent a power on, it should just decrement
389 // the count to 0. The quiesce handling is where the
390 // check of this count will occur
Andrew Geissler58a18012018-01-19 19:36:05 -0800391 if (value != server::Host::Transition::Off)
Andrew Geissler7b90a622017-08-08 11:41:08 -0500392 {
393 decrementRebootCount();
394 }
395
Andrew Geisslera27a6e82017-07-27 16:44:43 -0500396 executeTransition(value);
Andrew Geissler7b90a622017-08-08 11:41:08 -0500397
Andrew Geissler58a18012018-01-19 19:36:05 -0800398 auto retVal = server::Host::requestedHostTransition(value);
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500399 serialize();
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -0500400 return retVal;
Andrew Geissleref3c1842016-12-01 12:33:09 -0600401}
402
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500403Host::ProgressStages Host::bootProgress(ProgressStages value)
404{
405 auto retVal = bootprogress::Progress::bootProgress(value);
406 serialize();
407 return retVal;
408}
409
410Host::OSStatus Host::operatingSystemState(OSStatus value)
411{
412 auto retVal = osstatus::Status::operatingSystemState(value);
413 serialize();
414 return retVal;
415}
416
Andrew Geissleref3c1842016-12-01 12:33:09 -0600417Host::HostState Host::currentHostState(HostState value)
418{
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500419 info("Change to Host State: {STATE}", "STATE", value);
Andrew Geissleref621162016-12-08 12:56:21 -0600420 return server::Host::currentHostState(value);
Andrew Geissleref3c1842016-12-01 12:33:09 -0600421}
422
Andrew Geissler36529022016-11-29 15:23:54 -0600423} // namespace manager
424} // namespace state
Andrew Geisslera965cf02018-08-31 08:37:05 -0700425} // namespace phosphor