From 81748b1425e453b6a815a7b8ed2fa861d3068ac7 Mon Sep 17 00:00:00 2001 From: Matthew Barth Date: Wed, 2 May 2018 16:03:48 -0500 Subject: Support optional conditions on creating fans This adds the functional infrastructure to optionally attach a condition function to a fan definition. When a condition is defined on a fan, it must be true for a fan's associated functional properties to be created. When the given condition fails, that fan's functional properties will not be created by fan monitor. A fan without a defined condition will have all of its associated functional properties created. Example of generated condition (generation commit to follow): make_condition(condition::propertiesMatch( std::vector{ PropertyState{ PropertyIdentity{ "/xyz/openbmc_project/inventory/system/chassis", "xyz.openbmc_project.Inventory.Decorator.CoolingType", "WaterCooled" }, static_cast(false) } } )), Tested: Fan functional properties are not created when a condition fails Fan functional properties are created when condition passes Fan functional properties are created when no condition exists Change-Id: I9ced2e520d2f97e6655c9417970b3e976d78fef4 Signed-off-by: Matthew Barth --- monitor/Makefile.am | 3 ++- monitor/conditions.cpp | 35 +++++++++++++++++++++++++++++++++++ monitor/conditions.hpp | 43 +++++++++++++++++++++++++++++++++++++++++++ monitor/main.cpp | 10 ++++++++++ monitor/types.hpp | 22 +++++++++++++++++++++- 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 monitor/conditions.cpp create mode 100644 monitor/conditions.hpp diff --git a/monitor/Makefile.am b/monitor/Makefile.am index 8eda1e0..bea0933 100644 --- a/monitor/Makefile.am +++ b/monitor/Makefile.am @@ -8,7 +8,8 @@ phosphor_fan_monitor_SOURCES = \ argument.cpp \ fan.cpp \ main.cpp \ - tach_sensor.cpp + tach_sensor.cpp \ + conditions.cpp nodist_phosphor_fan_monitor_SOURCES = \ fan_monitor_defs.cpp diff --git a/monitor/conditions.cpp b/monitor/conditions.cpp new file mode 100644 index 0000000..c046f0c --- /dev/null +++ b/monitor/conditions.cpp @@ -0,0 +1,35 @@ +#include +#include "conditions.hpp" +#include "sdbusplus.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace monitor +{ +namespace condition +{ + +Condition propertiesMatch(std::vector&& propStates) +{ + return [pStates = std::move(propStates)](sdbusplus::bus::bus& bus) + { + return std::all_of( + pStates.begin(), + pStates.end(), + [&bus](const auto& p) + { + return util::SDBusPlus::getPropertyVariant( + bus, + std::get(p.first), + std::get(p.first), + std::get(p.first)) == p.second; + }); + }; +} + +} // namespace condition +} // namespace monitor +} // namespace fan +} // namespace phosphor diff --git a/monitor/conditions.hpp b/monitor/conditions.hpp new file mode 100644 index 0000000..76aa0de --- /dev/null +++ b/monitor/conditions.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include "types.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace monitor +{ + +/** + * @brief Create a condition function object + * + * @param[in] condition - The condition being created + * + * @return - The created condition function object + */ +template +auto make_condition(T&& condition) +{ + return Condition(std::forward(condition)); +} + +namespace condition +{ + +/** + * @brief A condition that checks all properties match the given values + * @details Checks each property entry against its given value where all + * property values must match their given value for the condition to pass + * + * @param[in] propStates - List of property identifiers and their value + * + * @return Condition lambda function + * A Condition function that checks all properties match + */ +Condition propertiesMatch(std::vector&& propStates); + +} // namespace condition +} // namespace monitor +} // namespace fan +} // namespace phosphor diff --git a/monitor/main.cpp b/monitor/main.cpp index 060f27a..84dd7d1 100644 --- a/monitor/main.cpp +++ b/monitor/main.cpp @@ -72,6 +72,16 @@ int main(int argc, char* argv[]) for (const auto& fanDef : fanDefinitions) { + // Check if a condition exists on the fan + auto condition = std::get(fanDef); + if (condition) + { + // Condition exists, skip adding fan if it fails + if (!(*condition)(bus)) + { + continue; + } + } fans.emplace_back(std::make_unique( mode, bus, eventPtr, trust, fanDef)); } diff --git a/monitor/types.hpp b/monitor/types.hpp index 3d8306d..9a7b1fa 100644 --- a/monitor/types.hpp +++ b/monitor/types.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "trust_group.hpp" namespace phosphor @@ -13,6 +14,23 @@ namespace fan namespace monitor { +constexpr auto propObj = 0; +constexpr auto propIface = 1; +constexpr auto propName = 2; +using PropertyIdentity = std::tuple; + +using PropertyValue = sdbusplus::message::variant; +constexpr auto propIdentity = 0; +constexpr auto propValue = 1; +using PropertyState = std::pair; + +using Condition = std::function; + using CreateGroupFunction = std::function()>; @@ -34,13 +52,15 @@ constexpr auto timeoutField = 2; constexpr auto fanDeviationField = 3; constexpr auto numSensorFailsForNonfuncField = 4; constexpr auto sensorListField = 5; +constexpr auto conditionField = 6; using FanDefinition = std::tuple>; + std::vector, + std::experimental::optional>; } } -- cgit v1.2.1