diff options
author | Jason M. Bills <jason.m.bills@linux.intel.com> | 2019-10-23 00:01:54 +0300 |
---|---|---|
committer | Jason M. Bills <jason.m.bills@linux.intel.com> | 2019-10-23 00:48:48 +0300 |
commit | 456380bb272d3a301c887eee513a3937cc1f48e1 (patch) | |
tree | 124399167d539582befbe35ad28377eaea6cc8bc /meta-openbmc-mods/meta-common/recipes-phosphor/watchdog | |
parent | 9722c6ee87766a45a337c094d1293de81cdcb106 (diff) | |
download | openbmc-456380bb272d3a301c887eee513a3937cc1f48e1.tar.xz |
Update to internal 10-22-19
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/watchdog')
10 files changed, 340 insertions, 579 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb index 950f4932d..ebd795e83 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/frb2-watchdog.bb @@ -10,7 +10,7 @@ SRC_URI = "\ PV = "0.1" LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://${PHOSPHORBASE}/LICENSE;md5=19407077e42b1ba3d653da313f1f5b4e" +LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658" S = "${WORKDIR}" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Customize-phosphor-watchdog-for-Intel-platforms.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Customize-phosphor-watchdog-for-Intel-platforms.patch new file mode 100644 index 000000000..736431e9e --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Customize-phosphor-watchdog-for-Intel-platforms.patch @@ -0,0 +1,316 @@ +From a65701eabcf205203d6363d54730a6a497c0e6fc Mon Sep 17 00:00:00 2001 +From: James Feist <james.feist@linux.intel.com> +Date: Mon, 17 Jun 2019 12:00:58 -0700 +Subject: [PATCH] Customize phosphor-watchdog for Intel platforms + +This patch adds various changes to phosphor-watchdog that are +required for compatibility with Intel platforms. + + 1. Add Redfish messages for watchdog timeout and pre-interrupt + 2. Use dbus properties for power control insted of service files + 3. Use host status to enable/disable watchdog + 4. Set preTimeoutInterruptOccurFlag + +Signed-off-by: James Feist <james.feist@linux.intel.com> +Signed-off-by: Ren Yu <yux.ren@intel.com> +Signed-off-by: Yong Li <yong.b.li@linux.intel.com> +Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com> +--- + watchdog.cpp | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + watchdog.hpp | 23 ++++++- + 2 files changed, 206 insertions(+), 10 deletions(-) + +diff --git a/watchdog.cpp b/watchdog.cpp +index 9090760..68b4246 100644 +--- a/watchdog.cpp ++++ b/watchdog.cpp +@@ -1,11 +1,14 @@ + #include "watchdog.hpp" + ++#include <systemd/sd-journal.h> ++ + #include <algorithm> + #include <chrono> + #include <phosphor-logging/elog.hpp> + #include <phosphor-logging/log.hpp> + #include <sdbusplus/exception.hpp> + #include <xyz/openbmc_project/Common/error.hpp> ++#include <xyz/openbmc_project/State/Host/server.hpp> + + namespace phosphor + { +@@ -18,10 +21,69 @@ using namespace phosphor::logging; + using sdbusplus::exception::SdBusError; + using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; + +-// systemd service to kick start a target. +-constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; +-constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; +-constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; ++const static constexpr char* currentHostState = "CurrentHostState"; ++const static constexpr char* hostStatusOff = ++ "xyz.openbmc_project.State.Host.HostState.Off"; ++ ++const static constexpr char* actionDescription = " due to Watchdog timeout"; ++const static constexpr char* hardResetDescription = "Hard Reset - System reset"; ++const static constexpr char* powerOffDescription = ++ "Power Down - System power down"; ++const static constexpr char* powerCycleDescription = ++ "Power Cycle - System power cycle"; ++const static constexpr char* timerExpiredDescription = "Timer expired"; ++ ++const static constexpr char* preInterruptActionNone = ++ "xyz.openbmc_project.State.Watchdog.PreTimeoutInterruptAction.None"; ++ ++const static constexpr char* preInterruptDescriptionSMI = "SMI"; ++const static constexpr char* preInterruptDescriptionNMI = "NMI"; ++const static constexpr char* preInterruptDescriptionMI = "Messaging Interrupt"; ++ ++const static constexpr char* reservedDescription = "Reserved"; ++ ++const static constexpr char* timerUseDescriptionBIOSFRB2 = "BIOS FRB2"; ++const static constexpr char* timerUseDescriptionBIOSPOST = "BIOS/POST"; ++const static constexpr char* timerUseDescriptionOSLoad = "OSLoad"; ++const static constexpr char* timerUseDescriptionSMSOS = "SMS/OS"; ++const static constexpr char* timerUseDescriptionOEM = "OEM"; ++ ++namespace restart ++{ ++static constexpr const char* busName = ++ "xyz.openbmc_project.Control.Host.RestartCause"; ++static constexpr const char* path = ++ "/xyz/openbmc_project/control/host0/restart_cause"; ++static constexpr const char* interface = ++ "xyz.openbmc_project.Control.Host.RestartCause"; ++static constexpr const char* property = "RequestedRestartCause"; ++} // namespace restart ++ ++// chassis state manager service ++namespace chassis ++{ ++static constexpr const char* busName = "xyz.openbmc_project.State.Chassis"; ++static constexpr const char* path = "/xyz/openbmc_project/state/chassis0"; ++static constexpr const char* interface = "xyz.openbmc_project.State.Chassis"; ++static constexpr const char* request = "RequestedPowerTransition"; ++} // namespace chassis ++ ++void Watchdog::powerStateChangedHandler( ++ const std::map<std::string, std::variant<std::string>>& props) ++{ ++ const auto iter = props.find(currentHostState); ++ if (iter != props.end()) ++ { ++ const std::string* powerState = std::get_if<std::string>(&iter->second); ++ if (powerState && (*powerState == hostStatusOff)) ++ { ++ if (timerEnabled()) ++ { ++ enabled(false); ++ } ++ } ++ } ++} + + void Watchdog::resetTimeRemaining(bool enableWatchdog) + { +@@ -102,13 +164,102 @@ uint64_t Watchdog::interval(uint64_t value) + // Optional callback function on timer expiration + void Watchdog::timeOutHandler() + { ++ PreTimeoutInterruptAction preTimeoutInterruptAction = preTimeoutInterrupt(); ++ std::string preInterruptActionMessageArgs{}; ++ + Action action = expireAction(); ++ std::string actionMessageArgs{}; ++ ++ expiredTimerUse(currentTimerUse()); ++ ++ TimerUse timeUser = expiredTimerUse(); ++ std::string timeUserMessage{}; ++ + if (!this->enabled()) + { + action = fallback->action; + } + +- expiredTimerUse(currentTimerUse()); ++ switch (timeUser) ++ { ++ case Watchdog::TimerUse::BIOSFRB2: ++ timeUserMessage = timerUseDescriptionBIOSFRB2; ++ break; ++ case Watchdog::TimerUse::BIOSPOST: ++ timeUserMessage = timerUseDescriptionBIOSPOST; ++ break; ++ case Watchdog::TimerUse::OSLoad: ++ timeUserMessage = timerUseDescriptionOSLoad; ++ break; ++ case Watchdog::TimerUse::SMSOS: ++ timeUserMessage = timerUseDescriptionSMSOS; ++ break; ++ case Watchdog::TimerUse::OEM: ++ timeUserMessage = timerUseDescriptionOEM; ++ break; ++ default: ++ timeUserMessage = reservedDescription; ++ break; ++ } ++ ++ switch (action) ++ { ++ case Watchdog::Action::HardReset: ++ actionMessageArgs = std::string(hardResetDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::PowerOff: ++ actionMessageArgs = std::string(powerOffDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::PowerCycle: ++ actionMessageArgs = std::string(powerCycleDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::None: ++ actionMessageArgs = timerExpiredDescription; ++ break; ++ default: ++ actionMessageArgs = reservedDescription; ++ break; ++ } ++ ++ // Log into redfish event log ++ sd_journal_send("MESSAGE=IPMIWatchdog: Timed out ACTION=%s", ++ convertForMessage(action).c_str(), "PRIORITY=%i", LOG_INFO, ++ "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.IPMIWatchdog", ++ "REDFISH_MESSAGE_ARGS=%s. timer use: %s", ++ actionMessageArgs.c_str(), timeUserMessage.c_str(), NULL); ++ ++ switch (preTimeoutInterruptAction) ++ { ++ case Watchdog::PreTimeoutInterruptAction::SMI: ++ preInterruptActionMessageArgs = preInterruptDescriptionSMI; ++ break; ++ case Watchdog::PreTimeoutInterruptAction::NMI: ++ preInterruptActionMessageArgs = preInterruptDescriptionNMI; ++ break; ++ case Watchdog::PreTimeoutInterruptAction::MI: ++ preInterruptActionMessageArgs = preInterruptDescriptionMI; ++ break; ++ default: ++ preInterruptActionMessageArgs = reservedDescription; ++ break; ++ } ++ ++ if (preInterruptActionNone != convertForMessage(preTimeoutInterruptAction)) ++ { ++ preTimeoutInterruptOccurFlag(true); ++ ++ sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", ++ convertForMessage(preTimeoutInterruptAction).c_str(), ++ "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", ++ "OpenBMC.0.1.IPMIWatchdog", ++ "REDFISH_MESSAGE_ARGS=Timer interrupt - %s due to " ++ "Watchdog timeout. timer use: %s", ++ preInterruptActionMessageArgs.c_str(), ++ timeUserMessage.c_str(), NULL); ++ } + + auto target = actionTargetMap.find(action); + if (target == actionTargetMap.end()) +@@ -128,10 +279,11 @@ void Watchdog::timeOutHandler() + + try + { +- auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, +- SYSTEMD_INTERFACE, "StartUnit"); +- method.append(target->second); +- method.append("replace"); ++ auto method = ++ bus.new_method_call(chassis::busName, chassis::path, ++ "org.freedesktop.DBus.Properties", "Set"); ++ method.append(chassis::interface, chassis::request, ++ std::variant<std::string>(target->second)); + + bus.call_noreply(method); + } +@@ -142,6 +294,29 @@ void Watchdog::timeOutHandler() + entry("ERROR=%s", e.what())); + commit<InternalFailure>(); + } ++ ++ // set restart cause for watchdog HardReset & PowerCycle actions ++ if ((action == Watchdog::Action::HardReset) || ++ (action == Watchdog::Action::PowerCycle)) ++ { ++ try ++ { ++ auto method = bus.new_method_call( ++ restart::busName, restart::path, ++ "org.freedesktop.DBus.Properties", "Set"); ++ method.append( ++ restart::interface, restart::property, ++ std::variant<std::string>("xyz.openbmc_project.State.Host." ++ "RestartCause.WatchdogTimer")); ++ bus.call(method); ++ } ++ catch (sdbusplus::exception_t& e) ++ { ++ log<level::ERR>("Failed to set HostRestartCause property", ++ entry("ERROR=%s", e.what())); ++ commit<InternalFailure>(); ++ } ++ } + } + + tryFallbackOrDisable(); +diff --git a/watchdog.hpp b/watchdog.hpp +index 7de9bb3..b004b7a 100644 +--- a/watchdog.hpp ++++ b/watchdog.hpp +@@ -68,7 +68,18 @@ class Watchdog : public WatchdogInherits + WatchdogInherits(bus, objPath), + bus(bus), actionTargetMap(std::move(actionTargetMap)), + fallback(std::move(fallback)), minInterval(minInterval), +- timer(event, std::bind(&Watchdog::timeOutHandler, this)) ++ timer(event, std::bind(&Watchdog::timeOutHandler, this)), ++ powerStateChangedSignal( ++ bus, ++ sdbusplus::bus::match::rules::propertiesChanged( ++ "/xyz/openbmc_project/state/host0", ++ "xyz.openbmc_project.State.Host"), ++ [this](sdbusplus::message::message& msg) { ++ std::string objectName; ++ std::map<std::string, std::variant<std::string>> props; ++ msg.read(objectName, props); ++ powerStateChangedHandler(props); ++ }) + { + // We set the watchdog interval with the default value. + interval(interval()); +@@ -77,6 +88,12 @@ class Watchdog : public WatchdogInherits + tryFallbackOrDisable(); + } + ++ /** @brief Disable watchdog when power status change meet ++ * the specific requirement ++ */ ++ void powerStateChangedHandler( ++ const std::map<std::string, std::variant<std::string>>& props); ++ + /** @brief Resets the TimeRemaining to the configured Interval + * Optionally enables the watchdog. + * +@@ -165,6 +182,10 @@ class Watchdog : public WatchdogInherits + /** @brief Contained timer object */ + sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; + ++ /** @brief Optional Callback handler when power status change meet ++ * the specific requirement */ ++ sdbusplus::bus::match_t powerStateChangedSignal; ++ + /** @brief Optional Callback handler on timer expirartion */ + void timeOutHandler(); + +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Move-Phosphor-Watchdog-to-Not-Use-Service-Files.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Move-Phosphor-Watchdog-to-Not-Use-Service-Files.patch deleted file mode 100644 index 627dacef1..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0001-Move-Phosphor-Watchdog-to-Not-Use-Service-Files.patch +++ /dev/null @@ -1,198 +0,0 @@ -From d15cf914ad51207021451b12863d4b7585f4666c Mon Sep 17 00:00:00 2001 -From: James Feist <james.feist@linux.intel.com> -Date: Mon, 17 Jun 2019 12:00:58 -0700 -Subject: [PATCH] Move Phosphor-Watchdog to Not Use Service Files - -Our power control does not use service files, update it -so that it calls properties directly. - -According to EPS, change the messageArgs in redfish about watchdog -action and pre-interrupt action. - -Tested: used ipmi to create watchdog event and system -was restarted. - -Set a watchdog (Timer action and pre-interrupt action both are none). - ipmitool raw 0x06 0x24 0x05 0x00 0x00 0x00 0x30 0x00 -Get the watchdog. - ipmitool mc watchdog get -Start the watchdog. - ipmitool mc watchdog reset -When timer expired, check messageArgs in Redfish with below url: -https://IP/redfish/v1/Systems/system/LogServices/EventLog/Entries. - -Signed-off-by: James Feist <james.feist@linux.intel.com> -Signed-off-by: Ren Yu <yux.ren@intel.com> ---- - watchdog.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 108 insertions(+), 8 deletions(-) - -diff --git a/watchdog.cpp b/watchdog.cpp -index 9090760..4c8e480 100644 ---- a/watchdog.cpp -+++ b/watchdog.cpp -@@ -1,11 +1,14 @@ - #include "watchdog.hpp" - -+#include <systemd/sd-journal.h> -+ - #include <algorithm> - #include <chrono> - #include <phosphor-logging/elog.hpp> - #include <phosphor-logging/log.hpp> - #include <sdbusplus/exception.hpp> - #include <xyz/openbmc_project/Common/error.hpp> -+#include <xyz/openbmc_project/State/Host/server.hpp> - - namespace phosphor - { -@@ -18,10 +21,44 @@ using namespace phosphor::logging; - using sdbusplus::exception::SdBusError; - using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; - --// systemd service to kick start a target. --constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; --constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; --constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; -+const static constexpr char* powerActionHardReset = -+ "xyz.openbmc_project.State.Watchdog.Action.HardReset"; -+const static constexpr char* powerActionOff = -+ "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; -+const static constexpr char* powerActionPowerCycle = -+ "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; -+const static constexpr char* powerActionNone = -+ "xyz.openbmc_project.State.Watchdog.Action.None"; -+const static constexpr char* preInterruptNoAction = -+ "xyz.openbmc_project.State.Watchdog.PreTimeoutInterruptAction.None"; -+ -+const static constexpr char* hardResteDescription = -+ "Hard Reset - System reset due to Watchdog timeout"; -+const static constexpr char* powerOffDescription = -+ "Power Down - System power down due to Watchdog timeout"; -+const static constexpr char* powerCycleDescription = -+ "Power Cycle - System power cycle due to Watchdog timeout"; -+const static constexpr char* timerExpiredDescription = "Timer expired"; -+const static constexpr char* preInterruptDescription = "Timer interrupt"; -+ -+namespace restart -+{ -+static constexpr const char* busName = "xyz.openbmc_project.Settings"; -+static constexpr const char* path = -+ "/xyz/openbmc_project/control/host0/restart_cause"; -+static constexpr const char* interface = -+ "xyz.openbmc_project.Common.RestartCause"; -+static constexpr const char* property = "RestartCause"; -+} // namespace restart -+ -+// chassis state manager service -+namespace chassis -+{ -+static constexpr const char* busName = "xyz.openbmc_project.State.Chassis"; -+static constexpr const char* path = "/xyz/openbmc_project/state/chassis0"; -+static constexpr const char* interface = "xyz.openbmc_project.State.Chassis"; -+static constexpr const char* request = "RequestedPowerTransition"; -+} // namespace chassis - - void Watchdog::resetTimeRemaining(bool enableWatchdog) - { -@@ -102,12 +139,51 @@ uint64_t Watchdog::interval(uint64_t value) - // Optional callback function on timer expiration - void Watchdog::timeOutHandler() - { -+ PreTimeoutInterruptAction preTimeoutInterruptAction = preTimeoutInterrupt(); - Action action = expireAction(); -+ std::string actionMessageArgs{}; -+ - if (!this->enabled()) - { - action = fallback->action; - } - -+ if (convertForMessage(action) == powerActionHardReset) -+ { -+ actionMessageArgs = hardResteDescription; -+ } -+ else if (convertForMessage(action) == powerActionOff) -+ { -+ actionMessageArgs = powerOffDescription; -+ } -+ else if (convertForMessage(action) == powerActionPowerCycle) -+ { -+ actionMessageArgs = powerCycleDescription; -+ } -+ else if (convertForMessage(action) == powerActionNone) -+ { -+ actionMessageArgs = timerExpiredDescription; -+ } -+ else -+ { -+ actionMessageArgs = "Reserved"; -+ } -+ -+ // Log into redfish event log -+ sd_journal_send("MESSAGE=IPMIWatchdog: Timed out ACTION=%s", -+ convertForMessage(action).c_str(), "PRIORITY=%i", LOG_INFO, -+ "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.IPMIWatchdog", -+ "REDFISH_MESSAGE_ARGS=%s", actionMessageArgs.c_str(), NULL); -+ -+ if (preInterruptNoAction != convertForMessage(preTimeoutInterruptAction)) -+ { -+ sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", -+ convertForMessage(preTimeoutInterruptAction).c_str(), -+ "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", -+ "OpenBMC.0.1.IPMIWatchdog", "REDFISH_MESSAGE_ARGS=%s", -+ preInterruptDescription, NULL); -+ } -+ - expiredTimerUse(currentTimerUse()); - - auto target = actionTargetMap.find(action); -@@ -128,10 +204,11 @@ void Watchdog::timeOutHandler() - - try - { -- auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, -- SYSTEMD_INTERFACE, "StartUnit"); -- method.append(target->second); -- method.append("replace"); -+ auto method = -+ bus.new_method_call(chassis::busName, chassis::path, -+ "org.freedesktop.DBus.Properties", "Set"); -+ method.append(chassis::interface, chassis::request, -+ std::variant<std::string>(target->second)); - - bus.call_noreply(method); - } -@@ -142,6 +219,29 @@ void Watchdog::timeOutHandler() - entry("ERROR=%s", e.what())); - commit<InternalFailure>(); - } -+ -+ // set restart cause for watchdog HardReset & PowerCycle actions -+ if ((action == Watchdog::Action::HardReset) || -+ (action == Watchdog::Action::PowerCycle)) -+ { -+ try -+ { -+ auto method = bus.new_method_call( -+ restart::busName, restart::path, -+ "org.freedesktop.DBus.Properties", "Set"); -+ method.append( -+ restart::interface, restart::property, -+ std::variant<std::string>("xyz.openbmc_project.State.Host." -+ "RestartCause.WatchdogTimer")); -+ bus.call(method); -+ } -+ catch (sdbusplus::exception_t& e) -+ { -+ log<level::ERR>("Failed to set HostRestartCause property", -+ entry("ERROR=%s", e.what())); -+ commit<InternalFailure>(); -+ } -+ } - } - - tryFallbackOrDisable(); --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0002-Stop-the-watchdog-when-the-host-is-going-to-off.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0002-Stop-the-watchdog-when-the-host-is-going-to-off.patch deleted file mode 100644 index 016cf063a..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0002-Stop-the-watchdog-when-the-host-is-going-to-off.patch +++ /dev/null @@ -1,118 +0,0 @@ -From b05da90d7023199e23daf8fbb49455138332f241 Mon Sep 17 00:00:00 2001 -From: Ren Yu <yux.ren@intel.com> -Date: Wed, 24 Jul 2019 16:21:13 +0800 -Subject: [PATCH] Stop the watchdog when the host is going to off - -After the host is off, check the WDT status, if it is running, -needs to stop it - -Tested: -Set a watchdog with a long time expiration(Timer action is none, -Timer Use is OEM and Initial Countdown is 435.1 second). - ipmitool raw 0x06 0x24 0x05 0x00 0x00 0x00 0xff 0x10 -Get the watchdog. - ipmitool mc watchdog get -Start the watchdog. - ipmitool mc watchdog reset -Host off. - ipmitool chassis power off -Get the watchdog. - ipmitool mc watchdog get -Check the watchdog status, expect watchdog is stoped. - -Signed-off-by: Ren Yu <yux.ren@intel.com> ---- - watchdog.cpp | 21 +++++++++++++++++++++ - watchdog.hpp | 23 ++++++++++++++++++++++- - 2 files changed, 43 insertions(+), 1 deletion(-) - -diff --git a/watchdog.cpp b/watchdog.cpp -index 4c8e480..fa58ef4 100644 ---- a/watchdog.cpp -+++ b/watchdog.cpp -@@ -21,6 +21,10 @@ using namespace phosphor::logging; - using sdbusplus::exception::SdBusError; - using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; - -+const static constexpr char* currentPowerState = "CurrentPowerState"; -+const static constexpr char* powerStatusOff = -+ "xyz.openbmc_project.State.Chassis.PowerState.Off"; -+ - const static constexpr char* powerActionHardReset = - "xyz.openbmc_project.State.Watchdog.Action.HardReset"; - const static constexpr char* powerActionOff = -@@ -60,6 +64,23 @@ static constexpr const char* interface = "xyz.openbmc_project.State.Chassis"; - static constexpr const char* request = "RequestedPowerTransition"; - } // namespace chassis - -+void Watchdog::powerStateChangedHandler( -+ const std::map<std::string, std::variant<std::string>>& props) -+{ -+ const auto iter = props.find(currentPowerState); -+ if (iter != props.end()) -+ { -+ const std::string* powerState = std::get_if<std::string>(&iter->second); -+ if (powerState && (*powerState == powerStatusOff)) -+ { -+ if (timerEnabled()) -+ { -+ enabled(false); -+ } -+ } -+ } -+} -+ - void Watchdog::resetTimeRemaining(bool enableWatchdog) - { - timeRemaining(interval()); -diff --git a/watchdog.hpp b/watchdog.hpp -index 7de9bb3..dcbecd1 100644 ---- a/watchdog.hpp -+++ b/watchdog.hpp -@@ -68,7 +68,18 @@ class Watchdog : public WatchdogInherits - WatchdogInherits(bus, objPath), - bus(bus), actionTargetMap(std::move(actionTargetMap)), - fallback(std::move(fallback)), minInterval(minInterval), -- timer(event, std::bind(&Watchdog::timeOutHandler, this)) -+ timer(event, std::bind(&Watchdog::timeOutHandler, this)), -+ powerStateChangedSignal( -+ bus, -+ sdbusplus::bus::match::rules::propertiesChanged( -+ "/xyz/openbmc_project/state/chassis0", -+ "xyz.openbmc_project.State.Chassis"), -+ [this](sdbusplus::message::message& msg) { -+ std::string objectName; -+ std::map<std::string, std::variant<std::string>> props; -+ msg.read(objectName, props); -+ powerStateChangedHandler(props); -+ }) - { - // We set the watchdog interval with the default value. - interval(interval()); -@@ -77,6 +88,12 @@ class Watchdog : public WatchdogInherits - tryFallbackOrDisable(); - } - -+ /** @brief Disable watchdog when power status change meet -+ * the specific requirement -+ */ -+ void powerStateChangedHandler( -+ const std::map<std::string, std::variant<std::string>>& props); -+ - /** @brief Resets the TimeRemaining to the configured Interval - * Optionally enables the watchdog. - * -@@ -165,6 +182,10 @@ class Watchdog : public WatchdogInherits - /** @brief Contained timer object */ - sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; - -+ /** @brief Optional Callback handler when power status change meet -+ * the specific requirement */ -+ sdbusplus::bus::match_t powerStateChangedSignal; -+ - /** @brief Optional Callback handler on timer expirartion */ - void timeOutHandler(); - --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch deleted file mode 100644 index 60b605418..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 41f71ecfa2b8339281a33c260d78102453d4ac97 Mon Sep 17 00:00:00 2001 -From: Ren Yu <yux.ren@intel.com> -Date: Tue, 30 Jul 2019 15:31:09 +0800 -Subject: [PATCH] Set PreTimeoutInterruptOccurFlag in DBUS - -Set preTimeoutInterruptOccurFlag in DBUS as 'true' when -watchdog pre-timeout interrupt occurred. -This property is use for recording PreTimeoutInterruptOccurFlag. -In command get message flag, need verify whether pre-timeout -interrupt occurred by it. - -Tested: -Set watchdog timer -(Pre-timeout interrupt is Messaging, Initial Countdown is 2 second). -ipmitool raw 0x06 0x24 0x5 0x30 0x1 0x3e 0x14 0x00 -Start watchdog timer. -ipmitool mc watchdog reset -Wait watchdog timer expired, log into below: -http://BMC-IP:3000/ -xyz.openbmc_project.Watchdog -/xyz/openbmc_project/watchdog/host0 -xyz.openbmc_project.State.Watchdog -check whether the value of PreTimeoutInterruptOccurFlag is true. - -Signed-off-by: Ren Yu <yux.ren@intel.com> ---- - watchdog.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/watchdog.cpp b/watchdog.cpp -index fa58ef4..bdf65da 100644 ---- a/watchdog.cpp -+++ b/watchdog.cpp -@@ -198,6 +198,8 @@ void Watchdog::timeOutHandler() - - if (preInterruptNoAction != convertForMessage(preTimeoutInterruptAction)) - { -+ preTimeoutInterruptOccurFlag(true); -+ - sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", - convertForMessage(preTimeoutInterruptAction).c_str(), - "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0004-Standardize-watchdog-redfish-format-according-to-EPS.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0004-Standardize-watchdog-redfish-format-according-to-EPS.patch deleted file mode 100644 index 578fa1257..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0004-Standardize-watchdog-redfish-format-according-to-EPS.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 3bead6316f653f14773e65b2f6b8facb08f200e7 Mon Sep 17 00:00:00 2001 -From: Ren Yu <yux.ren@intel.com> -Date: Fri, 9 Aug 2019 14:54:13 +0800 -Subject: [PATCH] Standardize watchdog redfish format according to EPS - -According to EPS and test requirement, change the messageArgs -in redfish about watchdog action and pre-interrupt action and -add timer user display. - -Tested: -Set a watchdog (Timer action and pre-interrupt action both are none). - ipmitool raw 0x06 0x24 0x05 0x00 0x00 0x00 0x30 0x00 -Get the watchdog. - ipmitool mc watchdog get -Start the watchdog. - ipmitool mc watchdog reset -When timer expired, check messageArgs in Redfish with below url: -https://IP/redfish/v1/Systems/system/LogServices/EventLog/Entries. - - "Message": "Host Watchdog Event: Power Cycle - System power cycle due to Watchdog timeout. timer use: SMS/OS", - "MessageArgs": [ - "Power Cycle - System power cycle due to Watchdog timeout. timer use: SMS/OS" - ], - - "Message": "Host Watchdog Event: Timer interrupt - Messaging Interrupt due to Watchdog timeout. timer use: OEM", - "MessageArgs": [ - "Timer interrupt - Messaging Interrupt due to Watchdog timeout. timer use: OEM" - ], - -Signed-off-by: Ren Yu <yux.ren@intel.com> ---- - watchdog.cpp | 127 +++++++++++++++++++++++++++++++++++++++++------------------ - 1 file changed, 89 insertions(+), 38 deletions(-) - -diff --git a/watchdog.cpp b/watchdog.cpp -index bdf65da..7cfcc75 100644 ---- a/watchdog.cpp -+++ b/watchdog.cpp -@@ -25,25 +25,28 @@ const static constexpr char* currentPowerState = "CurrentPowerState"; - const static constexpr char* powerStatusOff = - "xyz.openbmc_project.State.Chassis.PowerState.Off"; - --const static constexpr char* powerActionHardReset = -- "xyz.openbmc_project.State.Watchdog.Action.HardReset"; --const static constexpr char* powerActionOff = -- "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; --const static constexpr char* powerActionPowerCycle = -- "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; --const static constexpr char* powerActionNone = -- "xyz.openbmc_project.State.Watchdog.Action.None"; --const static constexpr char* preInterruptNoAction = -- "xyz.openbmc_project.State.Watchdog.PreTimeoutInterruptAction.None"; -- --const static constexpr char* hardResteDescription = -- "Hard Reset - System reset due to Watchdog timeout"; -+const static constexpr char* actionDescription = " due to Watchdog timeout"; -+const static constexpr char* hardResetDescription = "Hard Reset - System reset"; - const static constexpr char* powerOffDescription = -- "Power Down - System power down due to Watchdog timeout"; -+ "Power Down - System power down"; - const static constexpr char* powerCycleDescription = -- "Power Cycle - System power cycle due to Watchdog timeout"; -+ "Power Cycle - System power cycle"; - const static constexpr char* timerExpiredDescription = "Timer expired"; --const static constexpr char* preInterruptDescription = "Timer interrupt"; -+ -+const static constexpr char* preInterruptActionNone = -+ "xyz.openbmc_project.State.Watchdog.PreTimeoutInterruptAction.None"; -+ -+const static constexpr char* preInterruptDescriptionSMI = "SMI"; -+const static constexpr char* preInterruptDescriptionNMI = "NMI"; -+const static constexpr char* preInterruptDescriptionMI = "Messaging Interrupt"; -+ -+const static constexpr char* reservedDescription = "Reserved"; -+ -+const static constexpr char* timerUseDescriptionBIOSFRB2 = "BIOS FRB2"; -+const static constexpr char* timerUseDescriptionBIOSPOST = "BIOS/POST"; -+const static constexpr char* timerUseDescriptionOSLoad = "OSLoad"; -+const static constexpr char* timerUseDescriptionSMSOS = "SMS/OS"; -+const static constexpr char* timerUseDescriptionOEM = "OEM"; - - namespace restart - { -@@ -161,54 +164,102 @@ uint64_t Watchdog::interval(uint64_t value) - void Watchdog::timeOutHandler() - { - PreTimeoutInterruptAction preTimeoutInterruptAction = preTimeoutInterrupt(); -+ std::string preInterruptActionMessageArgs{}; -+ - Action action = expireAction(); - std::string actionMessageArgs{}; - -+ expiredTimerUse(currentTimerUse()); -+ -+ TimerUse timeUser = expiredTimerUse(); -+ std::string timeUserMessage{}; -+ - if (!this->enabled()) - { - action = fallback->action; - } - -- if (convertForMessage(action) == powerActionHardReset) -- { -- actionMessageArgs = hardResteDescription; -- } -- else if (convertForMessage(action) == powerActionOff) -- { -- actionMessageArgs = powerOffDescription; -- } -- else if (convertForMessage(action) == powerActionPowerCycle) -+ switch (timeUser) - { -- actionMessageArgs = powerCycleDescription; -+ case Watchdog::TimerUse::BIOSFRB2: -+ timeUserMessage = timerUseDescriptionBIOSFRB2; -+ break; -+ case Watchdog::TimerUse::BIOSPOST: -+ timeUserMessage = timerUseDescriptionBIOSPOST; -+ break; -+ case Watchdog::TimerUse::OSLoad: -+ timeUserMessage = timerUseDescriptionOSLoad; -+ break; -+ case Watchdog::TimerUse::SMSOS: -+ timeUserMessage = timerUseDescriptionSMSOS; -+ break; -+ case Watchdog::TimerUse::OEM: -+ timeUserMessage = timerUseDescriptionOEM; -+ break; -+ default: -+ timeUserMessage = reservedDescription; -+ break; - } -- else if (convertForMessage(action) == powerActionNone) -- { -- actionMessageArgs = timerExpiredDescription; -- } -- else -+ -+ switch (action) - { -- actionMessageArgs = "Reserved"; -+ case Watchdog::Action::HardReset: -+ actionMessageArgs = std::string(hardResetDescription) + -+ std::string(actionDescription); -+ break; -+ case Watchdog::Action::PowerOff: -+ actionMessageArgs = std::string(powerOffDescription) + -+ std::string(actionDescription); -+ break; -+ case Watchdog::Action::PowerCycle: -+ actionMessageArgs = std::string(powerCycleDescription) + -+ std::string(actionDescription); -+ break; -+ case Watchdog::Action::None: -+ actionMessageArgs = timerExpiredDescription; -+ break; -+ default: -+ actionMessageArgs = reservedDescription; -+ break; - } - - // Log into redfish event log - sd_journal_send("MESSAGE=IPMIWatchdog: Timed out ACTION=%s", - convertForMessage(action).c_str(), "PRIORITY=%i", LOG_INFO, - "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.IPMIWatchdog", -- "REDFISH_MESSAGE_ARGS=%s", actionMessageArgs.c_str(), NULL); -+ "REDFISH_MESSAGE_ARGS=%s. timer use: %s", -+ actionMessageArgs.c_str(), timeUserMessage.c_str(), NULL); -+ -+ switch (preTimeoutInterruptAction) -+ { -+ case Watchdog::PreTimeoutInterruptAction::SMI: -+ preInterruptActionMessageArgs = preInterruptDescriptionSMI; -+ break; -+ case Watchdog::PreTimeoutInterruptAction::NMI: -+ preInterruptActionMessageArgs = preInterruptDescriptionNMI; -+ break; -+ case Watchdog::PreTimeoutInterruptAction::MI: -+ preInterruptActionMessageArgs = preInterruptDescriptionMI; -+ break; -+ default: -+ preInterruptActionMessageArgs = reservedDescription; -+ break; -+ } - -- if (preInterruptNoAction != convertForMessage(preTimeoutInterruptAction)) -+ if (preInterruptActionNone != convertForMessage(preTimeoutInterruptAction)) - { - preTimeoutInterruptOccurFlag(true); - - sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", - convertForMessage(preTimeoutInterruptAction).c_str(), - "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", -- "OpenBMC.0.1.IPMIWatchdog", "REDFISH_MESSAGE_ARGS=%s", -- preInterruptDescription, NULL); -+ "OpenBMC.0.1.IPMIWatchdog", -+ "REDFISH_MESSAGE_ARGS=Timer interrupt - %s due to " -+ "Watchdog timeout. timer use: %s", -+ preInterruptActionMessageArgs.c_str(), -+ timeUserMessage.c_str(), NULL); - } - -- expiredTimerUse(currentTimerUse()); -- - auto target = actionTargetMap.find(action); - if (target == actionTargetMap.end()) - { --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend index 0e221a6b5..f0b8e8f23 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend @@ -1,10 +1,7 @@ FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" SRCREV = "c35135d32f9cb84b62de7b72eee3a2e87b4b3d4d" -SRC_URI += "file://0001-Move-Phosphor-Watchdog-to-Not-Use-Service-Files.patch \ - file://0002-Stop-the-watchdog-when-the-host-is-going-to-off.patch \ - file://0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch \ - file://0004-Standardize-watchdog-redfish-format-according-to-EPS.patch \ +SRC_URI += "file://0001-Customize-phosphor-watchdog-for-Intel-platforms.patch \ " # Remove the override to keep service running after DC cycle diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb index 2ed120659..45c2c5364 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb @@ -5,6 +5,8 @@ DESCRIPTION = "BMC hardware watchdog service that is used to reset BMC \ inherit allarch inherit obmc-phosphor-systemd +RDEPENDS_${PN} = "bash" + LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658" @@ -14,3 +16,9 @@ SYSTEMD_ENVIRONMENT_FILE_${PN} += "obmc/system-watchdog/system-watchdog.conf" SYSTEMD_SERVICE_${PN} += "watchdog-reset.service" SYSTEMD_SERVICE_${PN} += "watchdog-clear-failures.service" SYSTEMD_SERVICE_${PN} += "watchdog-clear-failures.timer" +SRC_URI += "file://watchdog-reset.sh" + +do_install_append(){ + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/watchdog-reset.sh ${D}${bindir} +} diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service index 6f33b36d7..6a5ffb4ba 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service @@ -1,8 +1,7 @@ [Unit] Description=Reset BMC Using Hardware Watchdog -Conflicts=system-watchdog.service [Service] -ExecStart=/sbin/watchdog -T 0 -F /dev/watchdog1 +ExecStart=/usr/bin/watchdog-reset.sh Type=oneshot diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh new file mode 100644 index 000000000..b3afd73d3 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if /sbin/fw_printenv bootfailures -n | grep -q 3; then + exit 0 # passed boot limit, user started again on purpose +fi + +echo "Watchdog Failure Limit Reached, Failed Processes:" > /dev/kmsg +systemctl --failed --no-pager | grep failed > /dev/kmsg +echo "Log as follows:" > /dev/kmsg +journalctl -r -n 100 | while read line; do echo $line > /dev/kmsg; done + +systemctl stop system-watchdog.service +/sbin/watchdog -T 0 -F /dev/watchdog1 |