xref: /openbmc/phosphor-fan-presence/monitor/system.hpp (revision 4f472a866f5c2211c8e63126638c7afaee05085f)
1c95c527aSMatthew Barth /**
2c95c527aSMatthew Barth  * Copyright © 2020 IBM Corporation
3c95c527aSMatthew Barth  *
4c95c527aSMatthew Barth  * Licensed under the Apache License, Version 2.0 (the "License");
5c95c527aSMatthew Barth  * you may not use this file except in compliance with the License.
6c95c527aSMatthew Barth  * You may obtain a copy of the License at
7c95c527aSMatthew Barth  *
8c95c527aSMatthew Barth  *     http://www.apache.org/licenses/LICENSE-2.0
9c95c527aSMatthew Barth  *
10c95c527aSMatthew Barth  * Unless required by applicable law or agreed to in writing, software
11c95c527aSMatthew Barth  * distributed under the License is distributed on an "AS IS" BASIS,
12c95c527aSMatthew Barth  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c95c527aSMatthew Barth  * See the License for the specific language governing permissions and
14c95c527aSMatthew Barth  * limitations under the License.
15c95c527aSMatthew Barth  */
16c95c527aSMatthew Barth #pragma once
17c95c527aSMatthew Barth 
18c95c527aSMatthew Barth #include "fan.hpp"
19ac1efc11SMatt Spinler #include "fan_error.hpp"
20e892e39aSMatt Spinler #include "power_off_rule.hpp"
21e892e39aSMatt Spinler #include "power_state.hpp"
22c95c527aSMatthew Barth #include "tach_sensor.hpp"
23c95c527aSMatthew Barth #include "trust_manager.hpp"
24c95c527aSMatthew Barth #include "types.hpp"
25c95c527aSMatthew Barth 
26c95c527aSMatthew Barth #include <nlohmann/json.hpp>
27c95c527aSMatthew Barth #include <sdbusplus/bus.hpp>
28c95c527aSMatthew Barth #include <sdeventplus/event.hpp>
29*4f472a86SMatt Spinler #include <sdeventplus/source/event.hpp>
30d06905c9SMatthew Barth #include <sdeventplus/source/signal.hpp>
31c95c527aSMatthew Barth 
32c95c527aSMatthew Barth #include <memory>
33c95c527aSMatthew Barth #include <optional>
34c95c527aSMatthew Barth #include <vector>
35c95c527aSMatthew Barth 
36c95c527aSMatthew Barth namespace phosphor::fan::monitor
37c95c527aSMatthew Barth {
38c95c527aSMatthew Barth 
39c95c527aSMatthew Barth using json = nlohmann::json;
40c95c527aSMatthew Barth 
41fdcd5db3SMike Capps // Mapping from service name to sensor
42fdcd5db3SMike Capps using SensorMapType =
43fdcd5db3SMike Capps     std::map<std::string, std::set<std::shared_ptr<TachSensor>>>;
44fdcd5db3SMike Capps 
45c95c527aSMatthew Barth class System
46c95c527aSMatthew Barth {
47c95c527aSMatthew Barth   public:
48c95c527aSMatthew Barth     System() = delete;
49ac1efc11SMatt Spinler     ~System() = default;
50c95c527aSMatthew Barth     System(const System&) = delete;
51c95c527aSMatthew Barth     System(System&&) = delete;
52c95c527aSMatthew Barth     System& operator=(const System&) = delete;
53c95c527aSMatthew Barth     System& operator=(System&&) = delete;
54c95c527aSMatthew Barth 
55c95c527aSMatthew Barth     /**
56c95c527aSMatthew Barth      * Constructor
57c95c527aSMatthew Barth      *
58c95c527aSMatthew Barth      * @param[in] mode - mode of fan monitor
59c95c527aSMatthew Barth      * @param[in] bus - sdbusplus bus object
60c95c527aSMatthew Barth      * @param[in] event - event loop reference
61c95c527aSMatthew Barth      */
62cb356d48SPatrick Williams     System(Mode mode, sdbusplus::bus_t& bus, const sdeventplus::Event& event);
63c95c527aSMatthew Barth 
64d06905c9SMatthew Barth     /**
65d06905c9SMatthew Barth      * @brief Callback function to handle receiving a HUP signal to reload the
66d06905c9SMatthew Barth      * JSON configuration.
67d06905c9SMatthew Barth      */
68d06905c9SMatthew Barth     void sighupHandler(sdeventplus::source::Signal&,
69d06905c9SMatthew Barth                        const struct signalfd_siginfo*);
70d06905c9SMatthew Barth 
71b63aa09eSMatt Spinler     /**
72b63aa09eSMatt Spinler      * @brief Called from the fan when it changes either
73b63aa09eSMatt Spinler      *        present or functional status to update the
74b63aa09eSMatt Spinler      *        fan health map.
75b63aa09eSMatt Spinler      *
76b63aa09eSMatt Spinler      * @param[in] fan - The fan that changed
774283c5d5SMatt Spinler      * @param[in] skipRulesCheck - If the rules checks should be done now.
78b63aa09eSMatt Spinler      */
794283c5d5SMatt Spinler     void fanStatusChange(const Fan& fan, bool skipRulesCheck = false);
80b63aa09eSMatt Spinler 
81f13b42e2SMatt Spinler     /**
82f13b42e2SMatt Spinler      * @brief Called when a fan sensor's error timer expires, which
83f13b42e2SMatt Spinler      *        happens when the sensor has been nonfunctional for a
84f13b42e2SMatt Spinler      *        certain amount of time.  An event log will be created.
85f13b42e2SMatt Spinler      *
86f13b42e2SMatt Spinler      * @param[in] fan - The parent fan of the sensor
87f13b42e2SMatt Spinler      * @param[in] sensor - The faulted sensor
88f13b42e2SMatt Spinler      */
89f13b42e2SMatt Spinler     void sensorErrorTimerExpired(const Fan& fan, const TachSensor& sensor);
90f13b42e2SMatt Spinler 
9127f6b686SMatt Spinler     /**
9227f6b686SMatt Spinler      * @brief Called when the timer that starts when a fan is missing
9327f6b686SMatt Spinler      *        has expired so an event log needs to be created.
9427f6b686SMatt Spinler      *
9527f6b686SMatt Spinler      * @param[in] fan - The missing fan.
9627f6b686SMatt Spinler      */
9727f6b686SMatt Spinler     void fanMissingErrorTimerExpired(const Fan& fan);
9827f6b686SMatt Spinler 
99ac1efc11SMatt Spinler     /**
100ac1efc11SMatt Spinler      * @brief Called by the power off actions to log an error when there is
101ac1efc11SMatt Spinler      *        a power off due to fan problems.
102ac1efc11SMatt Spinler      *
103ac1efc11SMatt Spinler      * The error it logs is just the last fan error that occurred.
104ac1efc11SMatt Spinler      */
105ac1efc11SMatt Spinler     void logShutdownError();
106ac1efc11SMatt Spinler 
1077d135641SMatt Spinler     /**
1087d135641SMatt Spinler      * @brief Returns true if power is on
1097d135641SMatt Spinler      */
isPowerOn() const1107d135641SMatt Spinler     bool isPowerOn() const
1117d135641SMatt Spinler     {
1127d135641SMatt Spinler         return _powerState->isPowerOn();
1137d135641SMatt Spinler     }
1147d135641SMatt Spinler 
1157d135641SMatt Spinler     /**
116b4379a1eSMike Capps      * @brief tests the presence of Inventory and calls load() if present, else
117b4379a1eSMike Capps      *  waits for Inventory asynchronously and has a callback to load() when
118b4379a1eSMike Capps      * present
1197d135641SMatt Spinler      */
120823bc49eSMatthew Barth     void start();
1217d135641SMatt Spinler 
122b4379a1eSMike Capps     /**
123b4379a1eSMike Capps      * @brief Parses and populates the fan monitor trust groups and list of fans
124b4379a1eSMike Capps      */
125b4379a1eSMike Capps     void load();
126b4379a1eSMike Capps 
127*4f472a86SMatt Spinler     /**
128*4f472a86SMatt Spinler      * @brief Callback function to handle receiving a USR1 signal to dump
129*4f472a86SMatt Spinler      * debug data to a file.
130*4f472a86SMatt Spinler      */
131*4f472a86SMatt Spinler     void dumpDebugData(sdeventplus::source::Signal&,
132*4f472a86SMatt Spinler                        const struct signalfd_siginfo*);
133*4f472a86SMatt Spinler 
134c95c527aSMatthew Barth   private:
135b4379a1eSMike Capps     /**
136b4379a1eSMike Capps      * @brief Callback from D-Bus when Inventory service comes online
137b4379a1eSMike Capps      *
138b4379a1eSMike Capps      * @param[in] msg - Service details.
139b4379a1eSMike Capps      */
140cb356d48SPatrick Williams     void inventoryOnlineCb(sdbusplus::message_t& msg);
141b4379a1eSMike Capps 
142683a96c6SMike Capps     /**
143683a96c6SMike Capps      * @brief Create a BMC Dump
144683a96c6SMike Capps      */
145683a96c6SMike Capps     void createBmcDump() const;
146683a96c6SMike Capps 
147c95c527aSMatthew Barth     /* The mode of fan monitor */
148c95c527aSMatthew Barth     Mode _mode;
149c95c527aSMatthew Barth 
150c95c527aSMatthew Barth     /* The sdbusplus bus object */
151cb356d48SPatrick Williams     sdbusplus::bus_t& _bus;
152c95c527aSMatthew Barth 
153c95c527aSMatthew Barth     /* The event loop reference */
154c95c527aSMatthew Barth     const sdeventplus::Event& _event;
155c95c527aSMatthew Barth 
156c95c527aSMatthew Barth     /* Trust manager of trust groups */
157c95c527aSMatthew Barth     std::unique_ptr<phosphor::fan::trust::Manager> _trust;
158c95c527aSMatthew Barth 
159b4379a1eSMike Capps     /* match object to detect Inventory service */
160cb356d48SPatrick Williams     std::unique_ptr<sdbusplus::bus::match_t> _inventoryMatch;
161b4379a1eSMike Capps 
162c95c527aSMatthew Barth     /* List of fan objects to monitor */
163c95c527aSMatthew Barth     std::vector<std::unique_ptr<Fan>> _fans;
164c95c527aSMatthew Barth 
165c95c527aSMatthew Barth     /**
166b63aa09eSMatt Spinler      * @brief The latest health of all the fans
167b63aa09eSMatt Spinler      */
168b63aa09eSMatt Spinler     FanHealth _fanHealth;
169b63aa09eSMatt Spinler 
170b63aa09eSMatt Spinler     /**
171e892e39aSMatt Spinler      * @brief The object to watch the power state
172e892e39aSMatt Spinler      */
173e892e39aSMatt Spinler     std::unique_ptr<PowerState> _powerState;
174e892e39aSMatt Spinler 
175e892e39aSMatt Spinler     /**
176e892e39aSMatt Spinler      * @brief The power off rules, for shutting down the system
177e892e39aSMatt Spinler      *        due to fan failures.
178e892e39aSMatt Spinler      */
179e892e39aSMatt Spinler     std::vector<std::unique_ptr<PowerOffRule>> _powerOffRules;
180e892e39aSMatt Spinler 
181e892e39aSMatt Spinler     /**
182f13b42e2SMatt Spinler      * @brief The number of concurrently nonfunctional fan sensors
183f13b42e2SMatt Spinler      *        there must be for an event log created due to a
184f13b42e2SMatt Spinler      *        nonfunctional fan sensor to have an Error severity as
185f13b42e2SMatt Spinler      *        opposed to an Informational one.
186f13b42e2SMatt Spinler      */
187f13b42e2SMatt Spinler     std::optional<size_t> _numNonfuncSensorsBeforeError;
188f13b42e2SMatt Spinler 
189f13b42e2SMatt Spinler     /**
190ac1efc11SMatt Spinler      * @brief The most recently committed fan error.
191ac1efc11SMatt Spinler      */
192ac1efc11SMatt Spinler     std::unique_ptr<FanError> _lastError;
193ac1efc11SMatt Spinler 
194ac1efc11SMatt Spinler     /**
195c8d3c51fSMatt Spinler      * @brief The thermal alert D-Bus object
196c8d3c51fSMatt Spinler      */
197c8d3c51fSMatt Spinler     ThermalAlertObject _thermalAlert;
198c8d3c51fSMatt Spinler 
199c8d3c51fSMatt Spinler     /**
200fdcd5db3SMike Capps      * @brief The tach sensors D-Bus match objects
201fdcd5db3SMike Capps      */
202cb356d48SPatrick Williams     std::vector<std::unique_ptr<sdbusplus::bus::match_t>> _sensorMatch;
203fdcd5db3SMike Capps 
204fdcd5db3SMike Capps     /**
205b4379a1eSMike Capps      * @brief true if config files have been loaded
2067d135641SMatt Spinler      */
207b4379a1eSMike Capps     bool _loaded = false;
2087d135641SMatt Spinler 
2097d135641SMatt Spinler     /**
210*4f472a86SMatt Spinler      * @brief The name of the dump file
211*4f472a86SMatt Spinler      */
212*4f472a86SMatt Spinler     static const std::string dumpFile;
213*4f472a86SMatt Spinler 
214*4f472a86SMatt Spinler     /**
215f13b42e2SMatt Spinler      * @brief Captures tach sensor data as JSON for use in
216f13b42e2SMatt Spinler      *        fan fault and fan missing event logs.
217f13b42e2SMatt Spinler      *
218f13b42e2SMatt Spinler      * @return json - The JSON data
219f13b42e2SMatt Spinler      */
220f13b42e2SMatt Spinler     json captureSensorData();
221f13b42e2SMatt Spinler 
222f13b42e2SMatt Spinler     /**
22325f0327eSMike Capps      * @brief creates a subscription (service->sensor) to take sensors
22425f0327eSMike Capps      *        on/offline when D-Bus starts/stops updating values
225fdcd5db3SMike Capps      *
226fdcd5db3SMike Capps      */
22725f0327eSMike Capps     void subscribeSensorsToServices();
228fdcd5db3SMike Capps 
229fdcd5db3SMike Capps     /**
230c95c527aSMatthew Barth      * @brief Retrieve the configured trust groups
231c95c527aSMatthew Barth      *
232c95c527aSMatthew Barth      * @param[in] jsonObj - JSON object to parse from
233c95c527aSMatthew Barth      *
234c95c527aSMatthew Barth      * @return List of functions applied on trust groups
235c95c527aSMatthew Barth      */
236c95c527aSMatthew Barth     const std::vector<CreateGroupFunction> getTrustGroups(const json& jsonObj);
237c95c527aSMatthew Barth 
238c95c527aSMatthew Barth     /**
239d06905c9SMatthew Barth      * @brief Set the trust manager's list of trust group functions
240d06905c9SMatthew Barth      *
241d06905c9SMatthew Barth      * @param[in] groupFuncs - list of trust group functions
242d06905c9SMatthew Barth      */
243d06905c9SMatthew Barth     void setTrustMgr(const std::vector<CreateGroupFunction>& groupFuncs);
244d06905c9SMatthew Barth 
245d06905c9SMatthew Barth     /**
246c95c527aSMatthew Barth      * @brief Retrieve the configured fan definitions
247c95c527aSMatthew Barth      *
248c95c527aSMatthew Barth      * @param[in] jsonObj - JSON object to parse from
249c95c527aSMatthew Barth      *
250c95c527aSMatthew Barth      * @return List of fan definition data on the fans configured
251c95c527aSMatthew Barth      */
252c95c527aSMatthew Barth     const std::vector<FanDefinition> getFanDefinitions(const json& jsonObj);
253d06905c9SMatthew Barth 
254d06905c9SMatthew Barth     /**
255d06905c9SMatthew Barth      * @brief Set the list of fans to be monitored
256d06905c9SMatthew Barth      *
257d06905c9SMatthew Barth      * @param[in] fanDefs - list of fan definitions to create fans monitored
258d06905c9SMatthew Barth      */
259d06905c9SMatthew Barth     void setFans(const std::vector<FanDefinition>& fanDefs);
260b63aa09eSMatt Spinler 
261b63aa09eSMatt Spinler     /**
262b63aa09eSMatt Spinler      * @brief Updates the fan health map entry for the fan passed in
263b63aa09eSMatt Spinler      *
264b63aa09eSMatt Spinler      * @param[in] fan - The fan to update the health map with
265b63aa09eSMatt Spinler      */
266b63aa09eSMatt Spinler     void updateFanHealth(const Fan& fan);
267e892e39aSMatt Spinler 
268e892e39aSMatt Spinler     /**
269fdcd5db3SMike Capps      * @brief callback when a tach sensor signal goes offline
270fdcd5db3SMike Capps      *
271fdcd5db3SMike Capps      * @param[in] msg - D-Bus message containing details (inc. service name)
272fdcd5db3SMike Capps      *
273fdcd5db3SMike Capps      * @param[in] sensorMap - map providing sensor access for each service
274fdcd5db3SMike Capps      */
275cb356d48SPatrick Williams     void tachSignalOffline(sdbusplus::message_t& msg,
276fdcd5db3SMike Capps                            const SensorMapType& sensorMap);
277fdcd5db3SMike Capps 
278fdcd5db3SMike Capps     /**
279e892e39aSMatt Spinler      * @brief The function that runs when the power state changes
280e892e39aSMatt Spinler      *
281e892e39aSMatt Spinler      * @param[in] powerStateOn - If power is now on or not
282e892e39aSMatt Spinler      */
283e892e39aSMatt Spinler     void powerStateChanged(bool powerStateOn);
284e892e39aSMatt Spinler 
285e892e39aSMatt Spinler     /**
286e892e39aSMatt Spinler      * @brief Reads the fault configuration from the JSON config
287e892e39aSMatt Spinler      *        file, such as the power off rule configuration.
288e892e39aSMatt Spinler      *
289e892e39aSMatt Spinler      * @param[in] jsonObj - JSON object to parse from
290e892e39aSMatt Spinler      */
291e892e39aSMatt Spinler     void setFaultConfig(const json& jsonObj);
292bb449c1cSMatt Spinler 
293bb449c1cSMatt Spinler     /**
294bb449c1cSMatt Spinler      * @brief Log an error and shut down due to an offline fan controller
295bb449c1cSMatt Spinler      */
296bb449c1cSMatt Spinler     void handleOfflineFanController();
297c95c527aSMatthew Barth };
298c95c527aSMatthew Barth 
299c95c527aSMatthew Barth } // namespace phosphor::fan::monitor
300