Read fan target sysfs value on startup
When creating the object that represents the
Control.FanSpeed interface for a fan, read the
target fan speed out of sysfs and save it in
the object so it shows up in D-Bus immediately.
Previously the Target property would have a value
of zero until another application wrote it, leaving
a window where the D-Bus property wouldn't match
the underlying sysfs file value.
Change-Id: I08b149840c2cf731bc48f89118622fa63222600e
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/fan_speed.hpp b/fan_speed.hpp
index 3203178..7fc303a 100644
--- a/fan_speed.hpp
+++ b/fan_speed.hpp
@@ -26,18 +26,20 @@
* @param[in] bus - Dbus bus object
* @param[in] objPath - Dbus object path
* @param[in] defer - Dbus object registration defer
+ * @param[in] target - initial target speed value
*/
FanSpeed(const std::string& instancePath,
const std::string& devPath,
const std::string& id,
sdbusplus::bus::bus& bus,
const char* objPath,
- bool defer) : FanSpeedObject(bus, objPath, defer),
+ bool defer,
+ uint64_t target) : FanSpeedObject(bus, objPath, defer),
id(id),
ioAccess(instancePath),
devPath(devPath)
{
- // Nothing to do here
+ FanSpeedObject::target(target);
}
/**
diff --git a/mainloop.cpp b/mainloop.cpp
index 1190d85..bf2cacc 100644
--- a/mainloop.cpp
+++ b/mainloop.cpp
@@ -346,7 +346,7 @@
addThreshold<CriticalObject>(i.first.first, id, sensorValue, info);
auto target = addTarget<hwmon::FanSpeed>(
- i.first, ioAccess.path(), _devPath, info);
+ i.first, ioAccess, _devPath, info);
if (target)
{
diff --git a/targets.hpp b/targets.hpp
index 863eae5..5e938b0 100644
--- a/targets.hpp
+++ b/targets.hpp
@@ -1,6 +1,9 @@
#pragma once
#include <experimental/filesystem>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Sensor/Device/error.hpp>
#include "fan_speed.hpp"
/** @class Targets
@@ -31,7 +34,8 @@
* @tparam T - The target type
*
* @param[in] sensor - A sensor type and name
- * @param[in] instance - The target instance path
+ * @param[in] ioAccess - hwmon sysfs access object
+ * @param[in] devPath - The /sys/devices sysfs path
* @param[in] info - The sdbusplus server connection and interfaces
*
* @return A shared pointer to the target interface object
@@ -39,7 +43,7 @@
*/
template <typename T>
std::shared_ptr<T> addTarget(const SensorSet::key_type& sensor,
- const std::string& instancePath,
+ const sysfs::hwmonio::HwmonIO& ioAccess,
const std::string& devPath,
ObjectInfo& info)
{
@@ -52,18 +56,48 @@
auto& objPath = std::get<std::string>(info);
// Check if target sysfs file exists
- auto sysfsFullPath = sysfs::make_sysfs_path(instancePath,
+ auto sysfsFullPath = sysfs::make_sysfs_path(ioAccess.path(),
sensor.first,
sensor.second,
hwmon::entry::target);
if (fs::exists(sysfsFullPath))
{
- target = std::make_shared<T>(instancePath,
+ uint32_t targetSpeed = 0;
+
+ try
+ {
+ targetSpeed = ioAccess.read(
+ sensor.first,
+ sensor.second,
+ hwmon::entry::target,
+ sysfs::hwmonio::retries,
+ sysfs::hwmonio::delay);
+
+ }
+ 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()));
+ }
+
+ target = std::make_shared<T>(ioAccess.path(),
devPath,
sensor.second,
bus,
objPath.c_str(),
- deferSignals);
+ deferSignals,
+ targetSpeed);
auto type = Targets<T>::type;
obj[type] = target;
}