summaryrefslogtreecommitdiff
path: root/psu-manager
diff options
context:
space:
mode:
authorCheng C Yang <cheng.c.yang@intel.com>2019-08-16 18:02:58 +0300
committerCheng C Yang <cheng.c.yang@intel.com>2019-08-16 18:02:58 +0300
commit60fad5c0082a729cf275853da8ed489c69c172ed (patch)
treebd98b38613612ad20425b796d136adb448ef91af /psu-manager
parenta19580d978a58d1715b998c2b1db54462ca41d1e (diff)
downloadprovingground-60fad5c0082a729cf275853da8ed489c69c172ed.tar.xz
Add keep alive function for PSU
Add keep alive function to monitor the FRU of PSU. If FRU cannot be accessed, it means one PSU have been removed, need to rescan FRU. Tested: Only insert one PSU and start system. Check entity-manager, only one PSU will be found. Insert another PSU then, wait for a while and check entity-manager again, two PSU should be found now, add redfish log show { "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry", "@odata.id": "/redfish/v1/Systems/system/LogServices/EventLog/Entries/ 1563892418", "@odata.type": "#LogEntry.v1_4_0.LogEntry", "Created": "2019-07-23T14:33:38+00:00", "EntryType": "Event", "Id": "1563892418", "Message": "Power supply PSU1 inserted.", "MessageArgs": [ "PSU0" ], "MessageId": "OpenBMC.0.1.PowerSupplyInserted", "Name": "System Event Log Entry", "Severity": "OK" }, Then remove one PSU again, now only one PSU should be showed in entity-manager. And redfish log show: { "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry", "@odata.id": "/redfish/v1/Systems/system/LogServices/EventLog/Entries/ 1563892532", "@odata.type": "#LogEntry.v1_4_0.LogEntry", "Created": "2019-07-23T14:35:32+00:00", "EntryType": "Event", "Id": "1563892532", "Message": "Power supply PSU1 removed.", "MessageArgs": [ "PSU0" ], "MessageId": "OpenBMC.0.1.PowerSupplyRemoved", "Name": "System Event Log Entry", "Severity": "Warning" }, Change-Id: Icbd70407892a334a52208e5fa6da1c4bbd75bcab Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
Diffstat (limited to 'psu-manager')
-rw-r--r--psu-manager/include/cold_redundancy.hpp9
-rw-r--r--psu-manager/include/utility.hpp7
-rw-r--r--psu-manager/src/cold_redundancy.cpp152
-rw-r--r--psu-manager/src/redundancy_main.cpp3
-rw-r--r--psu-manager/src/utility.cpp2
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);