/** * 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. */ #pragma once #include "fan.hpp" #include "fan_error.hpp" #include "power_off_rule.hpp" #include "power_state.hpp" #include "tach_sensor.hpp" #include "trust_manager.hpp" #include "types.hpp" #include #include #include #include #include #include #include namespace phosphor::fan::monitor { using json = nlohmann::json; // Mapping from service name to sensor using SensorMapType = std::map>>; class System { public: System() = delete; ~System() = default; System(const System&) = delete; System(System&&) = delete; System& operator=(const System&) = delete; System& operator=(System&&) = delete; /** * Constructor * * @param[in] mode - mode of fan monitor * @param[in] bus - sdbusplus bus object * @param[in] event - event loop reference */ System(Mode mode, sdbusplus::bus::bus& bus, const sdeventplus::Event& event); /** * @brief Callback function to handle receiving a HUP signal to reload the * JSON configuration. */ void sighupHandler(sdeventplus::source::Signal&, const struct signalfd_siginfo*); /** * @brief Called from the fan when it changes either * present or functional status to update the * fan health map. * * @param[in] fan - The fan that changed * @param[in] skipRulesCheck - If the rules checks should be done now. */ void fanStatusChange(const Fan& fan, bool skipRulesCheck = false); /** * @brief Called when a fan sensor's error timer expires, which * happens when the sensor has been nonfunctional for a * certain amount of time. An event log will be created. * * @param[in] fan - The parent fan of the sensor * @param[in] sensor - The faulted sensor */ void sensorErrorTimerExpired(const Fan& fan, const TachSensor& sensor); /** * @brief Called when the timer that starts when a fan is missing * has expired so an event log needs to be created. * * @param[in] fan - The missing fan. */ void fanMissingErrorTimerExpired(const Fan& fan); /** * @brief Called by the power off actions to log an error when there is * a power off due to fan problems. * * The error it logs is just the last fan error that occurred. */ void logShutdownError(); /** * @brief Returns true if power is on */ bool isPowerOn() const { return _powerState->isPowerOn(); } /** * @brief tests the presence of Inventory and calls load() if present, else * waits for Inventory asynchronously and has a callback to load() when * present */ void start(); /** * @brief Parses and populates the fan monitor trust groups and list of fans */ void load(); private: /** * @brief Callback from D-Bus when Inventory service comes online * * @param[in] msg - Service details. */ void inventoryOnlineCb(sdbusplus::message::message& msg); /* The mode of fan monitor */ Mode _mode; /* The sdbusplus bus object */ sdbusplus::bus::bus& _bus; /* The event loop reference */ const sdeventplus::Event& _event; /* Trust manager of trust groups */ std::unique_ptr _trust; /* match object to detect Inventory service */ std::unique_ptr _inventoryMatch; /* List of fan objects to monitor */ std::vector> _fans; /** * @brief The latest health of all the fans */ FanHealth _fanHealth; /** * @brief The object to watch the power state */ std::unique_ptr _powerState; /** * @brief The power off rules, for shutting down the system * due to fan failures. */ std::vector> _powerOffRules; /** * @brief The number of concurrently nonfunctional fan sensors * there must be for an event log created due to a * nonfunctional fan sensor to have an Error severity as * opposed to an Informational one. */ std::optional _numNonfuncSensorsBeforeError; /** * @brief The most recently committed fan error. */ std::unique_ptr _lastError; /** * @brief The thermal alert D-Bus object */ ThermalAlertObject _thermalAlert; /** * @brief The tach sensors D-Bus match objects */ std::vector> _sensorMatch; /** * @brief true if config files have been loaded */ bool _loaded = false; /** * @brief Captures tach sensor data as JSON for use in * fan fault and fan missing event logs. * * @return json - The JSON data */ json captureSensorData(); /** * @brief creates a subscription (service->sensor) to take sensors * on/offline when D-Bus starts/stops updating values * */ void subscribeSensorsToServices(); /** * @brief Retrieve the configured trust groups * * @param[in] jsonObj - JSON object to parse from * * @return List of functions applied on trust groups */ const std::vector getTrustGroups(const json& jsonObj); /** * @brief Set the trust manager's list of trust group functions * * @param[in] groupFuncs - list of trust group functions */ void setTrustMgr(const std::vector& groupFuncs); /** * @brief Retrieve the configured fan definitions * * @param[in] jsonObj - JSON object to parse from * * @return List of fan definition data on the fans configured */ const std::vector getFanDefinitions(const json& jsonObj); /** * @brief Set the list of fans to be monitored * * @param[in] fanDefs - list of fan definitions to create fans monitored */ void setFans(const std::vector& fanDefs); /** * @brief Updates the fan health map entry for the fan passed in * * @param[in] fan - The fan to update the health map with */ void updateFanHealth(const Fan& fan); /** * @brief callback when a tach sensor signal goes offline * * @param[in] msg - D-Bus message containing details (inc. service name) * * @param[in] sensorMap - map providing sensor access for each service */ void tachSignalOffline(sdbusplus::message::message& msg, const SensorMapType& sensorMap); /** * @brief The function that runs when the power state changes * * @param[in] powerStateOn - If power is now on or not */ void powerStateChanged(bool powerStateOn); /** * @brief Reads the fault configuration from the JSON config * file, such as the power off rule configuration. * * @param[in] jsonObj - JSON object to parse from */ void setFaultConfig(const json& jsonObj); /** * @brief Log an error and shut down due to an offline fan controller */ void handleOfflineFanController(); }; } // namespace phosphor::fan::monitor