1 #include "config.h"
2 
3 #include "hypervisor_state_manager.hpp"
4 
5 #include <phosphor-logging/elog-errors.hpp>
6 #include <phosphor-logging/lg2.hpp>
7 #include <sdbusplus/exception.hpp>
8 #include <sdbusplus/server.hpp>
9 
10 #include <fstream>
11 #include <iostream>
12 #include <map>
13 #include <string>
14 
15 namespace phosphor
16 {
17 namespace state
18 {
19 namespace manager
20 {
21 
22 PHOSPHOR_LOG2_USING;
23 
24 // When you see server:: you know we're referencing our base class
25 namespace server = sdbusplus::server::xyz::openbmc_project::state;
26 using namespace phosphor::logging;
27 
requestedHostTransition(Transition value)28 server::Host::Transition Hypervisor::requestedHostTransition(Transition value)
29 {
30     info("Hypervisor state transition request of {TRAN_REQUEST}",
31          "TRAN_REQUEST", value);
32 
33     // Only support the transition to On
34     if (value != server::Host::Transition::On)
35     {
36         error("Hypervisor state only supports a transition to On");
37         // TODO raise appropriate error exception
38         return server::Host::Transition::Off;
39     }
40 
41     // This property is monitored by a separate application (for example PLDM)
42     // which is responsible for propagating the On request to the hypervisor
43 
44     return server::Host::requestedHostTransition(value);
45 }
46 
currentHostState(HostState value)47 server::Host::HostState Hypervisor::currentHostState(HostState value)
48 {
49     // Only log a message if this has changed since last
50     if (value != server::Host::currentHostState())
51     {
52         info("Change to Hypervisor State: {HYP_STATE}", "HYP_STATE", value);
53     }
54     return server::Host::currentHostState(value);
55 }
56 
currentHostState() const57 server::Host::HostState Hypervisor::currentHostState() const
58 {
59     return server::Host::currentHostState();
60 }
61 
updateCurrentHostState(std::string & bootProgress)62 void Hypervisor::updateCurrentHostState(std::string& bootProgress)
63 {
64     debug("New BootProgress: {BOOTPROGRESS}", "BOOTPROGRESS", bootProgress);
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.OSRunning")
73     {
74         currentHostState(server::Host::HostState::Running);
75     }
76     else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress."
77                              "ProgressStages.Unspecified")
78     {
79         // Unspecified is set when the system is powered off so
80         // set the state to off and reset the requested host state
81         // back to its default
82         currentHostState(server::Host::HostState::Off);
83         server::Host::requestedHostTransition(server::Host::Transition::Off);
84     }
85     else
86     {
87         // BootProgress changed and it is not one of the above so
88         // set hypervisor state to off
89         currentHostState(server::Host::HostState::Off);
90     }
91 }
92 
bootProgressChangeEvent(sdbusplus::message_t & msg)93 void Hypervisor::bootProgressChangeEvent(sdbusplus::message_t& msg)
94 {
95     std::string statusInterface;
96     std::map<std::string, std::variant<std::string>> msgData;
97     msg.read(statusInterface, msgData);
98 
99     auto propertyMap = msgData.find("BootProgress");
100     if (propertyMap != msgData.end())
101     {
102         // Extract the BootProgress
103         auto& bootProgress = std::get<std::string>(propertyMap->second);
104         updateCurrentHostState(bootProgress);
105     }
106 }
107 
108 } // namespace manager
109 } // namespace state
110 } // namespace phosphor
111