xref: /openbmc/phosphor-fan-presence/sensor-monitor/shutdown_alarm_monitor.hpp (revision 4fa67aa12bd73f7d528225f0c3c93c3242bbcc23)
19c0715b6SMatt Spinler /**
29c0715b6SMatt Spinler  * Copyright © 2021 IBM Corporation
39c0715b6SMatt Spinler  *
49c0715b6SMatt Spinler  * Licensed under the Apache License, Version 2.0 (the "License");
59c0715b6SMatt Spinler  * you may not use this file except in compliance with the License.
69c0715b6SMatt Spinler  * You may obtain a copy of the License at
79c0715b6SMatt Spinler  *
89c0715b6SMatt Spinler  *     http://www.apache.org/licenses/LICENSE-2.0
99c0715b6SMatt Spinler  *
109c0715b6SMatt Spinler  * Unless required by applicable law or agreed to in writing, software
119c0715b6SMatt Spinler  * distributed under the License is distributed on an "AS IS" BASIS,
129c0715b6SMatt Spinler  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139c0715b6SMatt Spinler  * See the License for the specific language governing permissions and
149c0715b6SMatt Spinler  * limitations under the License.
159c0715b6SMatt Spinler  */
169c0715b6SMatt Spinler #pragma once
1708a66efaSMatt Spinler #include "alarm_timestamps.hpp"
189c0715b6SMatt Spinler #include "power_state.hpp"
199c0715b6SMatt Spinler #include "types.hpp"
209c0715b6SMatt Spinler 
219c0715b6SMatt Spinler #include <sdbusplus/bus.hpp>
229c0715b6SMatt Spinler #include <sdbusplus/bus/match.hpp>
239c0715b6SMatt Spinler #include <sdeventplus/clock.hpp>
249c0715b6SMatt Spinler #include <sdeventplus/event.hpp>
259c0715b6SMatt Spinler #include <sdeventplus/utility/timer.hpp>
269c0715b6SMatt Spinler 
270b839516SMatt Spinler #include <chrono>
280b839516SMatt Spinler #include <optional>
290b839516SMatt Spinler 
309c0715b6SMatt Spinler namespace sensor::monitor
319c0715b6SMatt Spinler {
329c0715b6SMatt Spinler 
339c0715b6SMatt Spinler /**
349c0715b6SMatt Spinler  * @class ShutdownAlarmMonitor
359c0715b6SMatt Spinler  *
369c0715b6SMatt Spinler  * This class finds all instances of the D-Bus interfaces
379c0715b6SMatt Spinler  *   xyz.openbmc_project.Sensor.Threshold.SoftShutdown
389c0715b6SMatt Spinler  *   xyz.openbmc_project.Sensor.Threshold.HardShutdown
399c0715b6SMatt Spinler  *
409c0715b6SMatt Spinler  * and then watches the high and low alarm properties.  If they trip
419c0715b6SMatt Spinler  * the code will start a timer, at the end of which the system will
429c0715b6SMatt Spinler  * be shut down.  The timer values can be modified with configure.ac
439c0715b6SMatt Spinler  * options.  If the alarm is cleared before the timer expires, then
449c0715b6SMatt Spinler  * the timer is stopped.
459c0715b6SMatt Spinler  *
469c0715b6SMatt Spinler  * Event logs are also created when the alarms trip and clear.
479c0715b6SMatt Spinler  *
489c0715b6SMatt Spinler  * Note that the SoftShutdown alarm code actually implements a hard shutdown.
499c0715b6SMatt Spinler  * This is because in the system this is being written for, the host is
509c0715b6SMatt Spinler  * driving the shutdown process (i.e. doing a soft shutdown) based on an alert
519c0715b6SMatt Spinler  * it receives via another channel.  If the soft shutdown timer expires, it
529c0715b6SMatt Spinler  * means that the host didn't do a soft shutdown in the time allowed and
539c0715b6SMatt Spinler  * now a hard shutdown is required.  This behavior could be modified with
549c0715b6SMatt Spinler  * compile flags if anyone needs a different behavior in the future.
559c0715b6SMatt Spinler  */
569c0715b6SMatt Spinler class ShutdownAlarmMonitor
579c0715b6SMatt Spinler {
589c0715b6SMatt Spinler   public:
599c0715b6SMatt Spinler     ShutdownAlarmMonitor() = delete;
609c0715b6SMatt Spinler     ~ShutdownAlarmMonitor() = default;
619c0715b6SMatt Spinler     ShutdownAlarmMonitor(const ShutdownAlarmMonitor&) = delete;
629c0715b6SMatt Spinler     ShutdownAlarmMonitor& operator=(const ShutdownAlarmMonitor&) = delete;
639c0715b6SMatt Spinler     ShutdownAlarmMonitor(ShutdownAlarmMonitor&&) = delete;
649c0715b6SMatt Spinler     ShutdownAlarmMonitor& operator=(ShutdownAlarmMonitor&&) = delete;
659c0715b6SMatt Spinler 
669c0715b6SMatt Spinler     /**
679c0715b6SMatt Spinler      * @brief Constructor
689c0715b6SMatt Spinler      *
699c0715b6SMatt Spinler      * @param[in] bus - The sdbusplus bus object
709c0715b6SMatt Spinler      * @param[in] event - The sdeventplus event object
717f6946b2SMatt Spinler      * @param[in] powerState - The PowerState object
729c0715b6SMatt Spinler      */
73cb356d48SPatrick Williams     ShutdownAlarmMonitor(sdbusplus::bus_t& bus, sdeventplus::Event& event,
747f6946b2SMatt Spinler                          std::shared_ptr<phosphor::fan::PowerState> powerState);
759c0715b6SMatt Spinler 
769c0715b6SMatt Spinler   private:
779c0715b6SMatt Spinler     /**
789c0715b6SMatt Spinler      * @brief The propertiesChanged handled for the shutdown interfaces.
799c0715b6SMatt Spinler      *
809c0715b6SMatt Spinler      * If the power is on, the new alarm values will be checked to see
819c0715b6SMatt Spinler      * if the shutdown timer needs to be started or stopped.
829c0715b6SMatt Spinler      */
83cb356d48SPatrick Williams     void propertiesChanged(sdbusplus::message_t& message);
849c0715b6SMatt Spinler 
859c0715b6SMatt Spinler     /**
869c0715b6SMatt Spinler      * @brief Checks an alarm value to see if a shutdown timer needs
879c0715b6SMatt Spinler      *        to be started or stopped.
889c0715b6SMatt Spinler      *
899c0715b6SMatt Spinler      * If the alarm is on and the timer isn't running, start it.
909c0715b6SMatt Spinler      * If the alarm is off and the timer is running, stop it.
919c0715b6SMatt Spinler      *
929c0715b6SMatt Spinler      * @param[in] value - The alarm property value
939c0715b6SMatt Spinler      * @param[in] alarmKey - The alarm key
949c0715b6SMatt Spinler      */
959c0715b6SMatt Spinler     void checkAlarm(bool value, const AlarmKey& alarmKey);
969c0715b6SMatt Spinler 
979c0715b6SMatt Spinler     /**
989c0715b6SMatt Spinler      * @brief Checks all currently known alarm properties on D-Bus.
999c0715b6SMatt Spinler      *
1009c0715b6SMatt Spinler      * May result in starting or stopping shutdown timers.
1019c0715b6SMatt Spinler      */
1029c0715b6SMatt Spinler     void checkAlarms();
1039c0715b6SMatt Spinler 
1049c0715b6SMatt Spinler     /**
1059c0715b6SMatt Spinler      * @brief Finds all shutdown alarm interfaces currently on
1069c0715b6SMatt Spinler      *        D-Bus and adds them to the alarms map.
1079c0715b6SMatt Spinler      */
1089c0715b6SMatt Spinler     void findAlarms();
1099c0715b6SMatt Spinler 
1109c0715b6SMatt Spinler     /**
1110b839516SMatt Spinler      * @brief Starts a shutdown timer.
1120b839516SMatt Spinler      *
1130b839516SMatt Spinler      * @param[in] alarmKey - The alarm key
1140b839516SMatt Spinler      */
1150b839516SMatt Spinler     void startTimer(const AlarmKey& alarmKey);
1160b839516SMatt Spinler 
1170b839516SMatt Spinler     /**
1180b839516SMatt Spinler      * @brief Stops a shutdown timer.
1190b839516SMatt Spinler      *
1200b839516SMatt Spinler      * @param[in] alarmKey - The alarm key
1210b839516SMatt Spinler      */
1220b839516SMatt Spinler     void stopTimer(const AlarmKey& alarmKey);
1230b839516SMatt Spinler 
1240b839516SMatt Spinler     /**
1250b839516SMatt Spinler      * @brief The function called when the timer expires.
1260b839516SMatt Spinler      *
1270b839516SMatt Spinler      * @param[in] alarmKey - The alarm key
1280b839516SMatt Spinler      */
1290b839516SMatt Spinler     void timerExpired(const AlarmKey& alarmKey);
1300b839516SMatt Spinler 
1310b839516SMatt Spinler     /**
1329c0715b6SMatt Spinler      * @brief The power state changed handler.
1339c0715b6SMatt Spinler      *
1349c0715b6SMatt Spinler      * Checks alarms when power is turned on, and clears
1359c0715b6SMatt Spinler      * any running timers on a power off.
1369c0715b6SMatt Spinler      *
1379c0715b6SMatt Spinler      * @param[in] powerStateOn - If the power is now on or off.
1389c0715b6SMatt Spinler      */
1399c0715b6SMatt Spinler     void powerStateChanged(bool powerStateOn);
1409c0715b6SMatt Spinler 
1419c0715b6SMatt Spinler     /**
14216c7dc1eSMatt Spinler      * @brief Returns the ShutdownType for the passed in interface
14316c7dc1eSMatt Spinler      *
14416c7dc1eSMatt Spinler      * @param[in] interface - The D-Bus interface name
14516c7dc1eSMatt Spinler      * @return The interface, or std::nullopt if the interface isn't one
14616c7dc1eSMatt Spinler      *         of the shutdown interfaces.
14716c7dc1eSMatt Spinler      */
148*4fa67aa1SPatrick Williams     std::optional<ShutdownType> getShutdownType(
149*4fa67aa1SPatrick Williams         const std::string& interface) const;
15016c7dc1eSMatt Spinler 
15116c7dc1eSMatt Spinler     /**
152ffd54674SMatt Spinler      * @brief Creates a phosphor-logging event log
153ffd54674SMatt Spinler      *
154ffd54674SMatt Spinler      * @param[in] alarmKey - The alarm key
155ffd54674SMatt Spinler      * @param[in] alarmValue - The alarm property value
156ffd54674SMatt Spinler      * @param[in] sensorValue - The sensor value behind the alarm.
1572a6b39c8SMatt Spinler      * @param[in] isPowerOffError - If this is committed at the time of the
1582a6b39c8SMatt Spinler      *                              power off.
159ffd54674SMatt Spinler      */
160ffd54674SMatt Spinler     void createEventLog(const AlarmKey& alarmKey, bool alarmValue,
1612a6b39c8SMatt Spinler                         const std::optional<double>& sensorValue,
1622a6b39c8SMatt Spinler                         bool isPowerOffError = false);
163ffd54674SMatt Spinler 
164ffd54674SMatt Spinler     /**
165683a96c6SMike Capps      * @brief Create a BMC Dump
166683a96c6SMike Capps      */
167683a96c6SMike Capps     void createBmcDump() const;
168683a96c6SMike Capps 
169683a96c6SMike Capps     /**
1709c0715b6SMatt Spinler      * @brief The sdbusplus bus object
1719c0715b6SMatt Spinler      */
172cb356d48SPatrick Williams     sdbusplus::bus_t& bus;
1739c0715b6SMatt Spinler 
1749c0715b6SMatt Spinler     /**
1759c0715b6SMatt Spinler      * @brief The sdeventplus Event object
1769c0715b6SMatt Spinler      */
1779c0715b6SMatt Spinler     sdeventplus::Event& event;
1789c0715b6SMatt Spinler 
1799c0715b6SMatt Spinler     /**
1807f6946b2SMatt Spinler      * @brief The PowerState object to track power state changes.
1817f6946b2SMatt Spinler      */
1827f6946b2SMatt Spinler     std::shared_ptr<phosphor::fan::PowerState> _powerState;
1837f6946b2SMatt Spinler 
1847f6946b2SMatt Spinler     /**
1859c0715b6SMatt Spinler      * @brief The match for properties changing on the HardShutdown
1869c0715b6SMatt Spinler      *        interface.
1879c0715b6SMatt Spinler      */
188cb356d48SPatrick Williams     sdbusplus::bus::match_t hardShutdownMatch;
1899c0715b6SMatt Spinler 
1909c0715b6SMatt Spinler     /**
1919c0715b6SMatt Spinler      * @brief The match for properties changing on the SoftShutdown
1929c0715b6SMatt Spinler      *        interface.
1939c0715b6SMatt Spinler      */
194cb356d48SPatrick Williams     sdbusplus::bus::match_t softShutdownMatch;
1959c0715b6SMatt Spinler 
1969c0715b6SMatt Spinler     /**
1979c0715b6SMatt Spinler      * @brief The map of alarms.
1989c0715b6SMatt Spinler      */
1999c0715b6SMatt Spinler     std::map<AlarmKey, std::unique_ptr<sdeventplus::utility::Timer<
2009c0715b6SMatt Spinler                            sdeventplus::ClockId::Monotonic>>>
2019c0715b6SMatt Spinler         alarms;
20208a66efaSMatt Spinler 
20308a66efaSMatt Spinler     /**
20408a66efaSMatt Spinler      * @brief The running alarm timer timestamps.
20508a66efaSMatt Spinler      */
20608a66efaSMatt Spinler     AlarmTimestamps timestamps;
2079c0715b6SMatt Spinler };
2089c0715b6SMatt Spinler 
2099c0715b6SMatt Spinler } // namespace sensor::monitor
210