Implement a fallback watchdog option

Sometimes our initial watchdog action is not enough to recover the host
from the state it transitioned into. However, always using a more power
form of power cycle is not desirable as we can lose useful CPU crash
state. It is desirable in this case to have two levels of watchog
timers.

This patch implements the ability for the service to specify a fallback
watchdog action and interval. After the initial watchdog timeout is
encountered, the watchdog will be re-armed with the new parameters. Once
the watchdog times out again it will execute the fallback action.
Attempts to update the timeRemaining will reset the fallback just in
case something is still alive.

Change-Id: I69f4422c7e3963f02200815f3cef620af9e6cf8b
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/argument.cpp b/argument.cpp
index d212261..c2d99ce 100644
--- a/argument.cpp
+++ b/argument.cpp
@@ -28,15 +28,17 @@
 const std::vector<std::string> emptyArg;
 const std::string ArgumentParser::trueString = "true"s;
 
-const char* ArgumentParser::optionStr = "p:s:t:a:ch";
+const char* ArgumentParser::optionStr = "p:s:t:a:f:i:ch";
 const option ArgumentParser::options[] =
 {
-    { "path",          required_argument,  nullptr,   'p' },
-    { "service",       required_argument,  nullptr,   's' },
-    { "target",        required_argument,  nullptr,   't' },
-    { "action_target", required_argument,  nullptr,   'a' },
-    { "continue",      no_argument,        nullptr,   'c' },
-    { "help",          no_argument,        nullptr,   'h' },
+    { "path",                    required_argument,  nullptr,   'p' },
+    { "service",                 required_argument,  nullptr,   's' },
+    { "target",                  required_argument,  nullptr,   't' },
+    { "action_target",           required_argument,  nullptr,   'a' },
+    { "fallback_action",         required_argument,  nullptr,   'f' },
+    { "fallback_interval",       required_argument,  nullptr,   'i' },
+    { "continue",                no_argument,        nullptr,   'c' },
+    { "help",                    no_argument,        nullptr,   'h' },
     { 0, 0, 0, 0},
 };
 
@@ -102,6 +104,13 @@
     std::cerr << " [--action_target=<action>=<systemd unit>] Map of action to "
                      "systemd unit to be called on timeout if that action is "
                      "set for ExpireAction when the timer expires.\n";
+    std::cerr << " [--fallback_action=<action>]              Enables the "
+                     "watchdog even when disabled via the dbus interface. "
+                     "Perform this action when the fallback expires.\n";
+    std::cerr << " [--fallback_interval=<interval in ms>]    Enables the "
+                     "watchdog even when disabled via the dbus interface. "
+                     "Waits for this interval before performing the fallback "
+                     "action.\n";
     std::cerr << " [--continue]                              Continue daemon "
                      "after watchdog timeout.\n";
 }