Add logging for Fan Presence / Redundancy
Add logging and fix bug with shared_ptr usage. We
now use a std::optional * to the shared redundancy
object, so that it can 1. point to object / null and 2.
exist in config or not.
Tested: cat /var/log/redfish to see logs made by removing
and adding fans, and using sensor override to change
redundancy.
Change-Id: Ic4b319cf7484cbbd7ce7dbdf7556f48bebe11cb0
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/TachSensor.hpp b/include/TachSensor.hpp
index c6f255f..b160a60 100644
--- a/include/TachSensor.hpp
+++ b/include/TachSensor.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <systemd/sd-journal.h>
+
#include <Thresholds.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
@@ -12,7 +14,7 @@
public:
PresenceSensor(const size_t index, bool inverted,
- boost::asio::io_service& io);
+ boost::asio::io_service& io, const std::string& name);
~PresenceSensor();
void monitorPresence(void);
@@ -24,8 +26,16 @@
bool inverted;
boost::asio::ip::tcp::socket inputDev;
int fd;
+ std::string name;
};
+namespace redundancy
+{
+constexpr const char* full = "Full";
+constexpr const char* degraded = "Degraded";
+constexpr const char* failed = "Failed";
+} // namespace redundancy
+
class RedundancySensor
{
public:
@@ -38,6 +48,7 @@
private:
size_t count;
+ std::string state = redundancy::full;
std::shared_ptr<sdbusplus::asio::dbus_interface> iface;
std::shared_ptr<sdbusplus::asio::dbus_interface> association;
sdbusplus::asio::object_server& objectServer;
@@ -51,7 +62,7 @@
sdbusplus::asio::object_server& objectServer,
std::shared_ptr<sdbusplus::asio::connection>& conn,
std::unique_ptr<PresenceSensor>&& presence,
- const std::shared_ptr<RedundancySensor>& redundancy,
+ std::optional<RedundancySensor>* redundancy,
boost::asio::io_service& io, const std::string& fanName,
std::vector<thresholds::Threshold>&& thresholds,
const std::string& sensorConfiguration,
@@ -60,7 +71,7 @@
private:
sdbusplus::asio::object_server& objServer;
- std::shared_ptr<RedundancySensor> redundancy;
+ std::optional<RedundancySensor>* redundancy;
std::unique_ptr<PresenceSensor> presence;
std::shared_ptr<sdbusplus::asio::dbus_interface> itemIface;
boost::asio::posix::stream_descriptor inputDev;
@@ -71,3 +82,35 @@
void handleResponse(const boost::system::error_code& err);
void checkThresholds(void) override;
};
+
+inline void logFanInserted(const std::string& device)
+{
+
+ sd_journal_send("MESSAGE=%s", "Fan Inserted", "PRIORITY=%i", LOG_ERR,
+ "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.FanInserted",
+ "REDFISH_MESSAGE_ARGS=%s", device.c_str(), NULL);
+}
+
+inline void logFanRemoved(const std::string& device)
+{
+
+ sd_journal_send("MESSAGE=%s", "Fan Removed", "PRIORITY=%i", LOG_ERR,
+ "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.FanRemoved",
+ "REDFISH_MESSAGE_ARGS=%s", device.c_str(), NULL);
+}
+
+inline void logFanRedundancyLost(void)
+{
+
+ sd_journal_send("MESSAGE=%s", "Fan Inserted", "PRIORITY=%i", LOG_ERR,
+ "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.FanRedundancyLost",
+ NULL);
+}
+
+inline void logFanRedundancyRestored(void)
+{
+
+ sd_journal_send("MESSAGE=%s", "Fan Removed", "PRIORITY=%i", LOG_ERR,
+ "REDFISH_MESSAGE_ID=%s",
+ "OpenBMC.0.1.FanRedundancyRegained", NULL);
+}
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 962a115..eeface8 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -46,7 +46,7 @@
};
// todo: power supply fan redundancy
-std::shared_ptr<RedundancySensor> systemRedundancy = nullptr;
+std::optional<RedundancySensor> systemRedundancy;
FanTypes getFanType(const fs::path& parentPath)
{
@@ -251,14 +251,14 @@
size_t index = std::get<uint64_t>(findIndex->second);
bool inverted =
std::get<std::string>(findPolarity->second) == "Low";
- presenceSensor =
- std::make_unique<PresenceSensor>(index, inverted, io);
+ presenceSensor = std::make_unique<PresenceSensor>(
+ index, inverted, io, sensorName);
}
}
- std::shared_ptr<RedundancySensor> redundancy;
+ std::optional<RedundancySensor>* redundancy = nullptr;
if (fanType == FanTypes::aspeed)
{
- redundancy = systemRedundancy;
+ redundancy = &systemRedundancy;
}
constexpr double defaultMaxReading = 25000;
@@ -360,10 +360,10 @@
"/xyz/openbmc_project/sensors/fan_tach/" +
sensor.second->name);
}
- systemRedundancy = nullptr;
- systemRedundancy = std::make_shared<RedundancySensor>(
+ systemRedundancy.reset();
+ systemRedundancy.emplace(RedundancySensor(
std::get<uint64_t>(findCount->second), sensorList,
- objectServer, pathPair.first);
+ objectServer, pathPair.first));
return;
}
diff --git a/src/TachSensor.cpp b/src/TachSensor.cpp
index 03ff4a5..295c7e6 100644
--- a/src/TachSensor.cpp
+++ b/src/TachSensor.cpp
@@ -35,7 +35,7 @@
sdbusplus::asio::object_server& objectServer,
std::shared_ptr<sdbusplus::asio::connection>& conn,
std::unique_ptr<PresenceSensor>&& presenceSensor,
- const std::shared_ptr<RedundancySensor>& redundancy,
+ std::optional<RedundancySensor>* redundancy,
boost::asio::io_service& io, const std::string& fanName,
std::vector<thresholds::Threshold>&& _thresholds,
const std::string& sensorConfiguration,
@@ -187,17 +187,18 @@
void TachSensor::checkThresholds(void)
{
bool status = thresholds::checkThresholds(this);
- if (redundancy)
+ if (redundancy && *redundancy)
{
- redundancy->update("/xyz/openbmc_project/sensors/fan_tach/" + name,
- !status);
+ (*redundancy)
+ ->update("/xyz/openbmc_project/sensors/fan_tach/" + name, !status);
}
}
PresenceSensor::PresenceSensor(const size_t index, bool inverted,
- boost::asio::io_service& io) :
+ boost::asio::io_service& io,
+ const std::string& name) :
inverted(inverted),
- inputDev(io)
+ inputDev(io), name(name)
{
// todo: use gpiodaemon
std::string device = gpioPath + std::string("gpio") + std::to_string(index);
@@ -267,7 +268,18 @@
{
value = !value;
}
- status = value;
+ if (value != status)
+ {
+ status = value;
+ if (status)
+ {
+ logFanInserted(name);
+ }
+ else
+ {
+ logFanRemoved(name);
+ }
+ }
}
}
@@ -305,7 +317,7 @@
statuses[name] = failed;
size_t failedCount = 0;
- std::string state = "Full";
+ std::string newState = redundancy::full;
for (const auto& status : statuses)
{
if (status.second)
@@ -314,13 +326,25 @@
}
if (failedCount > count)
{
- state = "Failed";
+ newState = redundancy::failed;
break;
}
else if (failedCount)
{
- state = "Degraded";
+ newState = redundancy::degraded;
}
}
- iface->set_property("Status", state);
+ if (state != newState)
+ {
+ if (state == redundancy::full)
+ {
+ logFanRedundancyLost();
+ }
+ else if (newState == redundancy::full)
+ {
+ logFanRedundancyRestored();
+ }
+ state = newState;
+ iface->set_property("Status", state);
+ }
}
diff --git a/src/Thresholds.cpp b/src/Thresholds.cpp
index 36556cf..a15da17 100644
--- a/src/Thresholds.cpp
+++ b/src/Thresholds.cpp
@@ -247,7 +247,7 @@
bool checkThresholds(Sensor* sensor)
{
- bool status = false;
+ bool status = true;
std::vector<std::pair<Threshold, bool>> changes =
checkThresholds(sensor, sensor->value);
for (const auto& [threshold, asserted] : changes)
@@ -256,7 +256,7 @@
asserted);
if (threshold.level == thresholds::Level::CRITICAL && asserted)
{
- status = true;
+ status = false;
}
}