Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 1 | #include <nlohmann/json.hpp> |
Patrick Williams | 957e03c | 2021-09-02 16:38:42 -0500 | [diff] [blame] | 2 | #include <phosphor-logging/lg2.hpp> |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 3 | #include <sdbusplus/bus.hpp> |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 4 | #include <sdbusplus/message.hpp> |
Nan Zhou | af10994 | 2022-11-22 20:01:21 +0000 | [diff] [blame^] | 5 | #include <sdbusplus/server/manager.hpp> |
Vijay Khemka | b38fd58 | 2020-07-23 13:21:23 -0700 | [diff] [blame] | 6 | #include <sdeventplus/clock.hpp> |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 7 | #include <sdeventplus/event.hpp> |
Vijay Khemka | b38fd58 | 2020-07-23 13:21:23 -0700 | [diff] [blame] | 8 | #include <sdeventplus/utility/timer.hpp> |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 9 | #include <xyz/openbmc_project/Association/Definitions/server.hpp> |
Sui Chen | 517524a | 2021-12-19 20:52:46 -0800 | [diff] [blame] | 10 | #include <xyz/openbmc_project/Inventory/Item/Bmc/server.hpp> |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 11 | #include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp> |
| 12 | #include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp> |
| 13 | #include <xyz/openbmc_project/Sensor/Value/server.hpp> |
| 14 | |
Sui Chen | 517524a | 2021-12-19 20:52:46 -0800 | [diff] [blame] | 15 | constexpr char BMC_INVENTORY_ITEM[] = "xyz.openbmc_project.Inventory.Item.Bmc"; |
| 16 | constexpr char BMC_CONFIGURATION[] = "xyz.openbmc_project.Configuration.Bmc"; |
| 17 | |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 18 | #include <deque> |
Konstantin Aladyshev | a6cd704 | 2021-12-21 15:36:01 +0300 | [diff] [blame] | 19 | #include <limits> |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 20 | #include <map> |
| 21 | #include <string> |
| 22 | |
| 23 | namespace phosphor |
| 24 | { |
| 25 | namespace health |
| 26 | { |
| 27 | |
Sui Chen | 036f161 | 2021-07-22 01:31:49 -0700 | [diff] [blame] | 28 | const char* InventoryPath = "/xyz/openbmc_project/inventory"; |
| 29 | |
| 30 | // Used for identifying the BMC inventory creation signal |
| 31 | const char* BMCActivationPath = "/xyz/openbmc_project/inventory/bmc/activation"; |
| 32 | |
Patrick Williams | bbfe718 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 33 | bool FindSystemInventoryInObjectMapper(sdbusplus::bus_t& bus) |
Sui Chen | 036f161 | 2021-07-22 01:31:49 -0700 | [diff] [blame] | 34 | { |
Patrick Williams | bbfe718 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 35 | sdbusplus::message_t msg = |
Sui Chen | 036f161 | 2021-07-22 01:31:49 -0700 | [diff] [blame] | 36 | bus.new_method_call("xyz.openbmc_project.ObjectMapper", |
| 37 | "/xyz/openbmc_project/object_mapper", |
| 38 | "xyz.openbmc_project.ObjectMapper", "GetObject"); |
| 39 | msg.append(InventoryPath); |
| 40 | msg.append(std::vector<std::string>{}); |
| 41 | |
| 42 | try |
| 43 | { |
Patrick Williams | bbfe718 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 44 | sdbusplus::message_t reply = bus.call(msg, 0); |
Sui Chen | 036f161 | 2021-07-22 01:31:49 -0700 | [diff] [blame] | 45 | return true; |
| 46 | } |
| 47 | catch (const std::exception& e) |
| 48 | {} |
| 49 | return false; |
| 50 | } |
| 51 | |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 52 | using Json = nlohmann::json; |
| 53 | using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value; |
| 54 | |
| 55 | using CriticalInterface = |
| 56 | sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical; |
| 57 | |
| 58 | using WarningInterface = |
| 59 | sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning; |
| 60 | |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 61 | using AssociationDefinitionInterface = |
| 62 | sdbusplus::xyz::openbmc_project::Association::server::Definitions; |
| 63 | |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 64 | using healthIfaces = |
Patrick Williams | bbfe718 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 65 | sdbusplus::server::object_t<ValueIface, CriticalInterface, WarningInterface, |
| 66 | AssociationDefinitionInterface>; |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 67 | |
Patrick Williams | 9ca0045 | 2022-11-26 09:41:58 -0600 | [diff] [blame] | 68 | using BmcInterface = sdbusplus::server::object_t< |
Sui Chen | 517524a | 2021-12-19 20:52:46 -0800 | [diff] [blame] | 69 | sdbusplus::xyz::openbmc_project::Inventory::Item::server::Bmc>; |
| 70 | |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 71 | using AssociationTuple = std::tuple<std::string, std::string, std::string>; |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 72 | |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 73 | struct HealthConfig |
| 74 | { |
| 75 | std::string name; |
| 76 | uint16_t freq; |
| 77 | uint16_t windowSize; |
Konstantin Aladyshev | a6cd704 | 2021-12-21 15:36:01 +0300 | [diff] [blame] | 78 | double criticalHigh = std::numeric_limits<double>::quiet_NaN(); |
| 79 | double warningHigh = std::numeric_limits<double>::quiet_NaN(); |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 80 | bool criticalLog; |
| 81 | bool warningLog; |
| 82 | std::string criticalTgt; |
| 83 | std::string warningTgt; |
Bruceleequantatw | af9acbd | 2020-10-12 15:21:42 +0800 | [diff] [blame] | 84 | std::string path; |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 85 | }; |
| 86 | |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 87 | class HealthSensor : public healthIfaces |
| 88 | { |
| 89 | public: |
| 90 | HealthSensor() = delete; |
| 91 | HealthSensor(const HealthSensor&) = delete; |
| 92 | HealthSensor& operator=(const HealthSensor&) = delete; |
| 93 | HealthSensor(HealthSensor&&) = delete; |
| 94 | HealthSensor& operator=(HealthSensor&&) = delete; |
| 95 | virtual ~HealthSensor() = default; |
| 96 | |
| 97 | /** @brief Constructs HealthSensor |
| 98 | * |
| 99 | * @param[in] bus - Handle to system dbus |
| 100 | * @param[in] objPath - The Dbus path of health sensor |
| 101 | */ |
Patrick Williams | bbfe718 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 102 | HealthSensor(sdbusplus::bus_t& bus, const char* objPath, |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 103 | HealthConfig& sensorConfig, |
| 104 | const std::vector<std::string>& bmcIds) : |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 105 | healthIfaces(bus, objPath), |
Vijay Khemka | b38fd58 | 2020-07-23 13:21:23 -0700 | [diff] [blame] | 106 | bus(bus), sensorConfig(sensorConfig), |
| 107 | timerEvent(sdeventplus::Event::get_default()), |
| 108 | readTimer(timerEvent, std::bind(&HealthSensor::readHealthSensor, this)) |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 109 | { |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 110 | initHealthSensor(bmcIds); |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 111 | } |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 112 | |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 113 | /** @brief list of sensor data values */ |
| 114 | std::deque<double> valQueue; |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 115 | /** @brief Initialize sensor, set default value and association */ |
| 116 | void initHealthSensor(const std::vector<std::string>& bmcIds); |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 117 | /** @brief Set sensor value utilization to health sensor D-bus */ |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 118 | void setSensorValueToDbus(const double value); |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 119 | /** @brief Set Sensor Threshold to D-bus at beginning */ |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 120 | void setSensorThreshold(double criticalHigh, double warningHigh); |
Vijay Khemka | b7a7b8a | 2020-07-29 12:22:01 -0700 | [diff] [blame] | 121 | /** @brief Check Sensor threshold and update alarm and log */ |
| 122 | void checkSensorThreshold(const double value); |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 123 | |
| 124 | private: |
Vijay Khemka | b38fd58 | 2020-07-23 13:21:23 -0700 | [diff] [blame] | 125 | /** @brief sdbusplus bus client connection. */ |
Patrick Williams | bbfe718 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 126 | sdbusplus::bus_t& bus; |
Vijay Khemka | b38fd58 | 2020-07-23 13:21:23 -0700 | [diff] [blame] | 127 | /** @brief Sensor config from config file */ |
Vijay Khemka | 1553776 | 2020-07-22 11:44:56 -0700 | [diff] [blame] | 128 | HealthConfig& sensorConfig; |
Vijay Khemka | b38fd58 | 2020-07-23 13:21:23 -0700 | [diff] [blame] | 129 | /** @brief the Event Loop structure */ |
| 130 | sdeventplus::Event timerEvent; |
| 131 | /** @brief Sensor Read Timer */ |
| 132 | sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> readTimer; |
Vijay Khemka | b38fd58 | 2020-07-23 13:21:23 -0700 | [diff] [blame] | 133 | /** @brief Read sensor at regular intrval */ |
| 134 | void readHealthSensor(); |
Potin Lai | 156ecf3 | 2022-07-11 17:09:10 +0800 | [diff] [blame] | 135 | /** @brief Start configured threshold systemd unit */ |
| 136 | void startUnit(const std::string& sysdUnit); |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 137 | }; |
| 138 | |
Sui Chen | 517524a | 2021-12-19 20:52:46 -0800 | [diff] [blame] | 139 | class BmcInventory : public BmcInterface |
| 140 | { |
| 141 | public: |
| 142 | BmcInventory() = delete; |
Patrick Williams | 9ca0045 | 2022-11-26 09:41:58 -0600 | [diff] [blame] | 143 | BmcInventory(sdbusplus::bus_t& bus, const char* objPath) : |
Sui Chen | 517524a | 2021-12-19 20:52:46 -0800 | [diff] [blame] | 144 | BmcInterface(bus, objPath) |
| 145 | {} |
| 146 | }; |
| 147 | |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 148 | class HealthMon |
| 149 | { |
| 150 | public: |
| 151 | HealthMon() = delete; |
| 152 | HealthMon(const HealthMon&) = delete; |
| 153 | HealthMon& operator=(const HealthMon&) = delete; |
| 154 | HealthMon(HealthMon&&) = delete; |
| 155 | HealthMon& operator=(HealthMon&&) = delete; |
| 156 | virtual ~HealthMon() = default; |
| 157 | |
Sui Chen | 036f161 | 2021-07-22 01:31:49 -0700 | [diff] [blame] | 158 | /** @brief Recreates sensor objects and their association if possible |
| 159 | */ |
| 160 | void recreateSensors(); |
| 161 | |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 162 | /** @brief Constructs HealthMon |
| 163 | * |
| 164 | * @param[in] bus - Handle to system dbus |
| 165 | */ |
Nan Zhou | af10994 | 2022-11-22 20:01:21 +0000 | [diff] [blame^] | 166 | HealthMon(sdbusplus::bus_t& bus) : |
| 167 | bus(bus), sensorsObjectManager(bus, "/xyz/openbmc_project/sensors") |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 168 | { |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 169 | // Read JSON file |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 170 | sensorConfigs = getHealthConfig(); |
Sui Chen | 036f161 | 2021-07-22 01:31:49 -0700 | [diff] [blame] | 171 | recreateSensors(); |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 172 | } |
| 173 | |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 174 | /** @brief Parse Health config JSON file */ |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 175 | Json parseConfigFile(std::string configFile); |
| 176 | |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 177 | /** @brief Read config for each health sensor component */ |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 178 | void getConfigData(Json& data, HealthConfig& cfg); |
| 179 | |
| 180 | /** @brief Map of the object HealthSensor */ |
| 181 | std::unordered_map<std::string, std::shared_ptr<HealthSensor>> |
| 182 | healthSensors; |
| 183 | |
| 184 | /** @brief Create sensors for health monitoring */ |
Sui Chen | 670cc13 | 2021-04-13 09:27:22 -0700 | [diff] [blame] | 185 | void createHealthSensors(const std::vector<std::string>& bmcIds); |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 186 | |
Sui Chen | 517524a | 2021-12-19 20:52:46 -0800 | [diff] [blame] | 187 | /** @brief Create the BMC Inventory object */ |
| 188 | void createBmcInventoryIfNotCreated(); |
| 189 | |
| 190 | std::shared_ptr<BmcInventory> bmcInventory; |
| 191 | |
| 192 | bool bmcInventoryCreated(); |
| 193 | |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 194 | private: |
Patrick Williams | bbfe718 | 2022-07-22 19:26:56 -0500 | [diff] [blame] | 195 | sdbusplus::bus_t& bus; |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 196 | std::vector<HealthConfig> sensorConfigs; |
| 197 | std::vector<HealthConfig> getHealthConfig(); |
Nan Zhou | af10994 | 2022-11-22 20:01:21 +0000 | [diff] [blame^] | 198 | sdbusplus::server::manager_t sensorsObjectManager; |
Vijay Khemka | e279530 | 2020-07-15 17:28:45 -0700 | [diff] [blame] | 199 | }; |
| 200 | |
| 201 | } // namespace health |
| 202 | } // namespace phosphor |