diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-06-14 21:14:32 -0400 |
---|---|---|
committer | Patrick Williams <patrick@stwcx.xyz> | 2017-08-02 20:18:19 +0000 |
commit | bfb8160710d95d208f7cb1565a97c2a909459d0c (patch) | |
tree | 12de3b1a97421b70abd4761ac23015fd5caf6646 /presence | |
parent | 5c5894878b09fdef8fcbee000f83283b73b8da64 (diff) | |
download | phosphor-fan-presence-bfb8160710d95d208f7cb1565a97c2a909459d0c.tar.gz phosphor-fan-presence-bfb8160710d95d208f7cb1565a97c2a909459d0c.zip |
presence: Add fallback redundancy policy
Add a fallback redundancy implementation of the RedundancyPolicy
interface.
The fallback policy associates multiple PresenceSensor instances
to a single fan, and "falls-back" on secondary sensor implementations
when the primary sensor cannot see the fan.
Change-Id: I6468d77d97b8916b3ff33bcd0cd28a102d1aaba1
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'presence')
-rw-r--r-- | presence/Makefile.am | 1 | ||||
-rw-r--r-- | presence/fallback.cpp | 101 | ||||
-rw-r--r-- | presence/fallback.hpp | 79 |
3 files changed, 181 insertions, 0 deletions
diff --git a/presence/Makefile.am b/presence/Makefile.am index 2a5976c..33f13a3 100644 --- a/presence/Makefile.am +++ b/presence/Makefile.am @@ -5,6 +5,7 @@ sbin_PROGRAMS = \ phosphor-fan-presence-tach phosphor_fan_presence_tach_SOURCES = \ + fallback.cpp \ fan.cpp \ gpio.cpp \ tach.cpp \ diff --git a/presence/fallback.cpp b/presence/fallback.cpp new file mode 100644 index 0000000..625d74a --- /dev/null +++ b/presence/fallback.cpp @@ -0,0 +1,101 @@ +/** + * Copyright © 2017 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 <algorithm> +#include <phosphor-logging/log.hpp> +#include "fan.hpp" +#include "fallback.hpp" +#include "psensor.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +void Fallback::stateChanged(bool present) +{ + if (!present) + { + // Starting with the first backup, find the first + // sensor that reports the fan as present, if any. + auto it = std::find_if( + std::next(activeSensor), + sensors.end(), + [](auto& s){return s.get().present();}); + + if (it != sensors.end()) + { + // A backup sensor disagrees with the active sensor. + // Switch to the backup. + activeSensor->get().stop(); + present = it->get().start(); + + while (activeSensor != it) + { + // Callout the broken sensors. + activeSensor->get().fail(); + ++activeSensor; + } + phosphor::logging::log<phosphor::logging::level::INFO>( + "Using backup presence sensor.", + phosphor::logging::entry( + "FAN=%s", std::get<1>(fan))); + activeSensor = it; + } + } + + setPresence(fan, present); +} + +void Fallback::monitor() +{ + // Find the first sensor that says the fan is present + // and set it as the active sensor. + activeSensor = std::find_if( + sensors.begin(), + sensors.end(), + [](auto& s){return s.get().present();}); + if (activeSensor == sensors.end()) + { + // The first sensor is working or all sensors + // agree the fan isn't present. Use the first sensor. + activeSensor = sensors.begin(); + } + + if (activeSensor != sensors.begin()) + { + phosphor::logging::log<phosphor::logging::level::INFO>( + "Using backup presence sensor.", + phosphor::logging::entry( + "FAN=%s", std::get<1>(fan))); + } + + // Callout the broken sensors. + auto it = sensors.begin(); + while (it != activeSensor) + { + it->get().fail(); + ++it; + } + + // Start the active sensor and set the initial state. + setPresence(fan, activeSensor->get().start()); +} + +} // namespace presence +} // namespace fan +} // namespace phosphor diff --git a/presence/fallback.hpp b/presence/fallback.hpp new file mode 100644 index 0000000..a1a5b29 --- /dev/null +++ b/presence/fallback.hpp @@ -0,0 +1,79 @@ +#pragma once + +#include <functional> +#include <vector> +#include "fan.hpp" +#include "rpolicy.hpp" + +namespace phosphor +{ +namespace fan +{ +namespace presence +{ + +class PresenceSensor; + +/** + * @class Fallback + * @brief Fallback redundancy policy. + * + * The fallback redundancy policy falls back to + * subsequent presence sensors when the active + * sensor indicates not present and a fallback + * sensor indicates the fan is present. + */ +class Fallback : public RedundancyPolicy +{ + public: + Fallback() = delete; + Fallback(const Fallback&) = default; + Fallback& operator=(const Fallback&) = default; + Fallback(Fallback&&) = default; + Fallback& operator=(Fallback&&) = default; + ~Fallback() = default; + + /** + * @brief Construct a fallback policy. + * + * @param[in] fan - The fan associated with the policy. + * @param[in] s - The set of sensors associated with the policy. + */ + Fallback( + const Fan& fan, + const std::vector<std::reference_wrapper<PresenceSensor>>& s) : + RedundancyPolicy(fan), sensors(s) + { + activeSensor = sensors.begin(); + } + + /** + * @brief stateChanged + * + * Update the inventory and execute the fallback + * policy. + * + * @param[in] present - The new presence state according + * to the active sensor. + */ + void stateChanged(bool present) override; + + /** + * @brief monitor + * + * Start monitoring the fan. + */ + void monitor() override; + + private: + + /** @brief All presence sensors in the redundancy set. */ + std::vector<std::reference_wrapper<PresenceSensor>> sensors; + + /** @brief The active presence sensor. */ + decltype(sensors)::iterator activeSensor; +}; + +} // namespace presence +} // namespace fan +} // namespace phosphor |