presence: Create ErrorReporter class
This class will, eventually, create event logs for missing fans.
This first commit will just create a stubbed out class if there is a
'reporting' section in the configuration JSON. From the JSON, the class
will pull out the value for the number of seconds to wait between first
detecting a fan is missing and creating the event log for it.
This requires a slight change to the existing JSON format, however the
JsonConfig class was updated to support both the old and new formats.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I991ea7cf0457448411e65f4c8e274bb2584d15f4
diff --git a/presence/Makefile.am b/presence/Makefile.am
index 2f1d787..a26fac9 100644
--- a/presence/Makefile.am
+++ b/presence/Makefile.am
@@ -6,6 +6,7 @@
phosphor_fan_presence_tach_SOURCES = \
anyof.cpp \
+ error_reporter.cpp \
fallback.cpp \
fan.cpp \
gpio.cpp \
diff --git a/presence/error_reporter.cpp b/presence/error_reporter.cpp
new file mode 100644
index 0000000..7ff71ae
--- /dev/null
+++ b/presence/error_reporter.cpp
@@ -0,0 +1,49 @@
+/**
+ * Copyright © 2020 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "error_reporter.hpp"
+
+#include <phosphor-logging/log.hpp>
+
+namespace phosphor::fan::presence
+{
+
+using json = nlohmann::json;
+using namespace phosphor::logging;
+
+ErrorReporter::ErrorReporter(
+ sdbusplus::bus::bus& bus, const json& jsonConf,
+ const std::vector<
+ std::tuple<Fan, std::vector<std::unique_ptr<PresenceSensor>>>>& fans) :
+ _bus(bus)
+{
+ loadConfig(jsonConf);
+}
+
+void ErrorReporter::loadConfig(const json& jsonConf)
+{
+ if (!jsonConf.contains("fan_missing_error_time"))
+ {
+ log<level::ERR>("Missing 'fan_missing_error_time' entry in JSON "
+ "'reporting' section");
+
+ throw std::runtime_error("Missing fan missing time entry in JSON");
+ }
+
+ _fanMissingErrorTime = std::chrono::seconds{
+ jsonConf.at("fan_missing_error_time").get<std::size_t>()};
+}
+
+} // namespace phosphor::fan::presence
diff --git a/presence/error_reporter.hpp b/presence/error_reporter.hpp
new file mode 100644
index 0000000..251aa7e
--- /dev/null
+++ b/presence/error_reporter.hpp
@@ -0,0 +1,67 @@
+#pragma once
+
+#include "fan.hpp"
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/bus.hpp>
+
+namespace phosphor::fan::presence
+{
+class PresenceSensor;
+
+/**
+ * @class ErrorReporter
+ *
+ * This class will create event logs for missing fans. The logs are
+ * created after a fan has been missing for an amount of time
+ * specified in the JSON config file while power is on.
+ *
+ * The timers to create event logs are not started when power is off.
+ * When power is turned on, the timers for any missing fans will be
+ * be started. If any timers are running when power is turned off,
+ * they will be stopped.
+ */
+class ErrorReporter
+{
+ public:
+ ErrorReporter() = delete;
+ ~ErrorReporter() = default;
+ ErrorReporter(const ErrorReporter&) = delete;
+ ErrorReporter& operator=(const ErrorReporter&) = delete;
+ ErrorReporter(ErrorReporter&&) = delete;
+ ErrorReporter& operator=(ErrorReporter&&) = delete;
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] bus - The sdbusplus bus object
+ * @param[in] jsonConf - The 'reporting' section of the JSON config file
+ * @param[in] fans - The fans for this configuration
+ */
+ ErrorReporter(
+ sdbusplus::bus::bus& bus, const nlohmann::json& jsonConf,
+ const std::vector<
+ std::tuple<Fan, std::vector<std::unique_ptr<PresenceSensor>>>>&
+ fans);
+
+ private:
+ /**
+ * @brief Reads in the configuration from the JSON section
+ *
+ * @param[in] jsonConf - The 'reporting' section of the JSON
+ */
+ void loadConfig(const nlohmann::json& jsonConf);
+
+ /**
+ * @brief Reference to the D-Bus connection object.
+ */
+ sdbusplus::bus::bus& _bus;
+
+ /**
+ * @brief The amount of time in seconds that a fan must be missing
+ * before an event log is created for it.
+ */
+ std::chrono::seconds _fanMissingErrorTime;
+};
+
+} // namespace phosphor::fan::presence
diff --git a/presence/example/example.json b/presence/example/example.json
index 6d77c81..25c77cc 100644
--- a/presence/example/example.json
+++ b/presence/example/example.json
@@ -1,72 +1,81 @@
-[
- {
- "name": "Example Fan0",
- "description": "'Example fan with tach feedback detection method. Fans without any special presence detection hardware can use one or more tach speed sensor feedbacks as an indicator of presence. Listed sensors are expected to be found in the /xyz/openbmc_project/sensors/fan_tach namespace as required by the OpenBMC DBus API. Supported policy types are fallback or anyof.'",
- "path": "/system/chassis/motherboard/fan0",
- "methods": [
- {
- "type": "tach",
- "sensors": [
- "fan0"
+{
+ "fans":
+ [
+ {
+ "name": "Example Fan0",
+ "description": "'Example fan with tach feedback detection method. Fans without any special presence detection hardware can use one or more tach speed sensor feedbacks as an indicator of presence. Listed sensors are expected to be found in the /xyz/openbmc_project/sensors/fan_tach namespace as required by the OpenBMC DBus API. Supported policy types are fallback or anyof.'",
+ "path": "/system/chassis/motherboard/fan0",
+ "methods": [
+ {
+ "type": "tach",
+ "sensors": [
+ "fan0"
+ ]
+ }
]
- }
- ]
- },
- {
- "name": "Example Fan1",
- "description": "'Example fan with gpio detection method. Fans with dedicated gpios can use the gpio detection method. The gpio detection uses Linux gpio-keys: the event number must be provided via the key property.'",
- "path": "/system/chassis/motherboard/fan1",
- "methods": [
- {
- "type": "gpio",
- "key": 123,
- "physpath": "/sys/devices/foo/bar",
- "devpath": "/dev/input/by-path/platform-gpio-keys-event"
- }
- ]
- },
- {
- "name": "Example Fan2",
- "description": "'Example fan with fallback redundancy policy. Multiple detection methods for a single fan are allowed. When multiple detection methods are provided a redundancy algorithm must be specified with the rpolicy attribute. Note that the redundancy policy algorithm may or may not factor the order the detection methods are listed into its logic. The fallback algorithm falls back to subsequently listed detection methods when the first method does not detect a fan and the second method does.'",
- "path": "/system/chassis/motherboard/fan2",
- "methods": [
- {
- "type": "gpio",
- "key": 124,
- "physpath": "/sys/devices/foo/bar",
- "devpath": "/dev/input/by-path/platform-gpio-keys-polled-event"
- },
- {
- "type": "tach",
- "sensors": [
- "fan2"
+ },
+ {
+ "name": "Example Fan1",
+ "description": "'Example fan with gpio detection method. Fans with dedicated gpios can use the gpio detection method. The gpio detection uses Linux gpio-keys: the event number must be provided via the key property.'",
+ "path": "/system/chassis/motherboard/fan1",
+ "methods": [
+ {
+ "type": "gpio",
+ "key": 123,
+ "physpath": "/sys/devices/foo/bar",
+ "devpath": "/dev/input/by-path/platform-gpio-keys-event"
+ }
]
- }
- ],
- "rpolicy": {
- "type": "fallback"
- }
- },
- {
- "name": "Example Fan3",
- "description": "'Example fan with anyof redundancy policy. The anyof algorithm reports true if any redundancy set component sensors report true.'",
- "path": "/system/chassis/motherboard/fan3",
- "methods": [
- {
- "type": "gpio",
- "key": 125,
- "physpath": "/sys/devices/foo/bar",
- "devpath": "/dev/input/by-path/platform-gpio-keys-polled-event"
- },
- {
- "type": "tach",
- "sensors": [
- "fan3"
- ]
- }
- ],
- "rpolicy": {
- "type": "anyof"
- }
- }
-]
+ },
+ {
+ "name": "Example Fan2",
+ "description": "'Example fan with fallback redundancy policy. Multiple detection methods for a single fan are allowed. When multiple detection methods are provided a redundancy algorithm must be specified with the rpolicy attribute. Note that the redundancy policy algorithm may or may not factor the order the detection methods are listed into its logic. The fallback algorithm falls back to subsequently listed detection methods when the first method does not detect a fan and the second method does.'",
+ "path": "/system/chassis/motherboard/fan2",
+ "methods": [
+ {
+ "type": "gpio",
+ "key": 124,
+ "physpath": "/sys/devices/foo/bar",
+ "devpath": "/dev/input/by-path/platform-gpio-keys-polled-event"
+ },
+ {
+ "type": "tach",
+ "sensors": [
+ "fan2"
+ ]
+ }
+ ],
+ "rpolicy": {
+ "type": "fallback"
+ }
+ },
+ {
+ "name": "Example Fan3",
+ "description": "'Example fan with anyof redundancy policy. The anyof algorithm reports true if any redundancy set component sensors report true.'",
+ "path": "/system/chassis/motherboard/fan3",
+ "methods": [
+ {
+ "type": "gpio",
+ "key": 125,
+ "physpath": "/sys/devices/foo/bar",
+ "devpath": "/dev/input/by-path/platform-gpio-keys-polled-event"
+ },
+ {
+ "type": "tach",
+ "sensors": [
+ "fan3"
+ ]
+ }
+ ],
+ "rpolicy": {
+ "type": "anyof"
+ }
+ }
+ ],
+
+ "reporting":
+ {
+ "description": "'The amount of time, in seconds, that a fan must be missing before an event log is created.'",
+ "fan_missing_error_time": 10
+ }
+}
diff --git a/presence/json_parser.cpp b/presence/json_parser.cpp
index 83267a7..23420b6 100644
--- a/presence/json_parser.cpp
+++ b/presence/json_parser.cpp
@@ -88,11 +88,25 @@
{
policies policies;
std::vector<fanPolicy> fans;
+ const json* fanJSON;
+
+ // The original JSON had the fan array at the root, but the new JSON
+ // has it under a 'fans' element. Support both.
+ // This can be removed after the new JSON is in the image.
+ if (jsonConf.is_array())
+ {
+ fanJSON = &jsonConf;
+ }
+ else
+ {
+ fanJSON = &jsonConf["fans"];
+ }
+
// Set the expected number of fan entries
// to be size of the list of fan json config entries
// (Must be done to eliminate vector reallocation of fan references)
- fans.reserve(jsonConf.size());
- for (auto& member : jsonConf)
+ fans.reserve(fanJSON->size());
+ for (auto& member : *fanJSON)
{
if (!member.contains("name") || !member.contains("path") ||
!member.contains("methods") || !member.contains("rpolicy"))
@@ -159,6 +173,13 @@
_policies.clear();
_policies.swap(policies);
+
+ // Create the error reporter class if necessary
+ if (jsonConf.contains("reporting"))
+ {
+ _reporter = std::make_unique<ErrorReporter>(
+ _bus, jsonConf.at("reporting"), _fans);
+ }
}
std::unique_ptr<RedundancyPolicy>
diff --git a/presence/json_parser.hpp b/presence/json_parser.hpp
index 9d99a40..38c76b9 100644
--- a/presence/json_parser.hpp
+++ b/presence/json_parser.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "error_reporter.hpp"
#include "fan.hpp"
#include "psensor.hpp"
#include "rpolicy.hpp"
@@ -94,6 +95,11 @@
static const std::map<std::string, rpolicyHandler> _rpolicies;
/**
+ * Class that handles reporting errors for missing fans.
+ */
+ std::unique_ptr<ErrorReporter> _reporter;
+
+ /**
* @brief Process the json config to extract the defined fan presence
* policies.
*