1c95c527aSMatthew Barth /** 2c95c527aSMatthew Barth * Copyright © 2020 IBM Corporation 3c95c527aSMatthew Barth * 4c95c527aSMatthew Barth * Licensed under the Apache License, Version 2.0 (the "License"); 5c95c527aSMatthew Barth * you may not use this file except in compliance with the License. 6c95c527aSMatthew Barth * You may obtain a copy of the License at 7c95c527aSMatthew Barth * 8c95c527aSMatthew Barth * http://www.apache.org/licenses/LICENSE-2.0 9c95c527aSMatthew Barth * 10c95c527aSMatthew Barth * Unless required by applicable law or agreed to in writing, software 11c95c527aSMatthew Barth * distributed under the License is distributed on an "AS IS" BASIS, 12c95c527aSMatthew Barth * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c95c527aSMatthew Barth * See the License for the specific language governing permissions and 14c95c527aSMatthew Barth * limitations under the License. 15c95c527aSMatthew Barth */ 16c95c527aSMatthew Barth #pragma once 17c95c527aSMatthew Barth 18c95c527aSMatthew Barth #include "fan.hpp" 19ac1efc11SMatt Spinler #include "fan_error.hpp" 20e892e39aSMatt Spinler #include "power_off_rule.hpp" 21e892e39aSMatt Spinler #include "power_state.hpp" 22c95c527aSMatthew Barth #include "tach_sensor.hpp" 23c95c527aSMatthew Barth #include "trust_manager.hpp" 24c95c527aSMatthew Barth #include "types.hpp" 25c95c527aSMatthew Barth 26c95c527aSMatthew Barth #include <nlohmann/json.hpp> 27c95c527aSMatthew Barth #include <sdbusplus/bus.hpp> 28c95c527aSMatthew Barth #include <sdeventplus/event.hpp> 29*4f472a86SMatt Spinler #include <sdeventplus/source/event.hpp> 30d06905c9SMatthew Barth #include <sdeventplus/source/signal.hpp> 31c95c527aSMatthew Barth 32c95c527aSMatthew Barth #include <memory> 33c95c527aSMatthew Barth #include <optional> 34c95c527aSMatthew Barth #include <vector> 35c95c527aSMatthew Barth 36c95c527aSMatthew Barth namespace phosphor::fan::monitor 37c95c527aSMatthew Barth { 38c95c527aSMatthew Barth 39c95c527aSMatthew Barth using json = nlohmann::json; 40c95c527aSMatthew Barth 41fdcd5db3SMike Capps // Mapping from service name to sensor 42fdcd5db3SMike Capps using SensorMapType = 43fdcd5db3SMike Capps std::map<std::string, std::set<std::shared_ptr<TachSensor>>>; 44fdcd5db3SMike Capps 45c95c527aSMatthew Barth class System 46c95c527aSMatthew Barth { 47c95c527aSMatthew Barth public: 48c95c527aSMatthew Barth System() = delete; 49ac1efc11SMatt Spinler ~System() = default; 50c95c527aSMatthew Barth System(const System&) = delete; 51c95c527aSMatthew Barth System(System&&) = delete; 52c95c527aSMatthew Barth System& operator=(const System&) = delete; 53c95c527aSMatthew Barth System& operator=(System&&) = delete; 54c95c527aSMatthew Barth 55c95c527aSMatthew Barth /** 56c95c527aSMatthew Barth * Constructor 57c95c527aSMatthew Barth * 58c95c527aSMatthew Barth * @param[in] mode - mode of fan monitor 59c95c527aSMatthew Barth * @param[in] bus - sdbusplus bus object 60c95c527aSMatthew Barth * @param[in] event - event loop reference 61c95c527aSMatthew Barth */ 62cb356d48SPatrick Williams System(Mode mode, sdbusplus::bus_t& bus, const sdeventplus::Event& event); 63c95c527aSMatthew Barth 64d06905c9SMatthew Barth /** 65d06905c9SMatthew Barth * @brief Callback function to handle receiving a HUP signal to reload the 66d06905c9SMatthew Barth * JSON configuration. 67d06905c9SMatthew Barth */ 68d06905c9SMatthew Barth void sighupHandler(sdeventplus::source::Signal&, 69d06905c9SMatthew Barth const struct signalfd_siginfo*); 70d06905c9SMatthew Barth 71b63aa09eSMatt Spinler /** 72b63aa09eSMatt Spinler * @brief Called from the fan when it changes either 73b63aa09eSMatt Spinler * present or functional status to update the 74b63aa09eSMatt Spinler * fan health map. 75b63aa09eSMatt Spinler * 76b63aa09eSMatt Spinler * @param[in] fan - The fan that changed 774283c5d5SMatt Spinler * @param[in] skipRulesCheck - If the rules checks should be done now. 78b63aa09eSMatt Spinler */ 794283c5d5SMatt Spinler void fanStatusChange(const Fan& fan, bool skipRulesCheck = false); 80b63aa09eSMatt Spinler 81f13b42e2SMatt Spinler /** 82f13b42e2SMatt Spinler * @brief Called when a fan sensor's error timer expires, which 83f13b42e2SMatt Spinler * happens when the sensor has been nonfunctional for a 84f13b42e2SMatt Spinler * certain amount of time. An event log will be created. 85f13b42e2SMatt Spinler * 86f13b42e2SMatt Spinler * @param[in] fan - The parent fan of the sensor 87f13b42e2SMatt Spinler * @param[in] sensor - The faulted sensor 88f13b42e2SMatt Spinler */ 89f13b42e2SMatt Spinler void sensorErrorTimerExpired(const Fan& fan, const TachSensor& sensor); 90f13b42e2SMatt Spinler 9127f6b686SMatt Spinler /** 9227f6b686SMatt Spinler * @brief Called when the timer that starts when a fan is missing 9327f6b686SMatt Spinler * has expired so an event log needs to be created. 9427f6b686SMatt Spinler * 9527f6b686SMatt Spinler * @param[in] fan - The missing fan. 9627f6b686SMatt Spinler */ 9727f6b686SMatt Spinler void fanMissingErrorTimerExpired(const Fan& fan); 9827f6b686SMatt Spinler 99ac1efc11SMatt Spinler /** 100ac1efc11SMatt Spinler * @brief Called by the power off actions to log an error when there is 101ac1efc11SMatt Spinler * a power off due to fan problems. 102ac1efc11SMatt Spinler * 103ac1efc11SMatt Spinler * The error it logs is just the last fan error that occurred. 104ac1efc11SMatt Spinler */ 105ac1efc11SMatt Spinler void logShutdownError(); 106ac1efc11SMatt Spinler 1077d135641SMatt Spinler /** 1087d135641SMatt Spinler * @brief Returns true if power is on 1097d135641SMatt Spinler */ isPowerOn() const1107d135641SMatt Spinler bool isPowerOn() const 1117d135641SMatt Spinler { 1127d135641SMatt Spinler return _powerState->isPowerOn(); 1137d135641SMatt Spinler } 1147d135641SMatt Spinler 1157d135641SMatt Spinler /** 116b4379a1eSMike Capps * @brief tests the presence of Inventory and calls load() if present, else 117b4379a1eSMike Capps * waits for Inventory asynchronously and has a callback to load() when 118b4379a1eSMike Capps * present 1197d135641SMatt Spinler */ 120823bc49eSMatthew Barth void start(); 1217d135641SMatt Spinler 122b4379a1eSMike Capps /** 123b4379a1eSMike Capps * @brief Parses and populates the fan monitor trust groups and list of fans 124b4379a1eSMike Capps */ 125b4379a1eSMike Capps void load(); 126b4379a1eSMike Capps 127*4f472a86SMatt Spinler /** 128*4f472a86SMatt Spinler * @brief Callback function to handle receiving a USR1 signal to dump 129*4f472a86SMatt Spinler * debug data to a file. 130*4f472a86SMatt Spinler */ 131*4f472a86SMatt Spinler void dumpDebugData(sdeventplus::source::Signal&, 132*4f472a86SMatt Spinler const struct signalfd_siginfo*); 133*4f472a86SMatt Spinler 134c95c527aSMatthew Barth private: 135b4379a1eSMike Capps /** 136b4379a1eSMike Capps * @brief Callback from D-Bus when Inventory service comes online 137b4379a1eSMike Capps * 138b4379a1eSMike Capps * @param[in] msg - Service details. 139b4379a1eSMike Capps */ 140cb356d48SPatrick Williams void inventoryOnlineCb(sdbusplus::message_t& msg); 141b4379a1eSMike Capps 142683a96c6SMike Capps /** 143683a96c6SMike Capps * @brief Create a BMC Dump 144683a96c6SMike Capps */ 145683a96c6SMike Capps void createBmcDump() const; 146683a96c6SMike Capps 147c95c527aSMatthew Barth /* The mode of fan monitor */ 148c95c527aSMatthew Barth Mode _mode; 149c95c527aSMatthew Barth 150c95c527aSMatthew Barth /* The sdbusplus bus object */ 151cb356d48SPatrick Williams sdbusplus::bus_t& _bus; 152c95c527aSMatthew Barth 153c95c527aSMatthew Barth /* The event loop reference */ 154c95c527aSMatthew Barth const sdeventplus::Event& _event; 155c95c527aSMatthew Barth 156c95c527aSMatthew Barth /* Trust manager of trust groups */ 157c95c527aSMatthew Barth std::unique_ptr<phosphor::fan::trust::Manager> _trust; 158c95c527aSMatthew Barth 159b4379a1eSMike Capps /* match object to detect Inventory service */ 160cb356d48SPatrick Williams std::unique_ptr<sdbusplus::bus::match_t> _inventoryMatch; 161b4379a1eSMike Capps 162c95c527aSMatthew Barth /* List of fan objects to monitor */ 163c95c527aSMatthew Barth std::vector<std::unique_ptr<Fan>> _fans; 164c95c527aSMatthew Barth 165c95c527aSMatthew Barth /** 166b63aa09eSMatt Spinler * @brief The latest health of all the fans 167b63aa09eSMatt Spinler */ 168b63aa09eSMatt Spinler FanHealth _fanHealth; 169b63aa09eSMatt Spinler 170b63aa09eSMatt Spinler /** 171e892e39aSMatt Spinler * @brief The object to watch the power state 172e892e39aSMatt Spinler */ 173e892e39aSMatt Spinler std::unique_ptr<PowerState> _powerState; 174e892e39aSMatt Spinler 175e892e39aSMatt Spinler /** 176e892e39aSMatt Spinler * @brief The power off rules, for shutting down the system 177e892e39aSMatt Spinler * due to fan failures. 178e892e39aSMatt Spinler */ 179e892e39aSMatt Spinler std::vector<std::unique_ptr<PowerOffRule>> _powerOffRules; 180e892e39aSMatt Spinler 181e892e39aSMatt Spinler /** 182f13b42e2SMatt Spinler * @brief The number of concurrently nonfunctional fan sensors 183f13b42e2SMatt Spinler * there must be for an event log created due to a 184f13b42e2SMatt Spinler * nonfunctional fan sensor to have an Error severity as 185f13b42e2SMatt Spinler * opposed to an Informational one. 186f13b42e2SMatt Spinler */ 187f13b42e2SMatt Spinler std::optional<size_t> _numNonfuncSensorsBeforeError; 188f13b42e2SMatt Spinler 189f13b42e2SMatt Spinler /** 190ac1efc11SMatt Spinler * @brief The most recently committed fan error. 191ac1efc11SMatt Spinler */ 192ac1efc11SMatt Spinler std::unique_ptr<FanError> _lastError; 193ac1efc11SMatt Spinler 194ac1efc11SMatt Spinler /** 195c8d3c51fSMatt Spinler * @brief The thermal alert D-Bus object 196c8d3c51fSMatt Spinler */ 197c8d3c51fSMatt Spinler ThermalAlertObject _thermalAlert; 198c8d3c51fSMatt Spinler 199c8d3c51fSMatt Spinler /** 200fdcd5db3SMike Capps * @brief The tach sensors D-Bus match objects 201fdcd5db3SMike Capps */ 202cb356d48SPatrick Williams std::vector<std::unique_ptr<sdbusplus::bus::match_t>> _sensorMatch; 203fdcd5db3SMike Capps 204fdcd5db3SMike Capps /** 205b4379a1eSMike Capps * @brief true if config files have been loaded 2067d135641SMatt Spinler */ 207b4379a1eSMike Capps bool _loaded = false; 2087d135641SMatt Spinler 2097d135641SMatt Spinler /** 210*4f472a86SMatt Spinler * @brief The name of the dump file 211*4f472a86SMatt Spinler */ 212*4f472a86SMatt Spinler static const std::string dumpFile; 213*4f472a86SMatt Spinler 214*4f472a86SMatt Spinler /** 215f13b42e2SMatt Spinler * @brief Captures tach sensor data as JSON for use in 216f13b42e2SMatt Spinler * fan fault and fan missing event logs. 217f13b42e2SMatt Spinler * 218f13b42e2SMatt Spinler * @return json - The JSON data 219f13b42e2SMatt Spinler */ 220f13b42e2SMatt Spinler json captureSensorData(); 221f13b42e2SMatt Spinler 222f13b42e2SMatt Spinler /** 22325f0327eSMike Capps * @brief creates a subscription (service->sensor) to take sensors 22425f0327eSMike Capps * on/offline when D-Bus starts/stops updating values 225fdcd5db3SMike Capps * 226fdcd5db3SMike Capps */ 22725f0327eSMike Capps void subscribeSensorsToServices(); 228fdcd5db3SMike Capps 229fdcd5db3SMike Capps /** 230c95c527aSMatthew Barth * @brief Retrieve the configured trust groups 231c95c527aSMatthew Barth * 232c95c527aSMatthew Barth * @param[in] jsonObj - JSON object to parse from 233c95c527aSMatthew Barth * 234c95c527aSMatthew Barth * @return List of functions applied on trust groups 235c95c527aSMatthew Barth */ 236c95c527aSMatthew Barth const std::vector<CreateGroupFunction> getTrustGroups(const json& jsonObj); 237c95c527aSMatthew Barth 238c95c527aSMatthew Barth /** 239d06905c9SMatthew Barth * @brief Set the trust manager's list of trust group functions 240d06905c9SMatthew Barth * 241d06905c9SMatthew Barth * @param[in] groupFuncs - list of trust group functions 242d06905c9SMatthew Barth */ 243d06905c9SMatthew Barth void setTrustMgr(const std::vector<CreateGroupFunction>& groupFuncs); 244d06905c9SMatthew Barth 245d06905c9SMatthew Barth /** 246c95c527aSMatthew Barth * @brief Retrieve the configured fan definitions 247c95c527aSMatthew Barth * 248c95c527aSMatthew Barth * @param[in] jsonObj - JSON object to parse from 249c95c527aSMatthew Barth * 250c95c527aSMatthew Barth * @return List of fan definition data on the fans configured 251c95c527aSMatthew Barth */ 252c95c527aSMatthew Barth const std::vector<FanDefinition> getFanDefinitions(const json& jsonObj); 253d06905c9SMatthew Barth 254d06905c9SMatthew Barth /** 255d06905c9SMatthew Barth * @brief Set the list of fans to be monitored 256d06905c9SMatthew Barth * 257d06905c9SMatthew Barth * @param[in] fanDefs - list of fan definitions to create fans monitored 258d06905c9SMatthew Barth */ 259d06905c9SMatthew Barth void setFans(const std::vector<FanDefinition>& fanDefs); 260b63aa09eSMatt Spinler 261b63aa09eSMatt Spinler /** 262b63aa09eSMatt Spinler * @brief Updates the fan health map entry for the fan passed in 263b63aa09eSMatt Spinler * 264b63aa09eSMatt Spinler * @param[in] fan - The fan to update the health map with 265b63aa09eSMatt Spinler */ 266b63aa09eSMatt Spinler void updateFanHealth(const Fan& fan); 267e892e39aSMatt Spinler 268e892e39aSMatt Spinler /** 269fdcd5db3SMike Capps * @brief callback when a tach sensor signal goes offline 270fdcd5db3SMike Capps * 271fdcd5db3SMike Capps * @param[in] msg - D-Bus message containing details (inc. service name) 272fdcd5db3SMike Capps * 273fdcd5db3SMike Capps * @param[in] sensorMap - map providing sensor access for each service 274fdcd5db3SMike Capps */ 275cb356d48SPatrick Williams void tachSignalOffline(sdbusplus::message_t& msg, 276fdcd5db3SMike Capps const SensorMapType& sensorMap); 277fdcd5db3SMike Capps 278fdcd5db3SMike Capps /** 279e892e39aSMatt Spinler * @brief The function that runs when the power state changes 280e892e39aSMatt Spinler * 281e892e39aSMatt Spinler * @param[in] powerStateOn - If power is now on or not 282e892e39aSMatt Spinler */ 283e892e39aSMatt Spinler void powerStateChanged(bool powerStateOn); 284e892e39aSMatt Spinler 285e892e39aSMatt Spinler /** 286e892e39aSMatt Spinler * @brief Reads the fault configuration from the JSON config 287e892e39aSMatt Spinler * file, such as the power off rule configuration. 288e892e39aSMatt Spinler * 289e892e39aSMatt Spinler * @param[in] jsonObj - JSON object to parse from 290e892e39aSMatt Spinler */ 291e892e39aSMatt Spinler void setFaultConfig(const json& jsonObj); 292bb449c1cSMatt Spinler 293bb449c1cSMatt Spinler /** 294bb449c1cSMatt Spinler * @brief Log an error and shut down due to an offline fan controller 295bb449c1cSMatt Spinler */ 296bb449c1cSMatt Spinler void handleOfflineFanController(); 297c95c527aSMatthew Barth }; 298c95c527aSMatthew Barth 299c95c527aSMatthew Barth } // namespace phosphor::fan::monitor 300