blob: 7de9bb38419c7564f5a0aac9ed100f341410b376 [file] [log] [blame]
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +05301#pragma once
2
William A. Kennington III73c2cfb2018-09-12 18:01:37 -07003#include <functional>
William A. Kennington III73c2cfb2018-09-12 18:01:37 -07004#include <optional>
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +05305#include <sdbusplus/bus.hpp>
6#include <sdbusplus/server/object.hpp>
William A. Kennington IIIf505fc02018-09-12 18:30:09 -07007#include <sdeventplus/event.hpp>
8#include <sdeventplus/utility/timer.hpp>
William A. Kennington III3bb2f402018-09-13 00:35:47 -07009#include <unordered_map>
William A. Kennington III73c2cfb2018-09-12 18:01:37 -070010#include <utility>
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053011#include <xyz/openbmc_project/State/Watchdog/server.hpp>
William A. Kennington III73c2cfb2018-09-12 18:01:37 -070012
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053013namespace phosphor
14{
15namespace watchdog
16{
William A. Kennington III3bb2f402018-09-13 00:35:47 -070017
Ofer Yehiellic35135d2019-06-14 11:30:25 -070018constexpr auto DEFAULT_MIN_INTERVAL_MS = 0;
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053019namespace Base = sdbusplus::xyz::openbmc_project::State::server;
20using WatchdogInherits = sdbusplus::server::object::object<Base::Watchdog>;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053021
22/** @class Watchdog
23 * @brief OpenBMC watchdog implementation.
24 * @details A concrete implementation for the
25 * xyz.openbmc_project.State.Watchdog DBus API.
26 */
27class Watchdog : public WatchdogInherits
28{
Patrick Venture8f6c5152018-09-11 17:45:33 -070029 public:
30 Watchdog() = delete;
31 ~Watchdog() = default;
32 Watchdog(const Watchdog&) = delete;
33 Watchdog& operator=(const Watchdog&) = delete;
34 Watchdog(Watchdog&&) = delete;
35 Watchdog& operator=(Watchdog&&) = delete;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053036
Patrick Venture8f6c5152018-09-11 17:45:33 -070037 /** @brief Type used to hold the name of a systemd target.
38 */
39 using TargetName = std::string;
William A. Kennington III1232a152018-02-02 15:57:34 -080040
William A. Kennington III3bb2f402018-09-13 00:35:47 -070041 /** @brief Type used to store the mapping of a Watchdog timeout
42 * action to a systemd target.
43 */
44 using ActionTargetMap = std::unordered_map<Action, TargetName>;
45
Patrick Venture8f6c5152018-09-11 17:45:33 -070046 /** @brief Type used to specify the parameters of a fallback watchdog
47 */
48 struct Fallback
49 {
50 Action action;
51 uint64_t interval;
52 bool always;
53 };
William A. Kennington IIId1331082018-02-27 18:47:05 -080054
Patrick Venture8f6c5152018-09-11 17:45:33 -070055 /** @brief Constructs the Watchdog object
56 *
William A. Kennington IIIf505fc02018-09-12 18:30:09 -070057 * @param[in] bus - DBus bus to attach to.
58 * @param[in] objPath - Object path to attach to.
59 * @param[in] event - reference to sdeventplus::Event loop
60 * @param[in] actionTargets - map of systemd targets called on timeout
Patrick Venture8f6c5152018-09-11 17:45:33 -070061 * @param[in] fallback
62 */
William A. Kennington IIIf505fc02018-09-12 18:30:09 -070063 Watchdog(sdbusplus::bus::bus& bus, const char* objPath,
64 const sdeventplus::Event& event,
William A. Kennington III3bb2f402018-09-13 00:35:47 -070065 ActionTargetMap&& actionTargetMap = {},
Ofer Yehiellic35135d2019-06-14 11:30:25 -070066 std::optional<Fallback>&& fallback = std::nullopt,
67 uint64_t minInterval = DEFAULT_MIN_INTERVAL_MS) :
Patrick Venture8f6c5152018-09-11 17:45:33 -070068 WatchdogInherits(bus, objPath),
William A. Kennington III3bb2f402018-09-13 00:35:47 -070069 bus(bus), actionTargetMap(std::move(actionTargetMap)),
Ofer Yehiellic35135d2019-06-14 11:30:25 -070070 fallback(std::move(fallback)), minInterval(minInterval),
Patrick Venture8f6c5152018-09-11 17:45:33 -070071 timer(event, std::bind(&Watchdog::timeOutHandler, this))
72 {
Ofer Yehiellic35135d2019-06-14 11:30:25 -070073 // We set the watchdog interval with the default value.
74 interval(interval());
Patrick Venture8f6c5152018-09-11 17:45:33 -070075 // We need to poke the enable mechanism to make sure that the timer
76 // enters the fallback state if the fallback is always enabled.
77 tryFallbackOrDisable();
78 }
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053079
Patrick Venture8f6c5152018-09-11 17:45:33 -070080 /** @brief Resets the TimeRemaining to the configured Interval
81 * Optionally enables the watchdog.
82 *
83 * @param[in] enableWatchdog - Should the call enable the watchdog
84 */
85 void resetTimeRemaining(bool enableWatchdog) override;
William A. Kennington III1726df62018-04-23 10:28:28 -070086
Patrick Venture8f6c5152018-09-11 17:45:33 -070087 /** @brief Since we are overriding the setter-enabled but not the
88 * getter-enabled, we need to have this using in order to
89 * allow passthrough usage of the getter-enabled.
90 */
91 using Base::Watchdog::enabled;
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053092
Patrick Venture8f6c5152018-09-11 17:45:33 -070093 /** @brief Enable or disable watchdog
94 * If a watchdog state is changed from disable to enable,
95 * the watchdog timer is set with the default expiration
96 * interval and it starts counting down.
97 * If a watchdog is already enabled, setting @value to true
98 * has no effect.
99 *
100 * @param[in] value - 'true' to enable. 'false' to disable
101 *
102 * @return : applied value if success, previous value otherwise
103 */
104 bool enabled(bool value) override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530105
Patrick Venture8f6c5152018-09-11 17:45:33 -0700106 /** @brief Gets the remaining time before watchdog expires.
107 *
108 * @return 0 if watchdog is expired.
109 * Remaining time in milliseconds otherwise.
110 */
111 uint64_t timeRemaining() const override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530112
Patrick Venture8f6c5152018-09-11 17:45:33 -0700113 /** @brief Reset timer to expire after new timeout in milliseconds.
114 *
115 * @param[in] value - the time in milliseconds after which
116 * the watchdog will expire
117 *
118 * @return: updated timeout value if watchdog is enabled.
119 * 0 otherwise.
120 */
121 uint64_t timeRemaining(uint64_t value) override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530122
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700123 /** @brief Get value of Interval
124 *
125 *
126 * @return: current interval
127 *
128 */
129 using WatchdogInherits::interval;
130
131 /** @brief Set value of Interval
132 *
133 * @param[in] value - interval time to set
134 *
135 * @return: interval that was set
136 *
137 */
138 uint64_t interval(uint64_t value);
139
Patrick Venture8f6c5152018-09-11 17:45:33 -0700140 /** @brief Tells if the referenced timer is expired or not */
141 inline auto timerExpired() const
142 {
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700143 return timer.hasExpired();
Patrick Venture8f6c5152018-09-11 17:45:33 -0700144 }
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530145
Patrick Venture8f6c5152018-09-11 17:45:33 -0700146 /** @brief Tells if the timer is running or not */
147 inline bool timerEnabled() const
148 {
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700149 return timer.isEnabled();
Patrick Venture8f6c5152018-09-11 17:45:33 -0700150 }
William A. Kennington III0650a3f2018-03-01 10:53:25 -0800151
Patrick Venture8f6c5152018-09-11 17:45:33 -0700152 private:
153 /** @brief sdbusplus handle */
154 sdbusplus::bus::bus& bus;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530155
Patrick Venture8f6c5152018-09-11 17:45:33 -0700156 /** @brief Map of systemd units to be started when the timer expires */
William A. Kennington III3bb2f402018-09-13 00:35:47 -0700157 ActionTargetMap actionTargetMap;
Vishwanatha Subbanna3473d702017-05-30 16:38:50 +0530158
Patrick Venture8f6c5152018-09-11 17:45:33 -0700159 /** @brief Fallback timer options */
William A. Kennington III73c2cfb2018-09-12 18:01:37 -0700160 std::optional<Fallback> fallback;
William A. Kennington IIId1331082018-02-27 18:47:05 -0800161
Ofer Yehiellic35135d2019-06-14 11:30:25 -0700162 /** @brief Minimum watchdog interval value */
163 uint64_t minInterval;
164
Patrick Venture8f6c5152018-09-11 17:45:33 -0700165 /** @brief Contained timer object */
William A. Kennington IIIf505fc02018-09-12 18:30:09 -0700166 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +0530167
Patrick Venture8f6c5152018-09-11 17:45:33 -0700168 /** @brief Optional Callback handler on timer expirartion */
169 void timeOutHandler();
William A. Kennington III825f4982018-02-27 19:10:56 -0800170
Patrick Venture8f6c5152018-09-11 17:45:33 -0700171 /** @brief Attempt to enter the fallback watchdog or disables it */
172 void tryFallbackOrDisable();
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530173};
174
175} // namespace watchdog
176} // namespace phosphor