diff options
author | Nagaraju Goruganti <ngorugan@in.ibm.com> | 2018-04-06 13:41:01 -0500 |
---|---|---|
committer | Nagaraju Goruganti <ngorugan@in.ibm.com> | 2018-05-12 04:57:37 +0000 |
commit | cb781fe1b8750712b9f8c6e534e794d27204c5ef (patch) | |
tree | 48428765acf75b0a66eedbcdbd4ff2f40046ca1c /chassis_state_manager.cpp | |
parent | 41a774efacb3f3a9593aeaa971468e770d205e13 (diff) | |
download | phosphor-state-manager-cb781fe1b8750712b9f8c6e534e794d27204c5ef.tar.gz phosphor-state-manager-cb781fe1b8750712b9f8c6e534e794d27204c5ef.zip |
Add Chassis POH Counter
Added 32-bit counter, which shows how many hours the system has been
running. The value is a cumulative one and includes all working hours
since production. If the chassis state is Powered-on, This will be
incremented by one for every hour. It won't get updated when the
chassis state is powered-off.
Resolves openbmc/openbmc#2979
Change-Id: I18e9bb571d1a6e401b25450168249f70891be665
Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
Diffstat (limited to 'chassis_state_manager.cpp')
-rw-r--r-- | chassis_state_manager.cpp | 128 |
1 files changed, 127 insertions, 1 deletions
diff --git a/chassis_state_manager.cpp b/chassis_state_manager.cpp index ece0b1c..d78a6f7 100644 --- a/chassis_state_manager.cpp +++ b/chassis_state_manager.cpp @@ -1,6 +1,15 @@ #include <sdbusplus/bus.hpp> #include <phosphor-logging/log.hpp> +#include <phosphor-logging/elog-errors.hpp> +#include "xyz/openbmc_project/Common/error.hpp" #include "chassis_state_manager.hpp" +#include <cereal/archives/json.hpp> +#include <fstream> +#include "config.h" +#include <experimental/filesystem> + +// Register class version with Cereal +CEREAL_CLASS_VERSION(phosphor::state::manager::Chassis, CLASS_VERSION); namespace phosphor { @@ -181,10 +190,127 @@ Chassis::Transition Chassis::requestedPowerTransition(Transition value) Chassis::PowerState Chassis::currentPowerState(PowerState value) { + PowerState chassisPowerState; log<level::INFO>("Change to Chassis Power State", entry("CHASSIS_CURRENT_POWER_STATE=%s", convertForMessage(value).c_str())); - return server::Chassis::currentPowerState(value); + + chassisPowerState = server::Chassis::currentPowerState(value); + if (chassisPowerState == PowerState::On) + { + timer->state(timer::ON); + } + else + { + timer->state(timer::OFF); + } + return chassisPowerState; +} + +uint32_t Chassis::pOHCounter(uint32_t value) +{ + if (value != pOHCounter()) + { + ChassisInherit::pOHCounter(value); + serialize(); + } + return pOHCounter(); +} + +void Chassis::restorePOHCounter() +{ + uint32_t counter; + if (!deserialize(POH_COUNTER_PERSIST_PATH, counter)) + { + // set to default value + pOHCounter(0); + } + else + { + pOHCounter(counter); + } +} + +fs::path Chassis::serialize(const fs::path& path) +{ + std::ofstream os(path.c_str(), std::ios::binary); + cereal::JSONOutputArchive oarchive(os); + oarchive(pOHCounter()); + return path; +} + +bool Chassis::deserialize(const fs::path& path, uint32_t& pOHCounter) +{ + try + { + if (fs::exists(path)) + { + std::ifstream is(path.c_str(), std::ios::in | std::ios::binary); + cereal::JSONInputArchive iarchive(is); + iarchive(pOHCounter); + return true; + } + return false; + } + catch (cereal::Exception& e) + { + log<level::ERR>(e.what()); + fs::remove(path); + return false; + } + catch (const fs::filesystem_error& e) + { + return false; + } + + return false; +} + +void Chassis::startPOHCounter() +{ + using namespace std::chrono_literals; + using namespace phosphor::logging; + using namespace sdbusplus::xyz::openbmc_project::Common::Error; + + auto dir = fs::path(POH_COUNTER_PERSIST_PATH).parent_path(); + fs::create_directories(dir); + + sd_event* event = nullptr; + auto r = sd_event_default(&event); + if (r < 0) + { + log<level::ERR>("Error creating a default sd_event handler"); + throw; + } + + phosphor::state::manager::EventPtr eventP{event}; + event = nullptr; + + auto callback = [&]() { + if (ChassisInherit::currentPowerState() == PowerState::On) + { + pOHCounter(pOHCounter() + 1); + } + }; + + try + { + timer = std::make_unique<phosphor::state::manager::Timer>( + eventP, callback, std::chrono::seconds(POH::hour), + phosphor::state::manager::timer::ON); + bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL); + r = sd_event_loop(eventP.get()); + if (r < 0) + { + log<level::ERR>("Error occurred during the sd_event_loop", + entry("RC=%d", r)); + elog<InternalFailure>(); + } + } + catch (InternalFailure& e) + { + phosphor::logging::commit<InternalFailure>(); + } } } // namespace manager |