Add status interface to sensors
When a fault sysfs file is present for a sensor, the OperationalStatus
interface is attached to the sensor object. The functional property is
initially set to the corresponding value read from the fault sysfs file
when the sensor object is created. A follow-up commit will address
updating the functional property based on reading the fault sysfs file
during the polling interval.
Tested:
OperationalStatus interface created for sensors with fault files
Interface not created for sensors without fault file
Functional property set to correct value from sensor's fault file
Change-Id: Id75b3711d048d4667d2173a3255512cf5482ab67
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index 0c26a6f..7e1cccb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,6 +26,7 @@
fan_pwm.cpp \
timer.cpp \
hwmon.cpp \
- hwmonio.cpp
+ hwmonio.cpp \
+ sensor.cpp
SUBDIRS = . msl test tools
diff --git a/hwmon.hpp b/hwmon.hpp
index 5319b69..5a7a90f 100644
--- a/hwmon.hpp
+++ b/hwmon.hpp
@@ -13,11 +13,13 @@
static constexpr auto clabel = "label";
static constexpr auto ctarget = "target";
static constexpr auto cenable = "enable";
+static constexpr auto cfault = "fault";
static const std::string input = cinput;
static const std::string label = clabel;
static const std::string target = ctarget;
static const std::string enable = cenable;
+static const std::string fault = cfault;
}
namespace type
diff --git a/interface.hpp b/interface.hpp
index da939c2..a2fa21f 100644
--- a/interface.hpp
+++ b/interface.hpp
@@ -5,6 +5,7 @@
#include "xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp"
#include "xyz/openbmc_project/Control/FanSpeed/server.hpp"
#include "xyz/openbmc_project/Control/FanPwm/server.hpp"
+#include "xyz/openbmc_project/State/Decorator/OperationalStatus/server.hpp"
#include <sdbusplus/server.hpp>
template <typename... T>
@@ -24,6 +25,9 @@
using FanPwmInterface =
sdbusplus::xyz::openbmc_project::Control::server::FanPwm;
using FanPwmObject = ServerObject<FanPwmInterface>;
+using StatusInterface =
+ sdbusplus::xyz::openbmc_project::State::Decorator::server::OperationalStatus;
+using StatusObject = ServerObject<StatusInterface>;
enum class InterfaceType
{
@@ -32,6 +36,7 @@
CRIT,
FAN_SPEED,
FAN_PWM,
+ STATUS,
};
// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
diff --git a/mainloop.cpp b/mainloop.cpp
index c18ae7f..a9898b7 100644
--- a/mainloop.cpp
+++ b/mainloop.cpp
@@ -33,6 +33,7 @@
#include "mainloop.hpp"
#include "targets.hpp"
#include "thresholds.hpp"
+#include "sensor.hpp"
#include <xyz/openbmc_project/Sensor/Device/error.hpp>
@@ -357,6 +358,9 @@
}
addTarget<hwmon::FanPwm>(sensor.first, ioAccess, _devPath, info);
+ // Add status interface based on _fault file being present
+ sensor::addStatus(sensor.first, ioAccess, _devPath, info);
+
// All the interfaces have been created. Go ahead
// and emit InterfacesAdded.
valueInterface->emit_object_added();
diff --git a/sensor.cpp b/sensor.cpp
new file mode 100644
index 0000000..cbcbfeb
--- /dev/null
+++ b/sensor.cpp
@@ -0,0 +1,83 @@
+#include <experimental/filesystem>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <xyz/openbmc_project/Sensor/Device/error.hpp>
+
+#include "sensor.hpp"
+#include "sensorset.hpp"
+#include "hwmon.hpp"
+#include "sysfs.hpp"
+
+namespace sensor
+{
+
+std::shared_ptr<StatusObject> addStatus(
+ const SensorSet::key_type& sensor,
+ const hwmonio::HwmonIO& ioAccess,
+ const std::string& devPath,
+ ObjectInfo& info)
+{
+ namespace fs = std::experimental::filesystem;
+
+ std::shared_ptr<StatusObject> iface = nullptr;
+ static constexpr bool deferSignals = true;
+ auto& bus = *std::get<sdbusplus::bus::bus*>(info);
+ auto& objPath = std::get<std::string>(info);
+ auto& obj = std::get<Object>(info);
+
+ // Check if fault sysfs file exists
+ std::string faultName = sensor.first;
+ std::string faultID = sensor.second;
+ std::string entry = hwmon::entry::fault;
+
+ auto sysfsFullPath = sysfs::make_sysfs_path(ioAccess.path(),
+ faultName,
+ faultID,
+ entry);
+ if (fs::exists(sysfsFullPath))
+ {
+ bool functional = true;
+ uint32_t fault = 0;
+ try
+ {
+ fault = ioAccess.read(faultName,
+ faultID,
+ entry,
+ hwmonio::retries,
+ hwmonio::delay);
+ if (fault != 0)
+ {
+ functional = false;
+ }
+ }
+ catch (const std::system_error& e)
+ {
+ using namespace phosphor::logging;
+ using namespace sdbusplus::xyz::openbmc_project::
+ Sensor::Device::Error;
+ using metadata = xyz::openbmc_project::Sensor::
+ Device::ReadFailure;
+
+ report<ReadFailure>(
+ metadata::CALLOUT_ERRNO(e.code().value()),
+ metadata::CALLOUT_DEVICE_PATH(devPath.c_str()));
+
+ log<level::INFO>("Logging failing sysfs file",
+ phosphor::logging::entry(
+ "FILE=%s", sysfsFullPath.c_str()));
+ }
+
+ iface = std::make_shared<StatusObject>(
+ bus,
+ objPath.c_str(),
+ deferSignals);
+ // Set functional property
+ iface->functional(functional);
+
+ obj[InterfaceType::STATUS] = iface;
+ }
+
+ return iface;
+}
+
+} // namespace sensor
diff --git a/sensor.hpp b/sensor.hpp
new file mode 100644
index 0000000..e22af0b
--- /dev/null
+++ b/sensor.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "sensorset.hpp"
+#include "mainloop.hpp"
+
+namespace sensor
+{
+
+/**
+ * @brief Add status interface and functional property for sensor
+ * @details When a sensor has an associated fault file, the OperationalStatus
+ * interface is added along with setting the Functional property to the
+ * corresponding value found in the fault file.
+ *
+ * @param[in] sensor - Sensor identification data
+ * @param[in] ioAccess - I/O access to sysfs
+ * @param[in] devPath - Device path
+ * @param[in] info - Sensor object information
+ *
+ * @return - Shared pointer to the status object
+ */
+std::shared_ptr<StatusObject> addStatus(
+ const SensorSet::key_type& sensor,
+ const hwmonio::HwmonIO& ioAccess,
+ const std::string& devPath,
+ ObjectInfo& info);
+
+} // namespace sensor