summaryrefslogtreecommitdiffstats
path: root/chassis_state_manager.cpp
diff options
context:
space:
mode:
authorNagaraju Goruganti <ngorugan@in.ibm.com>2018-04-06 13:41:01 -0500
committerNagaraju Goruganti <ngorugan@in.ibm.com>2018-05-12 04:57:37 +0000
commitcb781fe1b8750712b9f8c6e534e794d27204c5ef (patch)
tree48428765acf75b0a66eedbcdbd4ff2f40046ca1c /chassis_state_manager.cpp
parent41a774efacb3f3a9593aeaa971468e770d205e13 (diff)
downloadphosphor-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.cpp128
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
OpenPOWER on IntegriCloud