summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2018-02-02 15:57:34 -0800
committerWilliam A. Kennington III <wak@google.com>2018-02-15 10:40:39 -0800
commit1232a151514f722bc13e4e0165f3dd02dc63de2a (patch)
tree60ba87a853bc50689eb31616f5d37909a5ba483d
parent41d63a05fbdc0e85e22f152150f7961ebfc2f3d9 (diff)
downloadphosphor-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.cpp18
-rw-r--r--watchdog.cpp29
-rw-r--r--watchdog.hpp21
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;
OpenPOWER on IntegriCloud