blob: c9821db8a225778c3ade981261fb234d111adfb8 [file] [log] [blame]
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +05301#pragma once
2
Patrick Venture8f6c5152018-09-11 17:45:33 -07003#include "timer.hpp"
4
William A. Kennington III73c2cfb2018-09-12 18:01:37 -07005#include <functional>
William A. Kennington III73c2cfb2018-09-12 18:01:37 -07006#include <optional>
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +05307#include <sdbusplus/bus.hpp>
8#include <sdbusplus/server/object.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
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053018namespace Base = sdbusplus::xyz::openbmc_project::State::server;
19using WatchdogInherits = sdbusplus::server::object::object<Base::Watchdog>;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053020
21/** @class Watchdog
22 * @brief OpenBMC watchdog implementation.
23 * @details A concrete implementation for the
24 * xyz.openbmc_project.State.Watchdog DBus API.
25 */
26class Watchdog : public WatchdogInherits
27{
Patrick Venture8f6c5152018-09-11 17:45:33 -070028 public:
29 Watchdog() = delete;
30 ~Watchdog() = default;
31 Watchdog(const Watchdog&) = delete;
32 Watchdog& operator=(const Watchdog&) = delete;
33 Watchdog(Watchdog&&) = delete;
34 Watchdog& operator=(Watchdog&&) = delete;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053035
Patrick Venture8f6c5152018-09-11 17:45:33 -070036 /** @brief Type used to hold the name of a systemd target.
37 */
38 using TargetName = std::string;
William A. Kennington III1232a152018-02-02 15:57:34 -080039
William A. Kennington III3bb2f402018-09-13 00:35:47 -070040 /** @brief Type used to store the mapping of a Watchdog timeout
41 * action to a systemd target.
42 */
43 using ActionTargetMap = std::unordered_map<Action, TargetName>;
44
Patrick Venture8f6c5152018-09-11 17:45:33 -070045 /** @brief Type used to specify the parameters of a fallback watchdog
46 */
47 struct Fallback
48 {
49 Action action;
50 uint64_t interval;
51 bool always;
52 };
William A. Kennington IIId1331082018-02-27 18:47:05 -080053
Patrick Venture8f6c5152018-09-11 17:45:33 -070054 /** @brief Constructs the Watchdog object
55 *
William A. Kennington III3bb2f402018-09-13 00:35:47 -070056 * @param[in] bus - DBus bus to attach to.
57 * @param[in] objPath - Object path to attach to.
58 * @param[in] event - reference to sd_event unique pointer
59 * @param[in] actionTargetMap - map of systemd targets called on timeout
Patrick Venture8f6c5152018-09-11 17:45:33 -070060 * @param[in] fallback
61 */
62 Watchdog(sdbusplus::bus::bus& bus, const char* objPath, EventPtr& event,
William A. Kennington III3bb2f402018-09-13 00:35:47 -070063 ActionTargetMap&& actionTargetMap = {},
William A. Kennington III73c2cfb2018-09-12 18:01:37 -070064 std::optional<Fallback>&& fallback = std::nullopt) :
Patrick Venture8f6c5152018-09-11 17:45:33 -070065 WatchdogInherits(bus, objPath),
William A. Kennington III3bb2f402018-09-13 00:35:47 -070066 bus(bus), actionTargetMap(std::move(actionTargetMap)),
Patrick Venture8f6c5152018-09-11 17:45:33 -070067 fallback(std::move(fallback)),
68 timer(event, std::bind(&Watchdog::timeOutHandler, this))
69 {
70 // We need to poke the enable mechanism to make sure that the timer
71 // enters the fallback state if the fallback is always enabled.
72 tryFallbackOrDisable();
73 }
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +053074
Patrick Venture8f6c5152018-09-11 17:45:33 -070075 /** @brief Resets the TimeRemaining to the configured Interval
76 * Optionally enables the watchdog.
77 *
78 * @param[in] enableWatchdog - Should the call enable the watchdog
79 */
80 void resetTimeRemaining(bool enableWatchdog) override;
William A. Kennington III1726df62018-04-23 10:28:28 -070081
Patrick Venture8f6c5152018-09-11 17:45:33 -070082 /** @brief Since we are overriding the setter-enabled but not the
83 * getter-enabled, we need to have this using in order to
84 * allow passthrough usage of the getter-enabled.
85 */
86 using Base::Watchdog::enabled;
Vishwanatha Subbanna00bd3772017-05-31 14:53:42 +053087
Patrick Venture8f6c5152018-09-11 17:45:33 -070088 /** @brief Enable or disable watchdog
89 * If a watchdog state is changed from disable to enable,
90 * the watchdog timer is set with the default expiration
91 * interval and it starts counting down.
92 * If a watchdog is already enabled, setting @value to true
93 * has no effect.
94 *
95 * @param[in] value - 'true' to enable. 'false' to disable
96 *
97 * @return : applied value if success, previous value otherwise
98 */
99 bool enabled(bool value) override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530100
Patrick Venture8f6c5152018-09-11 17:45:33 -0700101 /** @brief Gets the remaining time before watchdog expires.
102 *
103 * @return 0 if watchdog is expired.
104 * Remaining time in milliseconds otherwise.
105 */
106 uint64_t timeRemaining() const override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530107
Patrick Venture8f6c5152018-09-11 17:45:33 -0700108 /** @brief Reset timer to expire after new timeout in milliseconds.
109 *
110 * @param[in] value - the time in milliseconds after which
111 * the watchdog will expire
112 *
113 * @return: updated timeout value if watchdog is enabled.
114 * 0 otherwise.
115 */
116 uint64_t timeRemaining(uint64_t value) override;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530117
Patrick Venture8f6c5152018-09-11 17:45:33 -0700118 /** @brief Tells if the referenced timer is expired or not */
119 inline auto timerExpired() const
120 {
121 return timer.expired();
122 }
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530123
Patrick Venture8f6c5152018-09-11 17:45:33 -0700124 /** @brief Tells if the timer is running or not */
125 inline bool timerEnabled() const
126 {
127 return timer.getEnabled() != SD_EVENT_OFF;
128 }
William A. Kennington III0650a3f2018-03-01 10:53:25 -0800129
Patrick Venture8f6c5152018-09-11 17:45:33 -0700130 private:
131 /** @brief sdbusplus handle */
132 sdbusplus::bus::bus& bus;
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530133
Patrick Venture8f6c5152018-09-11 17:45:33 -0700134 /** @brief Map of systemd units to be started when the timer expires */
William A. Kennington III3bb2f402018-09-13 00:35:47 -0700135 ActionTargetMap actionTargetMap;
Vishwanatha Subbanna3473d702017-05-30 16:38:50 +0530136
Patrick Venture8f6c5152018-09-11 17:45:33 -0700137 /** @brief Fallback timer options */
William A. Kennington III73c2cfb2018-09-12 18:01:37 -0700138 std::optional<Fallback> fallback;
William A. Kennington IIId1331082018-02-27 18:47:05 -0800139
Patrick Venture8f6c5152018-09-11 17:45:33 -0700140 /** @brief Contained timer object */
141 Timer timer;
Vishwanatha Subbanna8c5a2292017-05-30 15:34:23 +0530142
Patrick Venture8f6c5152018-09-11 17:45:33 -0700143 /** @brief Optional Callback handler on timer expirartion */
144 void timeOutHandler();
William A. Kennington III825f4982018-02-27 19:10:56 -0800145
Patrick Venture8f6c5152018-09-11 17:45:33 -0700146 /** @brief Attempt to enter the fallback watchdog or disables it */
147 void tryFallbackOrDisable();
Vishwanatha Subbannad7a3f132017-05-29 19:39:08 +0530148};
149
150} // namespace watchdog
151} // namespace phosphor