blob: c6e77dd73895920b553e359cc631412e420c5f32 [file] [log] [blame]
Vijay Khemkae2795302020-07-15 17:28:45 -07001#include <nlohmann/json.hpp>
Patrick Williams957e03c2021-09-02 16:38:42 -05002#include <phosphor-logging/lg2.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -07003#include <sdbusplus/bus.hpp>
Sui Chen670cc132021-04-13 09:27:22 -07004#include <sdbusplus/message.hpp>
Nan Zhouaf109942022-11-22 20:01:21 +00005#include <sdbusplus/server/manager.hpp>
Vijay Khemkab38fd582020-07-23 13:21:23 -07006#include <sdeventplus/clock.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -07007#include <sdeventplus/event.hpp>
Vijay Khemkab38fd582020-07-23 13:21:23 -07008#include <sdeventplus/utility/timer.hpp>
Sui Chen670cc132021-04-13 09:27:22 -07009#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Sui Chen517524a2021-12-19 20:52:46 -080010#include <xyz/openbmc_project/Inventory/Item/Bmc/server.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -070011#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 Chen517524a2021-12-19 20:52:46 -080015constexpr char BMC_INVENTORY_ITEM[] = "xyz.openbmc_project.Inventory.Item.Bmc";
16constexpr char BMC_CONFIGURATION[] = "xyz.openbmc_project.Configuration.Bmc";
17
Vijay Khemka15537762020-07-22 11:44:56 -070018#include <deque>
Konstantin Aladysheva6cd7042021-12-21 15:36:01 +030019#include <limits>
Vijay Khemkae2795302020-07-15 17:28:45 -070020#include <map>
21#include <string>
22
23namespace phosphor
24{
25namespace health
26{
27
Sui Chen036f1612021-07-22 01:31:49 -070028const char* InventoryPath = "/xyz/openbmc_project/inventory";
29
30// Used for identifying the BMC inventory creation signal
31const char* BMCActivationPath = "/xyz/openbmc_project/inventory/bmc/activation";
32
Patrick Williamsbbfe7182022-07-22 19:26:56 -050033bool FindSystemInventoryInObjectMapper(sdbusplus::bus_t& bus)
Sui Chen036f1612021-07-22 01:31:49 -070034{
Patrick Williamsbbfe7182022-07-22 19:26:56 -050035 sdbusplus::message_t msg =
Sui Chen036f1612021-07-22 01:31:49 -070036 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 Williamsbbfe7182022-07-22 19:26:56 -050044 sdbusplus::message_t reply = bus.call(msg, 0);
Sui Chen036f1612021-07-22 01:31:49 -070045 return true;
46 }
47 catch (const std::exception& e)
48 {}
49 return false;
50}
51
Vijay Khemkae2795302020-07-15 17:28:45 -070052using Json = nlohmann::json;
53using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
54
55using CriticalInterface =
56 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
57
58using WarningInterface =
59 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
60
Sui Chen670cc132021-04-13 09:27:22 -070061using AssociationDefinitionInterface =
62 sdbusplus::xyz::openbmc_project::Association::server::Definitions;
63
Vijay Khemkae2795302020-07-15 17:28:45 -070064using healthIfaces =
Patrick Williamsbbfe7182022-07-22 19:26:56 -050065 sdbusplus::server::object_t<ValueIface, CriticalInterface, WarningInterface,
66 AssociationDefinitionInterface>;
Sui Chen670cc132021-04-13 09:27:22 -070067
Patrick Williams9ca00452022-11-26 09:41:58 -060068using BmcInterface = sdbusplus::server::object_t<
Sui Chen517524a2021-12-19 20:52:46 -080069 sdbusplus::xyz::openbmc_project::Inventory::Item::server::Bmc>;
70
Sui Chen670cc132021-04-13 09:27:22 -070071using AssociationTuple = std::tuple<std::string, std::string, std::string>;
Vijay Khemkae2795302020-07-15 17:28:45 -070072
Vijay Khemka15537762020-07-22 11:44:56 -070073struct HealthConfig
74{
75 std::string name;
76 uint16_t freq;
77 uint16_t windowSize;
Konstantin Aladysheva6cd7042021-12-21 15:36:01 +030078 double criticalHigh = std::numeric_limits<double>::quiet_NaN();
79 double warningHigh = std::numeric_limits<double>::quiet_NaN();
Vijay Khemka15537762020-07-22 11:44:56 -070080 bool criticalLog;
81 bool warningLog;
82 std::string criticalTgt;
83 std::string warningTgt;
Bruceleequantatwaf9acbd2020-10-12 15:21:42 +080084 std::string path;
Vijay Khemka15537762020-07-22 11:44:56 -070085};
86
Vijay Khemkae2795302020-07-15 17:28:45 -070087class 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 Williamsbbfe7182022-07-22 19:26:56 -0500102 HealthSensor(sdbusplus::bus_t& bus, const char* objPath,
Sui Chen670cc132021-04-13 09:27:22 -0700103 HealthConfig& sensorConfig,
104 const std::vector<std::string>& bmcIds) :
Vijay Khemka15537762020-07-22 11:44:56 -0700105 healthIfaces(bus, objPath),
Vijay Khemkab38fd582020-07-23 13:21:23 -0700106 bus(bus), sensorConfig(sensorConfig),
107 timerEvent(sdeventplus::Event::get_default()),
108 readTimer(timerEvent, std::bind(&HealthSensor::readHealthSensor, this))
Vijay Khemka15537762020-07-22 11:44:56 -0700109 {
Sui Chen670cc132021-04-13 09:27:22 -0700110 initHealthSensor(bmcIds);
Vijay Khemka15537762020-07-22 11:44:56 -0700111 }
Vijay Khemkae2795302020-07-15 17:28:45 -0700112
Vijay Khemka15537762020-07-22 11:44:56 -0700113 /** @brief list of sensor data values */
114 std::deque<double> valQueue;
Sui Chen670cc132021-04-13 09:27:22 -0700115 /** @brief Initialize sensor, set default value and association */
116 void initHealthSensor(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700117 /** @brief Set sensor value utilization to health sensor D-bus */
Vijay Khemka15537762020-07-22 11:44:56 -0700118 void setSensorValueToDbus(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -0700119 /** @brief Set Sensor Threshold to D-bus at beginning */
Vijay Khemka15537762020-07-22 11:44:56 -0700120 void setSensorThreshold(double criticalHigh, double warningHigh);
Vijay Khemkab7a7b8a2020-07-29 12:22:01 -0700121 /** @brief Check Sensor threshold and update alarm and log */
122 void checkSensorThreshold(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -0700123
124 private:
Vijay Khemkab38fd582020-07-23 13:21:23 -0700125 /** @brief sdbusplus bus client connection. */
Patrick Williamsbbfe7182022-07-22 19:26:56 -0500126 sdbusplus::bus_t& bus;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700127 /** @brief Sensor config from config file */
Vijay Khemka15537762020-07-22 11:44:56 -0700128 HealthConfig& sensorConfig;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700129 /** @brief the Event Loop structure */
130 sdeventplus::Event timerEvent;
131 /** @brief Sensor Read Timer */
132 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> readTimer;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700133 /** @brief Read sensor at regular intrval */
134 void readHealthSensor();
Potin Lai156ecf32022-07-11 17:09:10 +0800135 /** @brief Start configured threshold systemd unit */
136 void startUnit(const std::string& sysdUnit);
Vijay Khemkae2795302020-07-15 17:28:45 -0700137};
138
Sui Chen517524a2021-12-19 20:52:46 -0800139class BmcInventory : public BmcInterface
140{
141 public:
142 BmcInventory() = delete;
Patrick Williams9ca00452022-11-26 09:41:58 -0600143 BmcInventory(sdbusplus::bus_t& bus, const char* objPath) :
Sui Chen517524a2021-12-19 20:52:46 -0800144 BmcInterface(bus, objPath)
145 {}
146};
147
Vijay Khemkae2795302020-07-15 17:28:45 -0700148class 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 Chen036f1612021-07-22 01:31:49 -0700158 /** @brief Recreates sensor objects and their association if possible
159 */
160 void recreateSensors();
161
Vijay Khemkae2795302020-07-15 17:28:45 -0700162 /** @brief Constructs HealthMon
163 *
164 * @param[in] bus - Handle to system dbus
165 */
Nan Zhouaf109942022-11-22 20:01:21 +0000166 HealthMon(sdbusplus::bus_t& bus) :
167 bus(bus), sensorsObjectManager(bus, "/xyz/openbmc_project/sensors")
Vijay Khemkae2795302020-07-15 17:28:45 -0700168 {
Sui Chen670cc132021-04-13 09:27:22 -0700169 // Read JSON file
Vijay Khemkae2795302020-07-15 17:28:45 -0700170 sensorConfigs = getHealthConfig();
Sui Chen036f1612021-07-22 01:31:49 -0700171 recreateSensors();
Vijay Khemkae2795302020-07-15 17:28:45 -0700172 }
173
Sui Chen670cc132021-04-13 09:27:22 -0700174 /** @brief Parse Health config JSON file */
Vijay Khemkae2795302020-07-15 17:28:45 -0700175 Json parseConfigFile(std::string configFile);
176
Sui Chen670cc132021-04-13 09:27:22 -0700177 /** @brief Read config for each health sensor component */
Vijay Khemkae2795302020-07-15 17:28:45 -0700178 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 Chen670cc132021-04-13 09:27:22 -0700185 void createHealthSensors(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700186
Sui Chen517524a2021-12-19 20:52:46 -0800187 /** @brief Create the BMC Inventory object */
188 void createBmcInventoryIfNotCreated();
189
190 std::shared_ptr<BmcInventory> bmcInventory;
191
192 bool bmcInventoryCreated();
193
Vijay Khemkae2795302020-07-15 17:28:45 -0700194 private:
Patrick Williamsbbfe7182022-07-22 19:26:56 -0500195 sdbusplus::bus_t& bus;
Vijay Khemkae2795302020-07-15 17:28:45 -0700196 std::vector<HealthConfig> sensorConfigs;
197 std::vector<HealthConfig> getHealthConfig();
Nan Zhouaf109942022-11-22 20:01:21 +0000198 sdbusplus::server::manager_t sensorsObjectManager;
Vijay Khemkae2795302020-07-15 17:28:45 -0700199};
200
201} // namespace health
202} // namespace phosphor