summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorJames Feist <james.feist@linux.intel.com>2018-10-05 15:39:01 -0700
committerPatrick Venture <venture@google.com>2018-10-15 16:22:47 +0000
commit36b7d8ebbbbdf3a57884ed5d9474e1122b69b5c2 (patch)
tree43eaf24b2e9d2827df921bcc3c49c21a656f201b /dbus
parent0771659e1253b36d825664f4295f9d13cdd5e320 (diff)
downloadphosphor-pid-control-36b7d8ebbbbdf3a57884ed5d9474e1122b69b5c2.tar.gz
phosphor-pid-control-36b7d8ebbbbdf3a57884ed5d9474e1122b69b5c2.zip
[dbus-passive] Add threshold fan failure
When a threshold is crossed for a monitored sensor, assert fan failure. Tested-by: Changed a sensor threshold so that its current reading made the threshold asserted and noticed via print messages that the sensor went into failure state. Also noticed fans ramp. Wrote unit test to verify sensor can move in and out of error state correctly. Change-Id: I83182536e4874eaba97f3f1d48d53ac110fba833 Signed-off-by: James Feist <james.feist@linux.intel.com>
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbuspassive.cpp40
-rw-r--r--dbus/dbuspassive.hpp3
-rw-r--r--dbus/util.cpp47
-rw-r--r--dbus/util.hpp23
4 files changed, 111 insertions, 2 deletions
diff --git a/dbus/dbuspassive.cpp b/dbus/dbuspassive.cpp
index 702bf8d..a43b024 100644
--- a/dbus/dbuspassive.cpp
+++ b/dbus/dbuspassive.cpp
@@ -58,6 +58,7 @@ DbusPassive::DbusPassive(sdbusplus::bus::bus& bus, const std::string& type,
_scale = settings.scale;
_value = settings.value * pow(10, _scale);
_updated = std::chrono::high_resolution_clock::now();
+ _failed = _helper->ThresholdsAsserted(tempBus, service, path);
}
ReadReturn DbusPassive::read(void)
@@ -77,6 +78,16 @@ void DbusPassive::setValue(double value)
_updated = std::chrono::high_resolution_clock::now();
}
+bool DbusPassive::getFailed(void) const
+{
+ return _failed;
+}
+
+void DbusPassive::setFailed(bool value)
+{
+ _failed = value;
+}
+
int64_t DbusPassive::getScale(void)
{
return _scale;
@@ -90,7 +101,8 @@ std::string DbusPassive::getId(void)
int HandleSensorValue(sdbusplus::message::message& msg, DbusPassive* owner)
{
std::string msgSensor;
- std::map<std::string, sdbusplus::message::variant<int64_t, double>> msgData;
+ std::map<std::string, sdbusplus::message::variant<int64_t, double, bool>>
+ msgData;
msg.read(msgSensor, msgData);
@@ -107,6 +119,32 @@ int HandleSensorValue(sdbusplus::message::message& msg, DbusPassive* owner)
owner->setValue(value);
}
}
+ else if (msgSensor == "xyz.openbmc_project.Sensor.Threshold.Critical")
+ {
+ auto criticalAlarmLow = msgData.find("CriticalAlarmLow");
+ auto criticalAlarmHigh = msgData.find("CriticalAlarmHigh");
+ if (criticalAlarmHigh == msgData.end() &&
+ criticalAlarmLow == msgData.end())
+ {
+ return 0;
+ }
+
+ bool asserted = false;
+ if (criticalAlarmLow != msgData.end())
+ {
+ asserted = sdbusplus::message::variant_ns::get<bool>(
+ criticalAlarmLow->second);
+ }
+
+ // checking both as in theory you could de-assert one threshold and
+ // assert the other at the same moment
+ if (!asserted && criticalAlarmHigh != msgData.end())
+ {
+ asserted = sdbusplus::message::variant_ns::get<bool>(
+ criticalAlarmHigh->second);
+ }
+ owner->setFailed(asserted);
+ }
return 0;
}
diff --git a/dbus/dbuspassive.hpp b/dbus/dbuspassive.hpp
index 87315a0..71ef339 100644
--- a/dbus/dbuspassive.hpp
+++ b/dbus/dbuspassive.hpp
@@ -41,8 +41,10 @@ class DbusPassive : public ReadInterface
const std::string& id, DbusHelperInterface* helper);
ReadReturn read(void) override;
+ bool getFailed(void) const override;
void setValue(double value);
+ void setFailed(bool value);
int64_t getScale(void);
std::string getId(void);
@@ -55,6 +57,7 @@ class DbusPassive : public ReadInterface
std::mutex _lock;
double _value = 0;
+ bool _failed = false;
/* The last time the value was refreshed, not necessarily changed. */
std::chrono::high_resolution_clock::time_point _updated;
};
diff --git a/dbus/util.cpp b/dbus/util.cpp
index 0d107ab..cdc4bb9 100644
--- a/dbus/util.cpp
+++ b/dbus/util.cpp
@@ -1,10 +1,11 @@
#include "dbus/util.hpp"
+#include <cmath>
#include <iostream>
#include <set>
using Property = std::string;
-using Value = sdbusplus::message::variant<int64_t, double, std::string>;
+using Value = sdbusplus::message::variant<int64_t, double, std::string, bool>;
using PropertyMap = std::map<Property, Value>;
/* TODO(venture): Basically all phosphor apps need this, maybe it should be a
@@ -89,6 +90,50 @@ void DbusHelper::GetProperties(sdbusplus::bus::bus& bus,
return;
}
+bool DbusHelper::ThresholdsAsserted(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& path)
+{
+
+ auto critical = bus.new_method_call(service.c_str(), path.c_str(),
+ propertiesintf.c_str(), "GetAll");
+ critical.append(criticalThreshInf);
+ PropertyMap criticalMap;
+
+ try
+ {
+ auto msg = bus.call(critical);
+ if (!msg.is_method_error())
+ {
+ msg.read(criticalMap);
+ }
+ }
+ catch (sdbusplus::exception_t&)
+ {
+ // do nothing, sensors don't have to expose critical thresholds
+ return false;
+ }
+
+ auto findCriticalLow = criticalMap.find("CriticalAlarmLow");
+ auto findCriticalHigh = criticalMap.find("CriticalAlarmHigh");
+
+ bool asserted = false;
+ if (findCriticalLow != criticalMap.end())
+ {
+ asserted =
+ sdbusplus::message::variant_ns::get<bool>(findCriticalLow->second);
+ }
+
+ // as we are catching properties changed, a sensor could theoretically jump
+ // from one threshold to the other in one event, so check both thresholds
+ if (!asserted && findCriticalHigh != criticalMap.end())
+ {
+ asserted =
+ sdbusplus::message::variant_ns::get<bool>(findCriticalHigh->second);
+ }
+ return asserted;
+}
+
std::string GetSensorPath(const std::string& type, const std::string& id)
{
std::string layer = type;
diff --git a/dbus/util.hpp b/dbus/util.hpp
index e459524..ed7a411 100644
--- a/dbus/util.hpp
+++ b/dbus/util.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <limits>
#include <sdbusplus/bus.hpp>
struct SensorProperties
@@ -9,7 +10,15 @@ struct SensorProperties
std::string unit;
};
+struct SensorThresholds
+{
+ double lowerThreshold = std::numeric_limits<double>::quiet_NaN();
+ double upperThreshold = std::numeric_limits<double>::quiet_NaN();
+};
+
const std::string sensorintf = "xyz.openbmc_project.Sensor.Value";
+const std::string criticalThreshInf =
+ "xyz.openbmc_project.Sensor.Threshold.Critical";
const std::string propertiesintf = "org.freedesktop.DBus.Properties";
class DbusHelperInterface
@@ -34,6 +43,16 @@ class DbusHelperInterface
const std::string& service,
const std::string& path,
struct SensorProperties* prop) = 0;
+
+ /** @brief Get Critical Threshold current assert status
+ *
+ * @param[in] bus - A bus to use for the call.
+ * @param[in] service - The service providing the interface.
+ * @param[in] path - The dbus path.
+ */
+ virtual bool ThresholdsAsserted(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& path) = 0;
};
class DbusHelper : public DbusHelperInterface
@@ -52,6 +71,10 @@ class DbusHelper : public DbusHelperInterface
void GetProperties(sdbusplus::bus::bus& bus, const std::string& service,
const std::string& path,
struct SensorProperties* prop) override;
+
+ bool ThresholdsAsserted(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& path) override;
};
std::string GetSensorPath(const std::string& type, const std::string& id);
OpenPOWER on IntegriCloud