diff options
author | Yang, Cheng C <cheng.c.yang@intel.com> | 2019-08-20 15:53:02 +0300 |
---|---|---|
committer | Gerrit Code Review <gerrit@localhost> | 2019-08-20 15:53:02 +0300 |
commit | 9f8aa30f0b8f50fa955030b859bfb0e616161d2a (patch) | |
tree | f0b07143cffed21cb9f1d8fe0a0627ed6ec6d8fc | |
parent | 7e3154c2e810e31c820fff83ec66bd6376a38685 (diff) | |
parent | 60fad5c0082a729cf275853da8ed489c69c172ed (diff) | |
download | provingground-9f8aa30f0b8f50fa955030b859bfb0e616161d2a.tar.xz |
Merge "Add keep alive function for PSU"
-rw-r--r-- | psu-manager/include/cold_redundancy.hpp | 9 | ||||
-rw-r--r-- | psu-manager/include/utility.hpp | 7 | ||||
-rw-r--r-- | psu-manager/src/cold_redundancy.cpp | 152 | ||||
-rw-r--r-- | psu-manager/src/redundancy_main.cpp | 3 | ||||
-rw-r--r-- | psu-manager/src/utility.cpp | 2 |
5 files changed, 149 insertions, 24 deletions
diff --git a/psu-manager/include/cold_redundancy.hpp b/psu-manager/include/cold_redundancy.hpp index 6d5397c..a8c53b5 100644 --- a/psu-manager/include/cold_redundancy.hpp +++ b/psu-manager/include/cold_redundancy.hpp @@ -30,7 +30,8 @@ class ColdRedundancy ColdRedundancy( boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer, - std::shared_ptr<sdbusplus::asio::connection>& dbusConnection); + std::shared_ptr<sdbusplus::asio::connection>& dbusConnection, + std::vector<std::unique_ptr<sdbusplus::bus::match::match>>& matches); ~ColdRedundancy() = default; uint8_t pSUNumber() const override; @@ -55,15 +56,17 @@ class ColdRedundancy void configCR(bool reConfig); void checkCR(void); void reRanking(void); - void putWarmRedundant(); + void putWarmRedundant(void); + void keepAliveCheck(void); std::shared_ptr<sdbusplus::asio::connection>& systemBus; - std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches; boost::asio::steady_timer timerRotation; boost::asio::steady_timer timerCheck; boost::asio::steady_timer warmRedundantTimer1; boost::asio::steady_timer warmRedundantTimer2; + boost::asio::steady_timer keepAliveTimer; + boost::asio::steady_timer filterTimer; }; constexpr const uint8_t pmbusCmdCRSupport = 0xd0; diff --git a/psu-manager/include/utility.hpp b/psu-manager/include/utility.hpp index e3c312a..882d151 100644 --- a/psu-manager/include/utility.hpp +++ b/psu-manager/include/utility.hpp @@ -28,8 +28,9 @@ static const constexpr std::array<const char*, 1> psuEventInterface = { "xyz.openbmc_project.State.Decorator.OperationalStatus"}; using BasicVariantType = - std::variant<std::vector<std::string>, std::string, int64_t, uint64_t, - double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>; + std::variant<std::vector<std::string>, std::vector<uint64_t>, std::string, + int64_t, uint64_t, double, int32_t, uint32_t, int16_t, + uint16_t, uint8_t, bool>; using PropertyMapType = boost::container::flat_map<std::string, BasicVariantType>; @@ -56,4 +57,4 @@ void getPSUEvent( const std::string& psuName, PSUState& state); int i2cSet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t value); -int i2cGet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t& value); +int i2cGet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, int& value); diff --git a/psu-manager/src/cold_redundancy.cpp b/psu-manager/src/cold_redundancy.cpp index e88897e..14fabca 100644 --- a/psu-manager/src/cold_redundancy.cpp +++ b/psu-manager/src/cold_redundancy.cpp @@ -31,22 +31,28 @@ static constexpr const bool debug = false; -static constexpr const std::array<const char*, 1> psuInterfaceTypes = { - "xyz.openbmc_project.Configuration.pmbus"}; -static const constexpr char* inventoryPath = "/xyz/openbmc_project/inventory"; +static constexpr const std::array<const char*, 2> psuInterfaceTypes = { + "xyz.openbmc_project.Configuration.pmbus", + "xyz.openbmc_project.Configuration.PSUPresence"}; +static const constexpr char* inventoryPath = + "/xyz/openbmc_project/inventory/system"; static const constexpr char* eventPath = "/xyz/openbmc_project/State/Decorator"; static const constexpr char* coldRedundancyPath = "/xyz/openbmc_project/control/power_supply_redundancy"; static std::vector<std::unique_ptr<PowerSupply>> powerSupplies; +static uint8_t pmbusNum = 7; +static std::vector<uint64_t> addrTable = {0x50, 0x51}; ColdRedundancy::ColdRedundancy( boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer, - std::shared_ptr<sdbusplus::asio::connection>& systemBus) : + std::shared_ptr<sdbusplus::asio::connection>& systemBus, + std::vector<std::unique_ptr<sdbusplus::bus::match::match>>& matches) : sdbusplus::xyz::openbmc_project::Control::server::PowerSupplyRedundancy( *systemBus, coldRedundancyPath), timerRotation(io), timerCheck(io), systemBus(systemBus), - warmRedundantTimer1(io), warmRedundantTimer2(io) + warmRedundantTimer1(io), warmRedundantTimer2(io), keepAliveTimer(io), + filterTimer(io) { io.post([this, &io, &objectServer, &systemBus]() { createPSU(io, objectServer, systemBus); @@ -59,7 +65,6 @@ ColdRedundancy::ColdRedundancy( std::cerr << "callback method error\n"; return; } - boost::asio::steady_timer filterTimer(io); filterTimer.expires_after(std::chrono::seconds(1)); filterTimer.async_wait([this, &io, &objectServer, &systemBus]( const boost::system::error_code& ec) { @@ -244,13 +249,83 @@ ColdRedundancy::ColdRedundancy( io.run(); } +static std::set<uint8_t> psuPresence; +static const constexpr uint8_t fruOffsetZero = 0x00; + +int pingPSU(const uint8_t& addr) +{ + int fruData = 0; + return i2cGet(pmbusNum, addr, fruOffsetZero, fruData); +} + +void rescanPSUEntityManager( + std::shared_ptr<sdbusplus::asio::connection>& dbusConnection) +{ + sdbusplus::message::message method = dbusConnection->new_method_call( + "xyz.openbmc_project.FruDevice", "/xyz/openbmc_project/FruDevice", + "xyz.openbmc_project.FruDeviceManager", "ReScan"); + + try + { + dbusConnection->call(method); + } + catch (const sdbusplus::exception::exception&) + { + std::cerr << "Failed to rescan entity manager\n"; + } + return; +} + +void keepAlive(std::shared_ptr<sdbusplus::asio::connection>& dbusConnection) +{ + bool newPSUFound = false; + uint8_t psuNumber = 1; + for (const auto& addr : addrTable) + { + if (0 == pingPSU(addr)) + { + auto found = psuPresence.find(addr); + if (found != psuPresence.end()) + { + continue; + } + newPSUFound = true; + psuPresence.emplace(addr); + std::string psuNumStr = "PSU" + std::to_string(psuNumber); + sd_journal_send("MESSAGE=%s", "New PSU is found", "PRIORITY=%i", + LOG_INFO, "REDFISH_MESSAGE_ID=%s", + "OpenBMC.0.1.PowerSupplyInserted", + "REDFISH_MESSAGE_ARGS=%s", psuNumStr.c_str(), NULL); + } + else + { + auto found = psuPresence.find(addr); + if (found == psuPresence.end()) + { + continue; + } + psuPresence.erase(addr); + std::string psuNumStr = "PSU" + std::to_string(psuNumber); + sd_journal_send("MESSAGE=%s", "One PSU is removed", "PRIORITY=%i", + LOG_INFO, "REDFISH_MESSAGE_ID=%s", + "OpenBMC.0.1.PowerSupplyRemoved", + "REDFISH_MESSAGE_ARGS=%s", psuNumStr.c_str(), NULL); + } + psuNumber++; + } + if (newPSUFound) + { + rescanPSUEntityManager(dbusConnection); + } +} + +static const constexpr int psuDepth = 3; // Check PSU information from entity-manager D-Bus interface and use the bus // address to create PSU Class for cold redundancy. void ColdRedundancy::createPSU( boost::asio::io_service& io, sdbusplus::asio::object_server& objectServer, std::shared_ptr<sdbusplus::asio::connection>& conn) { - std::vector<PropertyMapType> sensorConfigs; numberOfPSU = 0; powerSupplies.clear(); @@ -290,8 +365,9 @@ void ColdRedundancy::createPSU( continue; conn->async_method_call( - [this, &conn](const boost::system::error_code ec, - PropertyMapType propMap) { + [this, &conn, + &interface](const boost::system::error_code ec, + PropertyMapType propMap) { if (ec) { std::cerr @@ -303,16 +379,44 @@ void ColdRedundancy::createPSU( { std::cerr << "get valid propMap\n"; } + + auto configName = + std::get_if<std::string>(&propMap["Name"]); + if (configName == nullptr) + { + std::cerr << "error finding necessary " + "entry in configuration\n"; + return; + } + if (interface == "xyz.openbmc_project." + "Configuration.PSUPresence") + { + auto psuBus = + std::get_if<uint64_t>(&propMap["Bus"]); + auto psuAddress = + std::get_if<std::vector<uint64_t>>( + &propMap["Address"]); + + if (psuBus == nullptr || + psuAddress == nullptr) + { + std::cerr << "error finding necessary " + "entry in configuration\n"; + return; + } + pmbusNum = static_cast<uint8_t>(*psuBus); + addrTable = *psuAddress; + keepAliveCheck(); + return; + } + auto configBus = std::get_if<uint64_t>(&propMap["Bus"]); auto configAddress = std::get_if<uint64_t>(&propMap["Address"]); - auto configName = - std::get_if<std::string>(&propMap["Name"]); if (configBus == nullptr || - configAddress == nullptr || - configName == nullptr) + configAddress == nullptr) { std::cerr << "error finding necessary " "entry in configuration\n"; @@ -337,12 +441,28 @@ void ColdRedundancy::createPSU( "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper", "GetSubTree", - "/xyz/openbmc_project/inventory/system/powersupply", 2, - psuInterfaceTypes); + "/xyz/openbmc_project/inventory/system", psuDepth, psuInterfaceTypes); startRotateCR(); startCRCheck(); } +void ColdRedundancy::keepAliveCheck(void) +{ + keepAliveTimer.expires_after(std::chrono::seconds(2)); + keepAliveTimer.async_wait([&](const boost::system::error_code& ec) { + if (ec == boost::asio::error::operation_aborted) + { + return; + } + else if (ec) + { + std::cerr << "timer error\n"; + } + keepAlive(systemBus); + keepAliveCheck(); + }); +} + uint8_t ColdRedundancy::pSUNumber() const { return numberOfPSU; @@ -453,7 +573,7 @@ void ColdRedundancy::checkCR(void) { if (psu->state == PSUState::normal) { - uint8_t order = 0; + int order = 0; if (i2cGet(psu->bus, psu->address, pmbusCmdCRSupport, order)) { std::cerr << "Failed to get PSU Cold Redundancy order\n"; diff --git a/psu-manager/src/redundancy_main.cpp b/psu-manager/src/redundancy_main.cpp index 7bae05b..c9bd3f2 100644 --- a/psu-manager/src/redundancy_main.cpp +++ b/psu-manager/src/redundancy_main.cpp @@ -21,11 +21,12 @@ int main(int argc, char** argv) { boost::asio::io_service io; auto systemBus = std::make_shared<sdbusplus::asio::connection>(io); + std::vector<std::unique_ptr<sdbusplus::bus::match::match>> matches; systemBus->request_name("xyz.openbmc_project.PSURedundancy"); sdbusplus::asio::object_server objectServer(systemBus); - ColdRedundancy coldRedundancy(io, objectServer, systemBus); + ColdRedundancy coldRedundancy(io, objectServer, systemBus, matches); return 0; } diff --git a/psu-manager/src/utility.cpp b/psu-manager/src/utility.cpp index 2143c80..d54c2b0 100644 --- a/psu-manager/src/utility.cpp +++ b/psu-manager/src/utility.cpp @@ -83,7 +83,7 @@ int i2cSet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t value) return 0; } -int i2cGet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t& value) +int i2cGet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, int& value) { unsigned long funcs = 0; std::string devPath = "/dev/i2c-" + std::to_string(bus); |