1 #pragma once 2 3 #include <sdbusplus/bus.hpp> 4 #include <tuple> 5 #include <vector> 6 #include "event.hpp" 7 #include "tach_sensor.hpp" 8 #include "trust_manager.hpp" 9 #include "types.hpp" 10 11 namespace phosphor 12 { 13 namespace fan 14 { 15 namespace monitor 16 { 17 18 /** 19 * The mode fan monitor will run in: 20 * - init - only do the initialization steps 21 * - monitor - run normal monitoring algorithm 22 */ 23 enum class Mode 24 { 25 init, 26 monitor 27 }; 28 29 /** 30 * @class InvalidSensorError 31 * 32 * An exception type for sensors that don't exist or 33 * are otherwise inaccessible. 34 */ 35 class InvalidSensorError : public std::exception {}; 36 37 /** 38 * @class Fan 39 * 40 * Represents a fan, which can contain 1 or more sensors which 41 * loosely correspond to rotors. See below. 42 * 43 * There is a sensor when hwmon exposes one, which means there is a 44 * speed value to be read. Sometimes there is a sensor per rotor, 45 * and other times multiple rotors just use 1 sensor total where 46 * the sensor reports the slowest speed of all of the rotors. 47 * 48 * A rotor's speed is set by writing the Target value of a sensor. 49 * Sometimes each sensor in a fan supports having a Target, and other 50 * times not all of them do. A TachSensor object knows if it supports 51 * the Target property. 52 * 53 * The strategy for monitoring fan speeds is as follows: 54 * 55 * Every time a Target (new speed written) or Input (actual speed read) 56 * sensor changes, check if the input value is within some range of the target 57 * value. If it isn't, start a timer at the end of which the sensor will be 58 * set to not functional. If enough sensors in the fan are now nonfunctional, 59 * set the whole fan to nonfunctional in the inventory. 60 * 61 * When sensor inputs come back within a specified range of the target, 62 * stop its timer if running, make the sensor functional again if it wasn't, 63 * and if enough sensors in the fan are now functional set the whole fan 64 * back to functional in the inventory. 65 */ 66 class Fan 67 { 68 using Property = std::string; 69 using Value = sdbusplus::message::variant<bool>; 70 using PropertyMap = std::map<Property, Value>; 71 72 using Interface = std::string; 73 using InterfaceMap = std::map<Interface, PropertyMap>; 74 75 using Object = sdbusplus::message::object_path; 76 using ObjectMap = std::map<Object, InterfaceMap>; 77 78 public: 79 80 Fan() = delete; 81 Fan(const Fan&) = delete; 82 Fan(Fan&&) = default; 83 Fan& operator=(const Fan&) = delete; 84 Fan& operator=(Fan&&) = default; 85 ~Fan() = default; 86 87 /** 88 * @brief Constructor 89 * 90 * @param mode - mode of fan monitor 91 * @param bus - the dbus object 92 * @param events - pointer to sd_event object 93 * @param trust - the tach trust manager 94 * @param def - the fan definition structure 95 */ 96 Fan(Mode mode, 97 sdbusplus::bus::bus& bus, 98 phosphor::fan::event::EventPtr& events, 99 std::unique_ptr<trust::Manager>& trust, 100 const FanDefinition& def); 101 102 /** 103 * @brief Callback function for when an input sensor changes 104 * 105 * Starts a timer, where if it expires then the sensor 106 * was out of range for too long and can be considered not functional. 107 */ 108 void tachChanged(TachSensor& sensor); 109 110 /** 111 * @brief Calls tachChanged(sensor) on each sensor 112 */ 113 void tachChanged(); 114 115 /** 116 * @brief The callback function for the timer 117 * 118 * Sets the sensor to not functional. 119 * If enough sensors are now not functional, 120 * updates the functional status of the whole 121 * fan in the inventory. 122 * 123 * @param[in] sensor - the sensor whose timer expired 124 */ 125 void timerExpired(TachSensor& sensor); 126 127 private: 128 129 /** 130 * @brief Returns the target speed of the sensor 131 * 132 * If the sensor itself doesn't have a target, it finds 133 * the target speed from another sensor. 134 * 135 * @param[in] sensor - the sensor to get the target speed for 136 */ 137 uint64_t getTargetSpeed(const TachSensor& sensor); 138 139 /** 140 * @brief Returns true if the sensor input is not within 141 * some deviation of the target. 142 * 143 * @param[in] sensor - the sensor to check 144 */ 145 bool outOfRange(const TachSensor& sensor); 146 147 /** 148 * @brief Returns true if too many sensors are nonfunctional 149 * as defined by _numSensorFailsForNonFunc 150 */ 151 bool tooManySensorsNonfunctional(); 152 153 /** 154 * @brief Updates the Functional property in the inventory 155 * for the fan based on the value passed in. 156 * 157 * @param[in] functional - If the Functional property should 158 * be set to true or false. 159 */ 160 void updateInventory(bool functional); 161 162 /** 163 * @brief Returns the object map to use when updating the inventory 164 * 165 * @param[in] functional - If the Functional property should 166 * be set to true or false. 167 */ 168 ObjectMap getObjectMap(bool functional); 169 170 /** 171 * @brief the dbus object 172 */ 173 sdbusplus::bus::bus& _bus; 174 175 /** 176 * @brief The inventory name of the fan 177 */ 178 const std::string _name; 179 180 /** 181 * @brief The percentage that the input speed must be below 182 * the target speed to be considered an error. 183 * Between 0 and 100. 184 */ 185 const size_t _deviation; 186 187 /** 188 * The number of sensors that must be nonfunctional at the 189 * same time in order for the fan to be set to nonfunctional 190 * in the inventory. 191 */ 192 const size_t _numSensorFailsForNonFunc; 193 194 /** 195 * @brief The current functional state of the fan 196 */ 197 bool _functional = true; 198 199 /** 200 * The sensor objects for the fan 201 */ 202 std::vector<std::unique_ptr<TachSensor>> _sensors; 203 204 /** 205 * The tach trust manager object 206 */ 207 std::unique_ptr<trust::Manager>& _trustManager; 208 }; 209 210 } 211 } 212 } 213