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 class ShutdownAlarmMonitor 57 { 58 public: 59 ShutdownAlarmMonitor() = delete; 60 ~ShutdownAlarmMonitor() = default; 61 ShutdownAlarmMonitor(const ShutdownAlarmMonitor&) = delete; 62 ShutdownAlarmMonitor& operator=(const ShutdownAlarmMonitor&) = delete; 63 ShutdownAlarmMonitor(ShutdownAlarmMonitor&&) = delete; 64 ShutdownAlarmMonitor& operator=(ShutdownAlarmMonitor&&) = delete; 65 66 /** 67 * @brief Constructor 68 * 69 * @param[in] bus - The sdbusplus bus object 70 * @param[in] event - The sdeventplus event object 71 * @param[in] powerState - The PowerState object 72 */ 73 ShutdownAlarmMonitor(sdbusplus::bus::bus& bus, sdeventplus::Event& event, 74 std::shared_ptr<phosphor::fan::PowerState> powerState); 75 76 private: 77 /** 78 * @brief The propertiesChanged handled for the shutdown interfaces. 79 * 80 * If the power is on, the new alarm values will be checked to see 81 * if the shutdown timer needs to be started or stopped. 82 */ 83 void propertiesChanged(sdbusplus::message::message& message); 84 85 /** 86 * @brief Checks an alarm value to see if a shutdown timer needs 87 * to be started or stopped. 88 * 89 * If the alarm is on and the timer isn't running, start it. 90 * If the alarm is off and the timer is running, stop it. 91 * 92 * @param[in] value - The alarm property value 93 * @param[in] alarmKey - The alarm key 94 */ 95 void checkAlarm(bool value, const AlarmKey& alarmKey); 96 97 /** 98 * @brief Checks all currently known alarm properties on D-Bus. 99 * 100 * May result in starting or stopping shutdown timers. 101 */ 102 void checkAlarms(); 103 104 /** 105 * @brief Finds all shutdown alarm interfaces currently on 106 * D-Bus and adds them to the alarms map. 107 */ 108 void findAlarms(); 109 110 /** 111 * @brief Starts a shutdown timer. 112 * 113 * @param[in] alarmKey - The alarm key 114 */ 115 void startTimer(const AlarmKey& alarmKey); 116 117 /** 118 * @brief Stops a shutdown timer. 119 * 120 * @param[in] alarmKey - The alarm key 121 */ 122 void stopTimer(const AlarmKey& alarmKey); 123 124 /** 125 * @brief The function called when the timer expires. 126 * 127 * @param[in] alarmKey - The alarm key 128 */ 129 void timerExpired(const AlarmKey& alarmKey); 130 131 /** 132 * @brief The power state changed handler. 133 * 134 * Checks alarms when power is turned on, and clears 135 * any running timers on a power off. 136 * 137 * @param[in] powerStateOn - If the power is now on or off. 138 */ 139 void powerStateChanged(bool powerStateOn); 140 141 /** 142 * @brief Returns the ShutdownType for the passed in interface 143 * 144 * @param[in] interface - The D-Bus interface name 145 * @return The interface, or std::nullopt if the interface isn't one 146 * of the shutdown interfaces. 147 */ 148 std::optional<ShutdownType> 149 getShutdownType(const std::string& interface) const; 150 151 /** 152 * @brief Creates a phosphor-logging event log 153 * 154 * @param[in] alarmKey - The alarm key 155 * @param[in] alarmValue - The alarm property value 156 * @param[in] sensorValue - The sensor value behind the alarm. 157 * @param[in] isPowerOffError - If this is committed at the time of the 158 * power off. 159 */ 160 void createEventLog(const AlarmKey& alarmKey, bool alarmValue, 161 const std::optional<double>& sensorValue, 162 bool isPowerOffError = false); 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 PowerState object to track power state changes. 176 */ 177 std::shared_ptr<phosphor::fan::PowerState> _powerState; 178 179 /** 180 * @brief The match for properties changing on the HardShutdown 181 * interface. 182 */ 183 sdbusplus::bus::match::match hardShutdownMatch; 184 185 /** 186 * @brief The match for properties changing on the SoftShutdown 187 * interface. 188 */ 189 sdbusplus::bus::match::match softShutdownMatch; 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