1 #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 17 namespace phosphor 18 { 19 namespace state 20 { 21 namespace manager 22 { 23 24 // When you see server:: you know we're referencing our base class 25 namespace server = sdbusplus::xyz::openbmc_project::State::server; 26 using namespace phosphor::logging; 27 28 server::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 48 server::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 56 server::Host::HostState Hypervisor::currentHostState() 57 { 58 return server::Host::currentHostState(); 59 } 60 61 void 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 } 81 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 } 90 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 98 void 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 113 } // namespace manager 114 } // namespace state 115 } // namespace phosphor 116