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