diff options
author | William A. Kennington III <wak@google.com> | 2018-02-02 15:57:34 -0800 |
---|---|---|
committer | William A. Kennington III <wak@google.com> | 2018-02-15 10:40:39 -0800 |
commit | 1232a151514f722bc13e4e0165f3dd02dc63de2a (patch) | |
tree | 60ba87a853bc50689eb31616f5d37909a5ba483d | |
parent | 41d63a05fbdc0e85e22f152150f7961ebfc2f3d9 (diff) | |
download | phosphor-watchdog-1232a151514f722bc13e4e0165f3dd02dc63de2a.tar.gz phosphor-watchdog-1232a151514f722bc13e4e0165f3dd02dc63de2a.zip |
watchdog: Support multiple timeout actions
This change adds the infrastructure to support having different actions
map to different systemd targets being started when the watchdog
expires. Right now this maintains compatability with the current
--target argument and populates all of the watchdog actions, except for
None, with the same target. A follow up patch will implement setting
independent targets for each action.
Change-Id: I0f0601f9e94d488650f20a9cebfc7c967007d78c
Signed-off-by: William A. Kennington III <wak@google.com>
-rw-r--r-- | mainapp.cpp | 18 | ||||
-rw-r--r-- | watchdog.cpp | 29 | ||||
-rw-r--r-- | watchdog.hpp | 21 |
3 files changed, 45 insertions, 23 deletions
diff --git a/mainapp.cpp b/mainapp.cpp index 5819fb4..6cc3fdf 100644 --- a/mainapp.cpp +++ b/mainapp.cpp @@ -22,9 +22,12 @@ #include "argument.hpp" #include "watchdog.hpp" +using phosphor::watchdog::ArgumentParser; +using phosphor::watchdog::Watchdog; + static void exitWithError(const char* err, char** argv) { - phosphor::watchdog::ArgumentParser::usage(argv); + ArgumentParser::usage(argv); std::cerr << "ERROR: " << err << "\n"; exit(EXIT_FAILURE); } @@ -35,7 +38,7 @@ int main(int argc, char** argv) using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: Error::InternalFailure; // Read arguments. - auto options = phosphor::watchdog::ArgumentParser(argc, argv); + auto options = ArgumentParser(argc, argv); // Parse out continue argument. auto continueParam = (options)["continue"]; @@ -78,7 +81,13 @@ int main(int argc, char** argv) { exitWithError("Multiple targets specified.", argv); } - auto target = targetParam.back(); + std::map<Watchdog::Action, Watchdog::TargetName> actionTargets; + if (!targetParam.empty()) { + auto target = targetParam.back(); + actionTargets[Watchdog::Action::HardReset] = target; + actionTargets[Watchdog::Action::PowerOff] = target; + actionTargets[Watchdog::Action::PowerCycle] = target; + } sd_event* event = nullptr; auto r = sd_event_default(&event); @@ -102,8 +111,7 @@ int main(int argc, char** argv) try { // Create a watchdog object - phosphor::watchdog::Watchdog watchdog(bus, path.c_str(), - eventP, std::move(target)); + Watchdog watchdog(bus, path.c_str(), eventP, std::move(actionTargets)); // Claim the bus bus.request_name(service.c_str()); diff --git a/watchdog.cpp b/watchdog.cpp index d0dc7f0..c948d27 100644 --- a/watchdog.cpp +++ b/watchdog.cpp @@ -97,18 +97,27 @@ uint64_t Watchdog::timeRemaining(uint64_t value) // Optional callback function on timer expiration void Watchdog::timeOutHandler() { - if (!target.empty()) + auto action = expireAction(); + auto target = actionTargets.find(action); + + if (target == actionTargets.end()) { - auto method = bus.new_method_call(SYSTEMD_SERVICE, - SYSTEMD_ROOT, - SYSTEMD_INTERFACE, - "StartUnit"); - method.append(target); - method.append("replace"); - - bus.call_noreply(method); + log<level::INFO>("watchdog: Timed out with no target", + entry("ACTION=%s", convertForMessage(action).c_str())); + return; } - return; + + auto method = bus.new_method_call(SYSTEMD_SERVICE, + SYSTEMD_ROOT, + SYSTEMD_INTERFACE, + "StartUnit"); + method.append(target->second); + method.append("replace"); + + log<level::INFO>("watchdog: Timed out", + entry("ACTION=%s", convertForMessage(action).c_str()), + entry("TARGET=%s", target->second.c_str())); + bus.call_noreply(method); } } // namespace watchdog diff --git a/watchdog.hpp b/watchdog.hpp index f9657ac..757029c 100644 --- a/watchdog.hpp +++ b/watchdog.hpp @@ -27,20 +27,25 @@ class Watchdog : public WatchdogInherits Watchdog(Watchdog&&) = delete; Watchdog& operator=(Watchdog &&) = delete; + /** @brief Type used to hold the name of a systemd target. + */ + using TargetName = std::string; + /** @brief Constructs the Watchdog object * - * @param[in] bus - DBus bus to attach to. - * @param[in] objPath - Object path to attach to. - * @param[in] event - reference to sd_event unique pointer - * @param[in] target - systemd target to be called into on timeout + * @param[in] bus - DBus bus to attach to. + * @param[in] objPath - Object path to attach to. + * @param[in] event - reference to sd_event unique pointer + * @param[in] actionTargets - map of systemd targets called on timeout */ Watchdog(sdbusplus::bus::bus& bus, const char* objPath, EventPtr& event, - std::string&& target = std::string()) : + std::map<Action, TargetName>&& actionTargets = + std::map<Action, TargetName>()) : WatchdogInherits(bus, objPath), bus(bus), - target(std::move(target)), + actionTargets(std::move(actionTargets)), timer(event, std::bind(&Watchdog::timeOutHandler, this)) { // Nothing @@ -92,8 +97,8 @@ class Watchdog : public WatchdogInherits /** @brief sdbusplus handle */ sdbusplus::bus::bus& bus; - /** @brief Systemd unit to be started when the timer expires */ - std::string target; + /** @brief Map of systemd units to be started when the timer expires */ + std::map<Action, TargetName> actionTargets; /** @brief Contained timer object */ Timer timer; |