blob: e1f51064c2a0a110567269992c7d94fe17f50875 [file] [log] [blame]
Andrew Geisslerfe270d32021-01-27 14:06:46 -06001#include "config.h"
2
3#include "hypervisor_state_manager.hpp"
4
5#include <fmt/format.h>
6
7#include <phosphor-logging/elog-errors.hpp>
8#include <phosphor-logging/log.hpp>
9#include <sdbusplus/exception.hpp>
10#include <sdbusplus/server.hpp>
11
12#include <fstream>
13#include <iostream>
14#include <map>
15#include <string>
16
17namespace phosphor
18{
19namespace state
20{
21namespace manager
22{
23
24// When you see server:: you know we're referencing our base class
25namespace server = sdbusplus::xyz::openbmc_project::State::server;
26using namespace phosphor::logging;
27using sdbusplus::exception::SdBusError;
28
29server::Host::Transition Hypervisor::requestedHostTransition(Transition value)
30{
31 log<level::INFO>(fmt::format("Hypervisor state transition request of {}",
32 convertForMessage(value))
33 .c_str());
34
35 // Only support the transition to On
36 if (value != server::Host::Transition::On)
37 {
38 log<level::ERR>("Hypervisor state only supports a transition to On");
39 // TODO raise appropriate error exception
40 return server::Host::Transition::Off;
41 }
42
43 // This property is monitored by a separate application (for example PLDM)
44 // which is responsible for propagating the On request to the hypervisor
45
46 return server::Host::requestedHostTransition(value);
47}
48
Andrew Geisslerfe270d32021-01-27 14:06:46 -060049server::Host::HostState Hypervisor::currentHostState(HostState value)
50{
51 log<level::INFO>(
52 fmt::format("Change to Hypervisor State: {}", convertForMessage(value))
53 .c_str());
54 return server::Host::currentHostState(value);
55}
56
Andrew Geisslerc74716e2021-02-09 15:11:10 -060057server::Host::HostState Hypervisor::currentHostState()
58{
59 return server::Host::currentHostState();
60}
61
62void Hypervisor::updateCurrentHostState(std::string& bootProgress)
63{
64 log<level::DEBUG>(
65 fmt::format("New BootProgress: {}", bootProgress).c_str());
66
67 if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
68 "ProgressStages.SystemInitComplete")
69 {
70 currentHostState(server::Host::HostState::Standby);
71 }
72 else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
73 "ProgressStages.OSStart")
74 {
75 currentHostState(server::Host::HostState::TransitioningToRunning);
76 }
77 else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
78 "ProgressStages.OSRunning")
79 {
80 currentHostState(server::Host::HostState::Running);
81 }
Andrew Geissler75f38ee2021-02-10 13:50:21 -060082 else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
83 "ProgressStages.Unspecified")
84 {
85 // Unspecified is set when the system is powered off so
86 // set the state to off and reset the requested host state
87 // back to its default
88 currentHostState(server::Host::HostState::Off);
89 server::Host::requestedHostTransition(server::Host::Transition::Off);
90 }
Andrew Geisslerc74716e2021-02-09 15:11:10 -060091 else
92 {
93 // BootProgress changed and it is not one of the above so
94 // set hypervisor state to off
95 currentHostState(server::Host::HostState::Off);
96 }
97}
98
99void Hypervisor::bootProgressChangeEvent(sdbusplus::message::message& msg)
100{
101 std::string statusInterface;
102 std::map<std::string, std::variant<std::string>> msgData;
103 msg.read(statusInterface, msgData);
104
105 auto propertyMap = msgData.find("BootProgress");
106 if (propertyMap != msgData.end())
107 {
108 // Extract the BootProgress
109 auto& bootProgress = std::get<std::string>(propertyMap->second);
110 updateCurrentHostState(bootProgress);
111 }
112}
113
Andrew Geisslerfe270d32021-01-27 14:06:46 -0600114} // namespace manager
115} // namespace state
116} // namespace phosphor