blob: b86563ea6e2422e4829fa33ffecc1a3f25db6ae4 [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>
Vijay Khemkab38fd582020-07-23 13:21:23 -07005#include <sdeventplus/clock.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -07006#include <sdeventplus/event.hpp>
Vijay Khemkab38fd582020-07-23 13:21:23 -07007#include <sdeventplus/utility/timer.hpp>
Sui Chen670cc132021-04-13 09:27:22 -07008#include <xyz/openbmc_project/Association/Definitions/server.hpp>
Vijay Khemkae2795302020-07-15 17:28:45 -07009#include <xyz/openbmc_project/Sensor/Threshold/Critical/server.hpp>
10#include <xyz/openbmc_project/Sensor/Threshold/Warning/server.hpp>
11#include <xyz/openbmc_project/Sensor/Value/server.hpp>
12
Vijay Khemka15537762020-07-22 11:44:56 -070013#include <deque>
Konstantin Aladysheva6cd7042021-12-21 15:36:01 +030014#include <limits>
Vijay Khemkae2795302020-07-15 17:28:45 -070015#include <map>
16#include <string>
17
18namespace phosphor
19{
20namespace health
21{
22
Sui Chen036f1612021-07-22 01:31:49 -070023const char* InventoryPath = "/xyz/openbmc_project/inventory";
24
25// Used for identifying the BMC inventory creation signal
26const char* BMCActivationPath = "/xyz/openbmc_project/inventory/bmc/activation";
27
Patrick Williamsbbfe7182022-07-22 19:26:56 -050028bool FindSystemInventoryInObjectMapper(sdbusplus::bus_t& bus)
Sui Chen036f1612021-07-22 01:31:49 -070029{
Patrick Williamsbbfe7182022-07-22 19:26:56 -050030 sdbusplus::message_t msg =
Sui Chen036f1612021-07-22 01:31:49 -070031 bus.new_method_call("xyz.openbmc_project.ObjectMapper",
32 "/xyz/openbmc_project/object_mapper",
33 "xyz.openbmc_project.ObjectMapper", "GetObject");
34 msg.append(InventoryPath);
35 msg.append(std::vector<std::string>{});
36
37 try
38 {
Patrick Williamsbbfe7182022-07-22 19:26:56 -050039 sdbusplus::message_t reply = bus.call(msg, 0);
Sui Chen036f1612021-07-22 01:31:49 -070040 return true;
41 }
42 catch (const std::exception& e)
43 {}
44 return false;
45}
46
Vijay Khemkae2795302020-07-15 17:28:45 -070047using Json = nlohmann::json;
48using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
49
50using CriticalInterface =
51 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Critical;
52
53using WarningInterface =
54 sdbusplus::xyz::openbmc_project::Sensor::Threshold::server::Warning;
55
Sui Chen670cc132021-04-13 09:27:22 -070056using AssociationDefinitionInterface =
57 sdbusplus::xyz::openbmc_project::Association::server::Definitions;
58
Vijay Khemkae2795302020-07-15 17:28:45 -070059using healthIfaces =
Patrick Williamsbbfe7182022-07-22 19:26:56 -050060 sdbusplus::server::object_t<ValueIface, CriticalInterface, WarningInterface,
61 AssociationDefinitionInterface>;
Sui Chen670cc132021-04-13 09:27:22 -070062
63using AssociationTuple = std::tuple<std::string, std::string, std::string>;
Vijay Khemkae2795302020-07-15 17:28:45 -070064
Vijay Khemka15537762020-07-22 11:44:56 -070065struct HealthConfig
66{
67 std::string name;
68 uint16_t freq;
69 uint16_t windowSize;
Konstantin Aladysheva6cd7042021-12-21 15:36:01 +030070 double criticalHigh = std::numeric_limits<double>::quiet_NaN();
71 double warningHigh = std::numeric_limits<double>::quiet_NaN();
Vijay Khemka15537762020-07-22 11:44:56 -070072 bool criticalLog;
73 bool warningLog;
74 std::string criticalTgt;
75 std::string warningTgt;
Bruceleequantatwaf9acbd2020-10-12 15:21:42 +080076 std::string path;
Vijay Khemka15537762020-07-22 11:44:56 -070077};
78
Vijay Khemkae2795302020-07-15 17:28:45 -070079class HealthSensor : public healthIfaces
80{
81 public:
82 HealthSensor() = delete;
83 HealthSensor(const HealthSensor&) = delete;
84 HealthSensor& operator=(const HealthSensor&) = delete;
85 HealthSensor(HealthSensor&&) = delete;
86 HealthSensor& operator=(HealthSensor&&) = delete;
87 virtual ~HealthSensor() = default;
88
89 /** @brief Constructs HealthSensor
90 *
91 * @param[in] bus - Handle to system dbus
92 * @param[in] objPath - The Dbus path of health sensor
93 */
Patrick Williamsbbfe7182022-07-22 19:26:56 -050094 HealthSensor(sdbusplus::bus_t& bus, const char* objPath,
Sui Chen670cc132021-04-13 09:27:22 -070095 HealthConfig& sensorConfig,
96 const std::vector<std::string>& bmcIds) :
Vijay Khemka15537762020-07-22 11:44:56 -070097 healthIfaces(bus, objPath),
Vijay Khemkab38fd582020-07-23 13:21:23 -070098 bus(bus), sensorConfig(sensorConfig),
99 timerEvent(sdeventplus::Event::get_default()),
100 readTimer(timerEvent, std::bind(&HealthSensor::readHealthSensor, this))
Vijay Khemka15537762020-07-22 11:44:56 -0700101 {
Sui Chen670cc132021-04-13 09:27:22 -0700102 initHealthSensor(bmcIds);
Vijay Khemka15537762020-07-22 11:44:56 -0700103 }
Vijay Khemkae2795302020-07-15 17:28:45 -0700104
Vijay Khemka15537762020-07-22 11:44:56 -0700105 /** @brief list of sensor data values */
106 std::deque<double> valQueue;
Sui Chen670cc132021-04-13 09:27:22 -0700107 /** @brief Initialize sensor, set default value and association */
108 void initHealthSensor(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700109 /** @brief Set sensor value utilization to health sensor D-bus */
Vijay Khemka15537762020-07-22 11:44:56 -0700110 void setSensorValueToDbus(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -0700111 /** @brief Set Sensor Threshold to D-bus at beginning */
Vijay Khemka15537762020-07-22 11:44:56 -0700112 void setSensorThreshold(double criticalHigh, double warningHigh);
Vijay Khemkab7a7b8a2020-07-29 12:22:01 -0700113 /** @brief Check Sensor threshold and update alarm and log */
114 void checkSensorThreshold(const double value);
Vijay Khemkae2795302020-07-15 17:28:45 -0700115
116 private:
Vijay Khemkab38fd582020-07-23 13:21:23 -0700117 /** @brief sdbusplus bus client connection. */
Patrick Williamsbbfe7182022-07-22 19:26:56 -0500118 sdbusplus::bus_t& bus;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700119 /** @brief Sensor config from config file */
Vijay Khemka15537762020-07-22 11:44:56 -0700120 HealthConfig& sensorConfig;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700121 /** @brief the Event Loop structure */
122 sdeventplus::Event timerEvent;
123 /** @brief Sensor Read Timer */
124 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> readTimer;
Vijay Khemkab38fd582020-07-23 13:21:23 -0700125 /** @brief Read sensor at regular intrval */
126 void readHealthSensor();
Potin Lai156ecf32022-07-11 17:09:10 +0800127 /** @brief Start configured threshold systemd unit */
128 void startUnit(const std::string& sysdUnit);
Vijay Khemkae2795302020-07-15 17:28:45 -0700129};
130
131class HealthMon
132{
133 public:
134 HealthMon() = delete;
135 HealthMon(const HealthMon&) = delete;
136 HealthMon& operator=(const HealthMon&) = delete;
137 HealthMon(HealthMon&&) = delete;
138 HealthMon& operator=(HealthMon&&) = delete;
139 virtual ~HealthMon() = default;
140
Sui Chen036f1612021-07-22 01:31:49 -0700141 /** @brief Recreates sensor objects and their association if possible
142 */
143 void recreateSensors();
144
Vijay Khemkae2795302020-07-15 17:28:45 -0700145 /** @brief Constructs HealthMon
146 *
147 * @param[in] bus - Handle to system dbus
148 */
Patrick Williamsbbfe7182022-07-22 19:26:56 -0500149 HealthMon(sdbusplus::bus_t& bus) : bus(bus)
Vijay Khemkae2795302020-07-15 17:28:45 -0700150 {
Sui Chen670cc132021-04-13 09:27:22 -0700151 // Read JSON file
Vijay Khemkae2795302020-07-15 17:28:45 -0700152 sensorConfigs = getHealthConfig();
Sui Chen036f1612021-07-22 01:31:49 -0700153 recreateSensors();
Vijay Khemkae2795302020-07-15 17:28:45 -0700154 }
155
Sui Chen670cc132021-04-13 09:27:22 -0700156 /** @brief Parse Health config JSON file */
Vijay Khemkae2795302020-07-15 17:28:45 -0700157 Json parseConfigFile(std::string configFile);
158
Sui Chen670cc132021-04-13 09:27:22 -0700159 /** @brief Read config for each health sensor component */
Vijay Khemkae2795302020-07-15 17:28:45 -0700160 void getConfigData(Json& data, HealthConfig& cfg);
161
162 /** @brief Map of the object HealthSensor */
163 std::unordered_map<std::string, std::shared_ptr<HealthSensor>>
164 healthSensors;
165
166 /** @brief Create sensors for health monitoring */
Sui Chen670cc132021-04-13 09:27:22 -0700167 void createHealthSensors(const std::vector<std::string>& bmcIds);
Vijay Khemkae2795302020-07-15 17:28:45 -0700168
169 private:
Patrick Williamsbbfe7182022-07-22 19:26:56 -0500170 sdbusplus::bus_t& bus;
Vijay Khemkae2795302020-07-15 17:28:45 -0700171 std::vector<HealthConfig> sensorConfigs;
172 std::vector<HealthConfig> getHealthConfig();
173};
174
175} // namespace health
176} // namespace phosphor