1 /** 2 * Copyright © 2021 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 #include "alarm_timestamps.hpp" 18 #include "power_state.hpp" 19 #include "types.hpp" 20 21 #include <sdbusplus/bus.hpp> 22 #include <sdbusplus/bus/match.hpp> 23 #include <sdeventplus/clock.hpp> 24 #include <sdeventplus/event.hpp> 25 #include <sdeventplus/utility/timer.hpp> 26 27 #include <chrono> 28 #include <optional> 29 30 namespace sensor::monitor 31 { 32 33 /** 34 * @class ShutdownAlarmMonitor 35 * 36 * This class finds all instances of the D-Bus interfaces 37 * xyz.openbmc_project.Sensor.Threshold.SoftShutdown 38 * xyz.openbmc_project.Sensor.Threshold.HardShutdown 39 * 40 * and then watches the high and low alarm properties. If they trip 41 * the code will start a timer, at the end of which the system will 42 * be shut down. The timer values can be modified with configure.ac 43 * options. If the alarm is cleared before the timer expires, then 44 * the timer is stopped. 45 * 46 * Event logs are also created when the alarms trip and clear. 47 * 48 * Note that the SoftShutdown alarm code actually implements a hard shutdown. 49 * This is because in the system this is being written for, the host is 50 * driving the shutdown process (i.e. doing a soft shutdown) based on an alert 51 * it receives via another channel. If the soft shutdown timer expires, it 52 * means that the host didn't do a soft shutdown in the time allowed and 53 * now a hard shutdown is required. This behavior could be modified with 54 * compile flags if anyone needs a different behavior in the future. 55 * 56 * It currently uses the PGoodState class to check for power state. 57 * If a different property is ever desired, a new class can be 58 * derived from PowerState and a compile option can be used. 59 * 60 */ 61 class ShutdownAlarmMonitor 62 { 63 public: 64 ShutdownAlarmMonitor() = delete; 65 ~ShutdownAlarmMonitor() = default; 66 ShutdownAlarmMonitor(const ShutdownAlarmMonitor&) = delete; 67 ShutdownAlarmMonitor& operator=(const ShutdownAlarmMonitor&) = delete; 68 ShutdownAlarmMonitor(ShutdownAlarmMonitor&&) = delete; 69 ShutdownAlarmMonitor& operator=(ShutdownAlarmMonitor&&) = delete; 70 71 /** 72 * @brief Constructor 73 * 74 * @param[in] bus - The sdbusplus bus object 75 * @param[in] event - The sdeventplus event object 76 */ 77 ShutdownAlarmMonitor(sdbusplus::bus::bus& bus, sdeventplus::Event& event); 78 79 private: 80 /** 81 * @brief The propertiesChanged handled for the shutdown interfaces. 82 * 83 * If the power is on, the new alarm values will be checked to see 84 * if the shutdown timer needs to be started or stopped. 85 */ 86 void propertiesChanged(sdbusplus::message::message& message); 87 88 /** 89 * @brief Checks an alarm value to see if a shutdown timer needs 90 * to be started or stopped. 91 * 92 * If the alarm is on and the timer isn't running, start it. 93 * If the alarm is off and the timer is running, stop it. 94 * 95 * @param[in] value - The alarm property value 96 * @param[in] alarmKey - The alarm key 97 */ 98 void checkAlarm(bool value, const AlarmKey& alarmKey); 99 100 /** 101 * @brief Checks all currently known alarm properties on D-Bus. 102 * 103 * May result in starting or stopping shutdown timers. 104 */ 105 void checkAlarms(); 106 107 /** 108 * @brief Finds all shutdown alarm interfaces currently on 109 * D-Bus and adds them to the alarms map. 110 */ 111 void findAlarms(); 112 113 /** 114 * @brief Starts a shutdown timer. 115 * 116 * @param[in] alarmKey - The alarm key 117 */ 118 void startTimer(const AlarmKey& alarmKey); 119 120 /** 121 * @brief Stops a shutdown timer. 122 * 123 * @param[in] alarmKey - The alarm key 124 */ 125 void stopTimer(const AlarmKey& alarmKey); 126 127 /** 128 * @brief The function called when the timer expires. 129 * 130 * @param[in] alarmKey - The alarm key 131 */ 132 void timerExpired(const AlarmKey& alarmKey); 133 134 /** 135 * @brief The power state changed handler. 136 * 137 * Checks alarms when power is turned on, and clears 138 * any running timers on a power off. 139 * 140 * @param[in] powerStateOn - If the power is now on or off. 141 */ 142 void powerStateChanged(bool powerStateOn); 143 144 /** 145 * @brief Returns the ShutdownType for the passed in interface 146 * 147 * @param[in] interface - The D-Bus interface name 148 * @return The interface, or std::nullopt if the interface isn't one 149 * of the shutdown interfaces. 150 */ 151 std::optional<ShutdownType> 152 getShutdownType(const std::string& interface) const; 153 154 /** 155 * @brief Creates a phosphor-logging event log 156 * 157 * @param[in] alarmKey - The alarm key 158 * @param[in] alarmValue - The alarm property value 159 * @param[in] sensorValue - The sensor value behind the alarm. 160 */ 161 void createEventLog(const AlarmKey& alarmKey, bool alarmValue, 162 const std::optional<double>& sensorValue); 163 164 /** 165 * @brief The sdbusplus bus object 166 */ 167 sdbusplus::bus::bus& bus; 168 169 /** 170 * @brief The sdeventplus Event object 171 */ 172 sdeventplus::Event& event; 173 174 /** 175 * @brief The match for properties changing on the HardShutdown 176 * interface. 177 */ 178 sdbusplus::bus::match::match hardShutdownMatch; 179 180 /** 181 * @brief The match for properties changing on the SoftShutdown 182 * interface. 183 */ 184 sdbusplus::bus::match::match softShutdownMatch; 185 186 /** 187 * @brief The PowerState object to track power state changes. 188 */ 189 std::unique_ptr<phosphor::fan::PowerState> _powerState; 190 191 /** 192 * @brief The map of alarms. 193 */ 194 std::map<AlarmKey, std::unique_ptr<sdeventplus::utility::Timer< 195 sdeventplus::ClockId::Monotonic>>> 196 alarms; 197 198 /** 199 * @brief The running alarm timer timestamps. 200 */ 201 AlarmTimestamps timestamps; 202 }; 203 204 } // namespace sensor::monitor 205