| #include "config.h" |
| |
| #include "hypervisor_state_manager.hpp" |
| |
| #include <fmt/format.h> |
| |
| #include <phosphor-logging/elog-errors.hpp> |
| #include <phosphor-logging/log.hpp> |
| #include <sdbusplus/exception.hpp> |
| #include <sdbusplus/server.hpp> |
| |
| #include <fstream> |
| #include <iostream> |
| #include <map> |
| #include <string> |
| |
| namespace phosphor |
| { |
| namespace state |
| { |
| namespace manager |
| { |
| |
| // When you see server:: you know we're referencing our base class |
| namespace server = sdbusplus::xyz::openbmc_project::State::server; |
| using namespace phosphor::logging; |
| |
| server::Host::Transition Hypervisor::requestedHostTransition(Transition value) |
| { |
| log<level::INFO>(fmt::format("Hypervisor state transition request of {}", |
| convertForMessage(value)) |
| .c_str()); |
| |
| // Only support the transition to On |
| if (value != server::Host::Transition::On) |
| { |
| log<level::ERR>("Hypervisor state only supports a transition to On"); |
| // TODO raise appropriate error exception |
| return server::Host::Transition::Off; |
| } |
| |
| // This property is monitored by a separate application (for example PLDM) |
| // which is responsible for propagating the On request to the hypervisor |
| |
| return server::Host::requestedHostTransition(value); |
| } |
| |
| server::Host::HostState Hypervisor::currentHostState(HostState value) |
| { |
| log<level::INFO>( |
| fmt::format("Change to Hypervisor State: {}", convertForMessage(value)) |
| .c_str()); |
| return server::Host::currentHostState(value); |
| } |
| |
| server::Host::HostState Hypervisor::currentHostState() |
| { |
| return server::Host::currentHostState(); |
| } |
| |
| void Hypervisor::updateCurrentHostState(std::string& bootProgress) |
| { |
| log<level::DEBUG>( |
| fmt::format("New BootProgress: {}", bootProgress).c_str()); |
| |
| if (bootProgress == "xyz.openbmc_project.State.Boot.Progress." |
| "ProgressStages.SystemInitComplete") |
| { |
| currentHostState(server::Host::HostState::Standby); |
| } |
| else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress." |
| "ProgressStages.OSStart") |
| { |
| currentHostState(server::Host::HostState::TransitioningToRunning); |
| } |
| else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress." |
| "ProgressStages.OSRunning") |
| { |
| currentHostState(server::Host::HostState::Running); |
| } |
| else if (bootProgress == "xyz.openbmc_project.State.Boot.Progress." |
| "ProgressStages.Unspecified") |
| { |
| // Unspecified is set when the system is powered off so |
| // set the state to off and reset the requested host state |
| // back to its default |
| currentHostState(server::Host::HostState::Off); |
| server::Host::requestedHostTransition(server::Host::Transition::Off); |
| } |
| else |
| { |
| // BootProgress changed and it is not one of the above so |
| // set hypervisor state to off |
| currentHostState(server::Host::HostState::Off); |
| } |
| } |
| |
| void Hypervisor::bootProgressChangeEvent(sdbusplus::message::message& msg) |
| { |
| std::string statusInterface; |
| std::map<std::string, std::variant<std::string>> msgData; |
| msg.read(statusInterface, msgData); |
| |
| auto propertyMap = msgData.find("BootProgress"); |
| if (propertyMap != msgData.end()) |
| { |
| // Extract the BootProgress |
| auto& bootProgress = std::get<std::string>(propertyMap->second); |
| updateCurrentHostState(bootProgress); |
| } |
| } |
| |
| } // namespace manager |
| } // namespace state |
| } // namespace phosphor |