blob: 398fca59eb7eed1499396f847c2a7f04b76f6192 [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
Allen.Wang79b45002022-02-10 17:59:20 +08008#include <fmt/format.h>
Andrew Geissler131d04a2021-03-12 11:02:41 -06009#include <stdio.h>
Andrew Geisslere426b582020-05-28 12:40:55 -050010#include <systemd/sd-bus.h>
11
12#include <cereal/archives/json.hpp>
13#include <cereal/cereal.hpp>
14#include <cereal/types/string.hpp>
15#include <cereal/types/tuple.hpp>
16#include <cereal/types/vector.hpp>
17#include <phosphor-logging/elog-errors.hpp>
Andrew Geissler8ffdb262021-09-20 15:25:19 -050018#include <phosphor-logging/lg2.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -050019#include <sdbusplus/exception.hpp>
20#include <sdbusplus/server.hpp>
21#include <xyz/openbmc_project/Common/error.hpp>
22#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
23
Andrew Geissler131d04a2021-03-12 11:02:41 -060024#include <filesystem>
Andrew Geisslere426b582020-05-28 12:40:55 -050025#include <fstream>
Andrew Geissler36529022016-11-29 15:23:54 -060026#include <iostream>
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -060027#include <map>
28#include <string>
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -050029
Vishwanatha Subbanna0a838732017-10-05 12:43:19 +053030// Register class version with Cereal
Andrew Geissler769a62f2019-12-06 13:36:08 -060031CEREAL_CLASS_VERSION(phosphor::state::manager::Host, CLASS_VERSION)
Andrew Geissler36529022016-11-29 15:23:54 -060032
33namespace phosphor
34{
35namespace state
36{
37namespace manager
38{
39
Andrew Geissler8ffdb262021-09-20 15:25:19 -050040PHOSPHOR_LOG2_USING;
41
Andrew Geissler7b90a622017-08-08 11:41:08 -050042// When you see server:: or reboot:: you know we're referencing our base class
Andrew Geissler3e3b84b2016-12-02 15:46:17 -060043namespace server = sdbusplus::xyz::openbmc_project::State::server;
Andrew Geissler7b90a622017-08-08 11:41:08 -050044namespace reboot = sdbusplus::xyz::openbmc_project::Control::Boot::server;
Dhruvaraj Subhashchandrana3b8d7e2017-08-10 05:40:04 -050045namespace bootprogress = sdbusplus::xyz::openbmc_project::State::Boot::server;
46namespace osstatus =
47 sdbusplus::xyz::openbmc_project::State::OperatingSystem::server;
Andrew Geissler1e3bf942016-12-13 15:32:22 -060048using namespace phosphor::logging;
Patrick Williams6ed41ea2022-04-05 15:50:21 -050049namespace fs = std::filesystem;
Andrew Geissler2f60aae2019-09-12 13:25:21 -050050using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Andrew Geissler1e3bf942016-12-13 15:32:22 -060051
Josh D. King929ef702017-03-02 10:58:11 -060052constexpr auto ACTIVE_STATE = "active";
53constexpr auto ACTIVATING_STATE = "activating";
54
Andrew Geissler58a18012018-01-19 19:36:05 -080055constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
56constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -060057constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
58
Josh D. King929ef702017-03-02 10:58:11 -060059constexpr auto SYSTEMD_PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
60constexpr auto SYSTEMD_INTERFACE_UNIT = "org.freedesktop.systemd1.Unit";
61
Andrew Geissleref3c1842016-12-01 12:33:09 -060062void Host::determineInitialState()
63{
Allen.Wang79b45002022-02-10 17:59:20 +080064 if (stateActive(getTarget(server::Host::HostState::Running)) ||
Potin Lai70f36d82022-03-15 10:25:39 +080065 isHostRunning(id))
Andrew Geissleref3c1842016-12-01 12:33:09 -060066 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -050067 info("Initial Host State will be Running");
Andrew Geissler97924142017-01-24 16:10:18 -060068 server::Host::currentHostState(HostState::Running);
69 server::Host::requestedHostTransition(Transition::On);
Andrew Geissleref3c1842016-12-01 12:33:09 -060070 }
71 else
72 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -050073 info("Initial Host State will be Off");
Andrew Geissler97924142017-01-24 16:10:18 -060074 server::Host::currentHostState(HostState::Off);
75 server::Host::requestedHostTransition(Transition::Off);
Andrew Geissleref3c1842016-12-01 12:33:09 -060076 }
77
Allen.Wangba182f02022-03-23 19:01:53 +080078 if (!deserialize())
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -050079 {
Andrew Geissler58a18012018-01-19 19:36:05 -080080 // set to default value.
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -050081 server::Host::requestedHostTransition(Transition::Off);
82 }
Andrew Geissleref3c1842016-12-01 12:33:09 -060083 return;
84}
85
Allen.Wang79b45002022-02-10 17:59:20 +080086void Host::createSystemdTargetMaps()
87{
88 stateTargetTable = {
89 {HostState::Off, fmt::format("obmc-host-stop@{}.target", id)},
90 {HostState::Running, fmt::format("obmc-host-startmin@{}.target", id)},
91 {HostState::Quiesced, fmt::format("obmc-host-quiesce@{}.target", id)},
92 {HostState::DiagnosticMode,
93 fmt::format("obmc-host-diagnostic-mode@{}.target", id)}};
94
95 transitionTargetTable = {
96 {Transition::Off, fmt::format("obmc-host-shutdown@{}.target", id)},
97 {Transition::On, fmt::format("obmc-host-start@{}.target", id)},
98 {Transition::Reboot, fmt::format("obmc-host-reboot@{}.target", id)},
99// Some systems do not support a warm reboot so just map the reboot
100// requests to our normal cold reboot in that case
101#if ENABLE_WARM_REBOOT
102 {Transition::GracefulWarmReboot,
103 fmt::format("obmc-host-warm-reboot@{}.target", id)},
104 {Transition::ForceWarmReboot,
105 fmt::format("obmc-host-force-warm-reboot@{}.target", id)}
106 };
107#else
108 {Transition::GracefulWarmReboot,
109 fmt::format("obmc-host-reboot@{}.target", id)},
110 {Transition::ForceWarmReboot,
111 fmt::format("obmc-host-reboot@{}.target", id)}
112 };
113#endif
Andrew Geissler128ea8e2022-06-22 12:28:15 -0400114 hostCrashTarget = fmt::format("obmc-host-crash@{}.target", id);
Allen.Wang79b45002022-02-10 17:59:20 +0800115}
116
117const std::string& Host::getTarget(HostState state)
118{
119 return stateTargetTable[state];
120};
121
122const std::string& Host::getTarget(Transition tranReq)
123{
124 return transitionTargetTable[tranReq];
125};
126
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600127void Host::executeTransition(Transition tranReq)
128{
Allen.Wang79b45002022-02-10 17:59:20 +0800129 auto& sysdUnit = getTarget(tranReq);
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600130
Andrew Geissler58a18012018-01-19 19:36:05 -0800131 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
132 SYSTEMD_INTERFACE, "StartUnit");
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600133
134 method.append(sysdUnit);
135 method.append("replace");
136
Andrew Geissler4da7e002017-01-24 15:21:40 -0600137 this->bus.call_noreply(method);
Andrew Geissler0cd2eaf2016-12-07 10:50:13 -0600138
139 return;
140}
141
Josh D. King929ef702017-03-02 10:58:11 -0600142bool Host::stateActive(const std::string& target)
143{
Patrick Williams2975e262020-05-13 18:01:09 -0500144 std::variant<std::string> currentState;
Josh D. King929ef702017-03-02 10:58:11 -0600145 sdbusplus::message::object_path unitTargetPath;
146
Andrew Geissler58a18012018-01-19 19:36:05 -0800147 auto method = this->bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
148 SYSTEMD_INTERFACE, "GetUnit");
Josh D. King929ef702017-03-02 10:58:11 -0600149
150 method.append(target);
Josh D. King929ef702017-03-02 10:58:11 -0600151
Anthony Wilson32c532e2018-10-25 21:56:07 -0500152 try
Josh D. King929ef702017-03-02 10:58:11 -0600153 {
Anthony Wilson32c532e2018-10-25 21:56:07 -0500154 auto result = this->bus.call(method);
155 result.read(unitTargetPath);
156 }
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500157 catch (const sdbusplus::exception_t& e)
Anthony Wilson32c532e2018-10-25 21:56:07 -0500158 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500159 error("Error in GetUnit call: {ERROR}", "ERROR", e);
Josh D. King929ef702017-03-02 10:58:11 -0600160 return false;
161 }
162
Andrew Geissler58a18012018-01-19 19:36:05 -0800163 method = this->bus.new_method_call(
164 SYSTEMD_SERVICE,
165 static_cast<const std::string&>(unitTargetPath).c_str(),
166 SYSTEMD_PROPERTY_IFACE, "Get");
Josh D. King929ef702017-03-02 10:58:11 -0600167
168 method.append(SYSTEMD_INTERFACE_UNIT, "ActiveState");
Josh D. King929ef702017-03-02 10:58:11 -0600169
Anthony Wilson32c532e2018-10-25 21:56:07 -0500170 try
Josh D. King929ef702017-03-02 10:58:11 -0600171 {
Anthony Wilson32c532e2018-10-25 21:56:07 -0500172 auto result = this->bus.call(method);
173 result.read(currentState);
174 }
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500175 catch (const sdbusplus::exception_t& e)
Anthony Wilson32c532e2018-10-25 21:56:07 -0500176 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500177 error("Error in ActiveState Get: {ERROR}", "ERROR", e);
Josh D. King929ef702017-03-02 10:58:11 -0600178 return false;
179 }
180
Patrick Williams37413dc2020-05-13 11:29:54 -0500181 const auto& currentStateStr = std::get<std::string>(currentState);
William A. Kennington III7a0689a2018-11-12 17:19:33 -0800182 return currentStateStr == ACTIVE_STATE ||
183 currentStateStr == ACTIVATING_STATE;
Josh D. King929ef702017-03-02 10:58:11 -0600184}
185
Michael Tritz206a8332017-02-06 16:01:23 -0600186bool Host::isAutoReboot()
187{
Deepak Kodihalli3dd08a52017-07-25 07:34:44 -0500188 using namespace settings;
Michael Tritz206a8332017-02-06 16:01:23 -0600189
Andrew Geissler7f620832020-10-23 08:25:52 -0500190 /* The logic here is to first check the one-time AutoReboot setting.
191 * If this property is true (the default) then look at the persistent
192 * user setting in the non one-time object, otherwise honor the one-time
193 * setting and do not auto reboot.
194 */
195 auto methodOneTime = bus.new_method_call(
Andrew Geissler58a18012018-01-19 19:36:05 -0800196 settings.service(settings.autoReboot, autoRebootIntf).c_str(),
Andrew Geissler7f620832020-10-23 08:25:52 -0500197 settings.autoRebootOneTime.c_str(), SYSTEMD_PROPERTY_IFACE, "Get");
198 methodOneTime.append(autoRebootIntf, "AutoReboot");
199
200 auto methodUserSetting = bus.new_method_call(
201 settings.service(settings.autoReboot, autoRebootIntf).c_str(),
202 settings.autoReboot.c_str(), SYSTEMD_PROPERTY_IFACE, "Get");
203 methodUserSetting.append(autoRebootIntf, "AutoReboot");
Michael Tritz206a8332017-02-06 16:01:23 -0600204
Anthony Wilson32c532e2018-10-25 21:56:07 -0500205 try
Michael Tritz206a8332017-02-06 16:01:23 -0600206 {
Andrew Geissler7f620832020-10-23 08:25:52 -0500207 auto reply = bus.call(methodOneTime);
Patrick Williams2975e262020-05-13 18:01:09 -0500208 std::variant<bool> result;
Anthony Wilson32c532e2018-10-25 21:56:07 -0500209 reply.read(result);
Patrick Williams37413dc2020-05-13 11:29:54 -0500210 auto autoReboot = std::get<bool>(result);
Andrew Geissler7f620832020-10-23 08:25:52 -0500211
212 if (!autoReboot)
213 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500214 info("Auto reboot (one-time) disabled");
Andrew Geissler7f620832020-10-23 08:25:52 -0500215 return false;
216 }
217 else
218 {
219 // one-time is true so read the user setting
220 reply = bus.call(methodUserSetting);
221 reply.read(result);
222 autoReboot = std::get<bool>(result);
223 }
224
Anthony Wilson32c532e2018-10-25 21:56:07 -0500225 auto rebootCounterParam = reboot::RebootAttempts::attemptsLeft();
226
227 if (autoReboot)
Saqib Khancbe08d12017-03-10 01:29:20 -0600228 {
Anthony Wilson32c532e2018-10-25 21:56:07 -0500229 if (rebootCounterParam > 0)
230 {
231 // Reduce BOOTCOUNT by 1
Andrew Geisslerad65b2d2021-09-21 12:53:29 -0500232 info(
233 "Auto reboot enabled and boot count at {BOOTCOUNT}, rebooting",
234 "BOOTCOUNT", rebootCounterParam);
Anthony Wilson32c532e2018-10-25 21:56:07 -0500235 return true;
236 }
Anthony Wilson32c532e2018-10-25 21:56:07 -0500237 else
238 {
Andrew Geissler43284792021-09-23 10:32:15 -0500239 // We are at 0 so reset reboot counter and go to quiesce state
240 info("Auto reboot enabled but HOST BOOTCOUNT already set to 0");
NodeMan97b4cbfac2022-05-09 23:56:39 -0500241 attemptsLeft(reboot::RebootAttempts::retryAttempts());
Andrew Geissler1ab2b6c2022-03-10 16:16:15 -0600242
243 // Generate log since we will now be sitting in Quiesce
244 const std::string errorMsg =
245 "xyz.openbmc_project.State.Error.HostQuiesce";
246 utils::createError(this->bus, errorMsg,
247 sdbusplus::xyz::openbmc_project::Logging::
248 server::Entry::Level::Critical);
Andrew Geissler5bcaee12022-04-19 15:40:40 -0400249
250 // Generate BMC dump to assist with debug
251 utils::createBmcDump(this->bus);
252
Anthony Wilson32c532e2018-10-25 21:56:07 -0500253 return false;
254 }
Saqib Khand5ac6352017-04-04 09:53:59 -0500255 }
256 else
257 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500258 info("Auto reboot disabled.");
Saqib Khancbe08d12017-03-10 01:29:20 -0600259 return false;
260 }
Michael Tritz206a8332017-02-06 16:01:23 -0600261 }
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500262 catch (const sdbusplus::exception_t& e)
Saqib Khand5ac6352017-04-04 09:53:59 -0500263 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500264 error("Error in AutoReboot Get, {ERROR}", "ERROR", e);
Saqib Khand5ac6352017-04-04 09:53:59 -0500265 return false;
266 }
Michael Tritz206a8332017-02-06 16:01:23 -0600267}
268
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500269void Host::sysStateChangeJobRemoved(sdbusplus::message_t& msg)
Andrew Geissler4da7e002017-01-24 15:21:40 -0600270{
Andrew Geissler58a18012018-01-19 19:36:05 -0800271 uint32_t newStateID{};
Andrew Geissler4da7e002017-01-24 15:21:40 -0600272 sdbusplus::message::object_path newStateObjPath;
273 std::string newStateUnit{};
274 std::string newStateResult{};
275
Andrew Geissler58a18012018-01-19 19:36:05 -0800276 // Read the msg and populate each variable
Patrick Williamsd22706f2017-05-04 05:42:49 -0500277 msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
Andrew Geissler4da7e002017-01-24 15:21:40 -0600278
Allen.Wang79b45002022-02-10 17:59:20 +0800279 if ((newStateUnit == getTarget(server::Host::HostState::Off)) &&
Andrew Geissler969b2612018-03-29 10:16:51 -0700280 (newStateResult == "done") &&
Allen.Wang79b45002022-02-10 17:59:20 +0800281 (!stateActive(getTarget(server::Host::HostState::Running))))
Andrew Geissleref621162016-12-08 12:56:21 -0600282 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500283 info("Received signal that host is off");
Andrew Geissler4da7e002017-01-24 15:21:40 -0600284 this->currentHostState(server::Host::HostState::Off);
Dhruvaraj Subhashchandrana3b8d7e2017-08-10 05:40:04 -0500285 this->bootProgress(bootprogress::Progress::ProgressStages::Unspecified);
286 this->operatingSystemState(osstatus::Status::OSStatus::Inactive);
Andrew Geissleref621162016-12-08 12:56:21 -0600287 }
Allen.Wang79b45002022-02-10 17:59:20 +0800288 else if ((newStateUnit == getTarget(server::Host::HostState::Running)) &&
Andrew Geissler58a18012018-01-19 19:36:05 -0800289 (newStateResult == "done") &&
Allen.Wang79b45002022-02-10 17:59:20 +0800290 (stateActive(getTarget(server::Host::HostState::Running))))
Andrew Geissler58a18012018-01-19 19:36:05 -0800291 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500292 info("Received signal that host is running");
Andrew Geissler58a18012018-01-19 19:36:05 -0800293 this->currentHostState(server::Host::HostState::Running);
Andrew Geissler131d04a2021-03-12 11:02:41 -0600294
295 // Remove temporary file which is utilized for scenarios where the
296 // BMC is rebooted while the host is still up.
297 // This file is used to indicate to host related systemd services
298 // that the host is already running and they should skip running.
299 // Once the host state is back to running we can clear this file.
300 auto size = std::snprintf(nullptr, 0, HOST_RUNNING_FILE, 0);
301 size++; // null
302 std::unique_ptr<char[]> hostFile(new char[size]);
303 std::snprintf(hostFile.get(), size, HOST_RUNNING_FILE, 0);
304 if (std::filesystem::exists(hostFile.get()))
305 {
306 std::filesystem::remove(hostFile.get());
307 }
Andrew Geissler58a18012018-01-19 19:36:05 -0800308 }
Allen.Wang79b45002022-02-10 17:59:20 +0800309 else if ((newStateUnit == getTarget(server::Host::HostState::Quiesced)) &&
Josh D. King29d025d2017-04-27 12:40:22 -0500310 (newStateResult == "done") &&
Allen.Wang79b45002022-02-10 17:59:20 +0800311 (stateActive(getTarget(server::Host::HostState::Quiesced))))
Andrew Geissler58a18012018-01-19 19:36:05 -0800312 {
313 if (Host::isAutoReboot())
314 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500315 info("Beginning reboot...");
Andrew Geissler58a18012018-01-19 19:36:05 -0800316 Host::requestedHostTransition(server::Host::Transition::Reboot);
317 }
318 else
319 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500320 info("Maintaining quiesce");
Andrew Geissler58a18012018-01-19 19:36:05 -0800321 this->currentHostState(server::Host::HostState::Quiesced);
322 }
323 }
Andrew Geissleref621162016-12-08 12:56:21 -0600324}
325
Patrick Williamsf053e6f2022-07-22 19:26:54 -0500326void Host::sysStateChangeJobNew(sdbusplus::message_t& msg)
Andrew Geissler47b96122020-02-11 16:13:13 -0600327{
328 uint32_t newStateID{};
329 sdbusplus::message::object_path newStateObjPath;
330 std::string newStateUnit{};
331
332 // Read the msg and populate each variable
333 msg.read(newStateID, newStateObjPath, newStateUnit);
334
Allen.Wang79b45002022-02-10 17:59:20 +0800335 if (newStateUnit == getTarget(server::Host::HostState::DiagnosticMode))
Andrew Geissler47b96122020-02-11 16:13:13 -0600336 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500337 info("Received signal that host is in diagnostice mode");
Andrew Geissler47b96122020-02-11 16:13:13 -0600338 this->currentHostState(server::Host::HostState::DiagnosticMode);
339 }
Andrew Geissler128ea8e2022-06-22 12:28:15 -0400340 else if ((newStateUnit == hostCrashTarget) &&
341 (server::Host::currentHostState() ==
342 server::Host::HostState::Running))
343 {
344 // Only decrease the boot count if host was running when the host crash
345 // target was started. Systemd will sometimes trigger multiple
346 // JobNew events for the same target. This seems to be related to
347 // how OpenBMC utilizes the targets in the reboot scenario
348 info("Received signal that host has crashed, decrement reboot count");
349
350 // A host crash can cause a reboot of the host so decrement the reboot
351 // count
352 decrementRebootCount();
353 }
Andrew Geissler47b96122020-02-11 16:13:13 -0600354}
355
Andrew Geissler7b90a622017-08-08 11:41:08 -0500356uint32_t Host::decrementRebootCount()
357{
358 auto rebootCount = reboot::RebootAttempts::attemptsLeft();
Andrew Geissler58a18012018-01-19 19:36:05 -0800359 if (rebootCount > 0)
Andrew Geissler7b90a622017-08-08 11:41:08 -0500360 {
Andrew Geissler58a18012018-01-19 19:36:05 -0800361 return (reboot::RebootAttempts::attemptsLeft(rebootCount - 1));
Andrew Geissler7b90a622017-08-08 11:41:08 -0500362 }
363 return rebootCount;
364}
365
Allen.Wangba182f02022-03-23 19:01:53 +0800366fs::path Host::serialize()
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500367{
Allen.Wangba182f02022-03-23 19:01:53 +0800368 fs::path path{fmt::format(HOST_STATE_PERSIST_PATH, id)};
369 std::ofstream os(path.c_str(), std::ios::binary);
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500370 cereal::JSONOutputArchive oarchive(os);
371 oarchive(*this);
Allen.Wangba182f02022-03-23 19:01:53 +0800372 return path;
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500373}
374
Allen.Wangba182f02022-03-23 19:01:53 +0800375bool Host::deserialize()
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500376{
Allen.Wangba182f02022-03-23 19:01:53 +0800377 fs::path path{fmt::format(HOST_STATE_PERSIST_PATH, id)};
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500378 try
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500379 {
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500380 if (fs::exists(path))
381 {
382 std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
383 cereal::JSONInputArchive iarchive(is);
384 iarchive(*this);
385 return true;
386 }
387 return false;
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500388 }
Patrick Williams8583b3b2021-10-06 12:19:20 -0500389 catch (const cereal::Exception& e)
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500390 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500391 error("deserialize exception: {ERROR}", "ERROR", e);
Jayanth Othayothe39f3792017-09-19 23:53:31 -0500392 fs::remove(path);
393 return false;
394 }
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500395}
396
Andrew Geissleref3c1842016-12-01 12:33:09 -0600397Host::Transition Host::requestedHostTransition(Transition value)
398{
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500399 info("Host state transition request of {REQ}", "REQ", value);
Andrew Geissler7b90a622017-08-08 11:41:08 -0500400 // If this is not a power off request then we need to
401 // decrement the reboot counter. This code should
402 // never prevent a power on, it should just decrement
403 // the count to 0. The quiesce handling is where the
404 // check of this count will occur
Andrew Geissler58a18012018-01-19 19:36:05 -0800405 if (value != server::Host::Transition::Off)
Andrew Geissler7b90a622017-08-08 11:41:08 -0500406 {
407 decrementRebootCount();
408 }
409
Andrew Geisslera27a6e82017-07-27 16:44:43 -0500410 executeTransition(value);
Andrew Geissler7b90a622017-08-08 11:41:08 -0500411
Andrew Geissler58a18012018-01-19 19:36:05 -0800412 auto retVal = server::Host::requestedHostTransition(value);
Allen.Wangba182f02022-03-23 19:01:53 +0800413
Andrew Geissler033fc3b2017-08-30 15:11:44 -0500414 serialize();
Dhruvaraj Subhashchandran3f475242017-07-12 00:44:27 -0500415 return retVal;
Andrew Geissleref3c1842016-12-01 12:33:09 -0600416}
417
Dhruvaraj Subhashchandran4e6534f2017-09-19 06:13:20 -0500418Host::ProgressStages Host::bootProgress(ProgressStages value)
419{
420 auto retVal = bootprogress::Progress::bootProgress(value);
421 serialize();
422 return retVal;
423}
424
425Host::OSStatus Host::operatingSystemState(OSStatus value)
426{
427 auto retVal = osstatus::Status::operatingSystemState(value);
428 serialize();
429 return retVal;
430}
431
Andrew Geissleref3c1842016-12-01 12:33:09 -0600432Host::HostState Host::currentHostState(HostState value)
433{
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500434 info("Change to Host State: {STATE}", "STATE", value);
Andrew Geissleref621162016-12-08 12:56:21 -0600435 return server::Host::currentHostState(value);
Andrew Geissleref3c1842016-12-01 12:33:09 -0600436}
437
Andrew Geissler36529022016-11-29 15:23:54 -0600438} // namespace manager
439} // namespace state
Andrew Geisslera965cf02018-08-31 08:37:05 -0700440} // namespace phosphor