1 #pragma once 2 3 #include "config.h" 4 5 #include "tach_sensor.hpp" 6 #include "trust_manager.hpp" 7 #include "types.hpp" 8 9 #include <sdbusplus/bus.hpp> 10 #include <sdeventplus/event.hpp> 11 12 #include <tuple> 13 #include <vector> 14 15 namespace phosphor 16 { 17 namespace fan 18 { 19 namespace monitor 20 { 21 22 class System; 23 24 /** 25 * @class Fan 26 * 27 * Represents a fan, which can contain 1 or more sensors which 28 * loosely correspond to rotors. See below. 29 * 30 * There is a sensor when hwmon exposes one, which means there is a 31 * speed value to be read. Sometimes there is a sensor per rotor, 32 * and other times multiple rotors just use 1 sensor total where 33 * the sensor reports the slowest speed of all of the rotors. 34 * 35 * A rotor's speed is set by writing the Target value of a sensor. 36 * Sometimes each sensor in a fan supports having a Target, and other 37 * times not all of them do. A TachSensor object knows if it supports 38 * the Target property. 39 * 40 * The strategy for monitoring fan speeds is as follows: 41 * 42 * Every time a Target (new speed written) or Input (actual speed read) 43 * sensor changes, check if the input value is within some range of the target 44 * value. If it isn't, start a timer at the end of which the sensor will be 45 * set to not functional. If enough sensors in the fan are now nonfunctional, 46 * set the whole fan to nonfunctional in the inventory. 47 * 48 * When sensor inputs come back within a specified range of the target, 49 * stop its timer if running, make the sensor functional again if it wasn't, 50 * and if enough sensors in the fan are now functional set the whole fan 51 * back to functional in the inventory. 52 */ 53 class Fan 54 { 55 using Property = std::string; 56 using Value = std::variant<bool>; 57 using PropertyMap = std::map<Property, Value>; 58 59 using Interface = std::string; 60 using InterfaceMap = std::map<Interface, PropertyMap>; 61 62 using Object = sdbusplus::message::object_path; 63 using ObjectMap = std::map<Object, InterfaceMap>; 64 65 public: 66 Fan() = delete; 67 Fan(const Fan&) = delete; 68 Fan(Fan&&) = default; 69 Fan& operator=(const Fan&) = delete; 70 Fan& operator=(Fan&&) = default; 71 ~Fan() = default; 72 73 /** 74 * @brief Constructor 75 * 76 * @param mode - mode of fan monitor 77 * @param bus - the dbus object 78 * @param event - event loop reference 79 * @param trust - the tach trust manager 80 * @param def - the fan definition structure 81 * @param system - Reference to the system object 82 */ 83 Fan(Mode mode, sdbusplus::bus_t& bus, const sdeventplus::Event& event, 84 std::unique_ptr<trust::Manager>& trust, const FanDefinition& def, 85 System& system); 86 87 /** 88 * @brief Callback function for when an input sensor changes 89 * 90 * Starts a timer, where if it expires then the sensor 91 * was out of range for too long and can be considered not functional. 92 */ 93 void tachChanged(TachSensor& sensor); 94 95 /** 96 * @brief Calls tachChanged(sensor) on each sensor 97 */ 98 void tachChanged(); 99 100 /** 101 * @brief The callback function for the method 102 * 103 * Sets the sensor to not functional. 104 * If enough sensors are now not functional, 105 * updates the functional status of the whole 106 * fan in the inventory. 107 * 108 * @param[in] sensor - the sensor for state update 109 */ 110 void updateState(TachSensor& sensor); 111 112 /** 113 * @brief Get the name of the fan 114 * 115 * @return - The fan name 116 */ getName() const117 inline const std::string& getName() const 118 { 119 return _name; 120 } 121 122 /** 123 * @brief Finds the target speed of this fan 124 * 125 * Finds the target speed from the list of sensors that make up this 126 * fan. At least one sensor should contain a target speed value. 127 * 128 * @return - The target speed found from the list of sensors on the fan 129 */ 130 uint64_t findTargetSpeed(); 131 132 /** 133 * @brief Returns the contained TachSensor objects 134 * 135 * @return std::vector<std::shared_ptr<TachSensor>> - The sensors 136 */ sensors() const137 const std::vector<std::shared_ptr<TachSensor>>& sensors() const 138 { 139 return _sensors; 140 } 141 142 /** 143 * @brief Returns the presence status of the fan 144 * 145 * @return bool - If the fan is present or not 146 */ present() const147 bool present() const 148 { 149 return _present; 150 } 151 152 /** 153 * @brief Called from TachSensor when its error timer expires 154 * so an event log calling out the fan can be created. 155 * 156 * @param[in] sensor - The nonfunctional sensor 157 */ 158 void sensorErrorTimerExpired(const TachSensor& sensor); 159 160 /** 161 * @brief Process the state of the given tach sensor without checking 162 * any trust groups the sensor may be included in 163 * 164 * @param[in] sensor - Tach sensor to process 165 * 166 * This function is intended to check the current state of a tach sensor 167 * regardless of whether or not the tach sensor is configured to be in any 168 * trust groups. 169 */ 170 void process(TachSensor& sensor); 171 172 /** 173 * @brief The function that runs when the power state changes 174 * 175 * @param[in] powerStateOn - If power is now on or not 176 */ 177 void powerStateChanged(bool powerStateOn); 178 179 /** 180 * @brief Timer callback function that deals with sensors using 181 * the 'count' method for determining functional status. 182 * 183 * @param[in] sensor - TachSensor object 184 */ 185 void countTimerExpired(TachSensor& sensor); 186 187 /** 188 * @brief Returns the number of tach sensors (Sensor.Value ifaces) 189 * on D-Bus at the last power on. 190 */ numSensorsOnDBusAtPowerOn() const191 inline size_t numSensorsOnDBusAtPowerOn() const 192 { 193 return _numSensorsOnDBusAtPowerOn; 194 } 195 196 /** 197 * @brief Returns true if the sensor input is not within 198 * some deviation of the target. 199 * 200 * @param[in] sensor - the sensor to check 201 */ 202 bool outOfRange(const TachSensor& sensor); 203 204 private: 205 /** 206 * @brief Returns the number sensors that are nonfunctional 207 */ 208 size_t countNonFunctionalSensors() const; 209 210 /** 211 * @brief Updates the Functional property in the inventory 212 * for the fan based on the value passed in. 213 * 214 * @param[in] functional - If the Functional property should 215 * be set to true or false. 216 * 217 * @return - True if an exception was encountered during update 218 */ 219 bool updateInventory(bool functional); 220 221 /** 222 * @brief Called by _monitorTimer to start fan monitoring some 223 * amount of time after startup. 224 */ 225 void startMonitor(); 226 227 /** 228 * @brief Called when the fan presence property changes on D-Bus 229 * 230 * @param[in] msg - The message from the propertiesChanged signal 231 */ 232 void presenceChanged(sdbusplus::message_t& msg); 233 234 /** 235 * @brief Called when there is an interfacesAdded signal on the 236 * fan D-Bus path so the code can look for the 'Present' 237 * property value. 238 * 239 * @param[in] msg - The message from the interfacesAdded signal 240 */ 241 void presenceIfaceAdded(sdbusplus::message_t& msg); 242 243 /** 244 * @brief the dbus object 245 */ 246 sdbusplus::bus_t& _bus; 247 248 /** 249 * @brief The inventory name of the fan 250 */ 251 const std::string _name; 252 253 /** 254 * @brief The percentage that the input speed must be below 255 * the target speed to be considered an error. 256 * Between 0 and 100. 257 */ 258 const size_t _deviation; 259 260 /** 261 * @brief The percentage that the input speed must be above 262 * the target speed to be considered an error. 263 * Between 0 and 100. 264 */ 265 const size_t _upperDeviation; 266 267 /** 268 * The number of sensors that must be nonfunctional at the 269 * same time in order for the fan to be set to nonfunctional 270 * in the inventory. 271 */ 272 const size_t _numSensorFailsForNonFunc; 273 274 /** 275 * The number of failed sensors 276 */ 277 size_t _numFailedSensor = 0; 278 279 /** 280 * @brief The current functional state of the fan 281 */ 282 bool _functional = true; 283 284 /** 285 * The sensor objects for the fan 286 */ 287 std::vector<std::shared_ptr<TachSensor>> _sensors; 288 289 /** 290 * The tach trust manager object 291 */ 292 std::unique_ptr<trust::Manager>& _trustManager; 293 294 #ifdef MONITOR_USE_JSON 295 /** 296 * @brief The number of seconds to wait after startup until 297 * fan sensors should checked against their targets. 298 */ 299 size_t _monitorDelay; 300 301 /** 302 * @brief Expires after _monitorDelay to start fan monitoring. 303 */ 304 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _monitorTimer; 305 #endif 306 307 /** 308 * @brief Set to true when monitoring can start. 309 */ 310 bool _monitorReady = false; 311 312 /** 313 * @brief Reference to the System object 314 */ 315 System& _system; 316 317 /** 318 * @brief The match object for propertiesChanged signals 319 * for the inventory item interface to track the 320 * Present property. 321 */ 322 sdbusplus::bus::match_t _presenceMatch; 323 324 /** 325 * @brief The match object for the interfacesAdded signal 326 * for the interface that has the Present property. 327 */ 328 sdbusplus::bus::match_t _presenceIfaceAddedMatch; 329 330 /** 331 * @brief The current presence state 332 */ 333 bool _present = false; 334 335 /** 336 * @brief The number of seconds to wait after a fan is removed before 337 * creating an event log for it. If std::nullopt, then no 338 * event log will be created. 339 */ 340 const std::optional<size_t> _fanMissingErrorDelay; 341 342 /** 343 * @brief The timer that uses the _fanMissingErrorDelay timeout, 344 * at the end of which an event log will be created. 345 */ 346 std::unique_ptr< 347 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 348 _fanMissingErrorTimer; 349 350 /** 351 * @brief If the fan and sensors should be set to functional when 352 * a fan plug is detected. 353 */ 354 bool _setFuncOnPresent; 355 356 /** 357 * @brief The number of sensors that have their Sensor.Value interfaces 358 * on D-Bus at the last power on. 359 * 360 * Will be zero until the power turns on the first time. 361 */ 362 size_t _numSensorsOnDBusAtPowerOn = 0; 363 }; 364 365 } // namespace monitor 366 } // namespace fan 367 } // namespace phosphor 368