blob: b3afc0c8556ed798757155b3eb07299718d8b2df [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;
Andrew Geisslerfe270d32021-01-27 14:06:46 -060027
28server::Host::Transition Hypervisor::requestedHostTransition(Transition value)
29{
30 log<level::INFO>(fmt::format("Hypervisor state transition request of {}",
31 convertForMessage(value))
32 .c_str());
33
34 // Only support the transition to On
35 if (value != server::Host::Transition::On)
36 {
37 log<level::ERR>("Hypervisor state only supports a transition to On");
38 // TODO raise appropriate error exception
39 return server::Host::Transition::Off;
40 }
41
42 // This property is monitored by a separate application (for example PLDM)
43 // which is responsible for propagating the On request to the hypervisor
44
45 return server::Host::requestedHostTransition(value);
46}
47
Andrew Geisslerfe270d32021-01-27 14:06:46 -060048server::Host::HostState Hypervisor::currentHostState(HostState value)
49{
50 log<level::INFO>(
51 fmt::format("Change to Hypervisor State: {}", convertForMessage(value))
52 .c_str());
53 return server::Host::currentHostState(value);
54}
55
Andrew Geisslerc74716e2021-02-09 15:11:10 -060056server::Host::HostState Hypervisor::currentHostState()
57{
58 return server::Host::currentHostState();
59}
60
61void Hypervisor::updateCurrentHostState(std::string& bootProgress)
62{
63 log<level::DEBUG>(
64 fmt::format("New BootProgress: {}", bootProgress).c_str());
65
66 if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
67 "ProgressStages.SystemInitComplete")
68 {
69 currentHostState(server::Host::HostState::Standby);
70 }
71 else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
72 "ProgressStages.OSStart")
73 {
74 currentHostState(server::Host::HostState::TransitioningToRunning);
75 }
76 else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
77 "ProgressStages.OSRunning")
78 {
79 currentHostState(server::Host::HostState::Running);
80 }
Andrew Geissler75f38ee2021-02-10 13:50:21 -060081 else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
82 "ProgressStages.Unspecified")
83 {
84 // Unspecified is set when the system is powered off so
85 // set the state to off and reset the requested host state
86 // back to its default
87 currentHostState(server::Host::HostState::Off);
88 server::Host::requestedHostTransition(server::Host::Transition::Off);
89 }
Andrew Geisslerc74716e2021-02-09 15:11:10 -060090 else
91 {
92 // BootProgress changed and it is not one of the above so
93 // set hypervisor state to off
94 currentHostState(server::Host::HostState::Off);
95 }
96}
97
98void Hypervisor::bootProgressChangeEvent(sdbusplus::message::message& msg)
99{
100 std::string statusInterface;
101 std::map<std::string, std::variant<std::string>> msgData;
102 msg.read(statusInterface, msgData);
103
104 auto propertyMap = msgData.find("BootProgress");
105 if (propertyMap != msgData.end())
106 {
107 // Extract the BootProgress
108 auto& bootProgress = std::get<std::string>(propertyMap->second);
109 updateCurrentHostState(bootProgress);
110 }
111}
112
Andrew Geisslerfe270d32021-01-27 14:06:46 -0600113} // namespace manager
114} // namespace state
115} // namespace phosphor