phosphor-state-manager: Add reset cause logic
This change will allow BMC graceful reboots to be tracked differently
from crashes.
Tested:
busctl set-property xyz.openbmc_project.State.BMC /xyz/openbmc_project/state/bmc0 xyz.openbmc_project.State.BMC RequestedBMCTransition s xyz.openbmc_project.State.BMC.Transition.Reboot
...
<bmc reboots>
...
Jan 24 22:27:58 <>-nfd01.prod.google.com phosphor-bmc-state-manager[435]: Rest flag file found
openbmc review for ref:
https://gerrit.openbmc.org/c/openbmc/phosphor-state-manager/+/77551
Fusion-Link:
https://fusion2.corp.google.com/3e6b34e0-7051-3d66-850b-35203e3520f0
Google-Bug-Id: 388883002
Change-Id: I85b415dbdbf6babb1bc262a230303d6c860450eb
Signed-off-by: John Edward Broadbent <jebr@google.com>
diff --git a/recipes-phosphor/state/phosphor-state-manager/0001-Adds-bmc-reboot-flag-identify-reboot-types.patch b/recipes-phosphor/state/phosphor-state-manager/0001-Adds-bmc-reboot-flag-identify-reboot-types.patch
new file mode 100644
index 0000000..0c0b219
--- /dev/null
+++ b/recipes-phosphor/state/phosphor-state-manager/0001-Adds-bmc-reboot-flag-identify-reboot-types.patch
@@ -0,0 +1,127 @@
+From eb587dd9a2650fdd351653d9c905d2691fb6d851 Mon Sep 17 00:00:00 2001
+From: John Edward Broadbent <jebr@google.com>
+Date: Sat, 18 Jan 2025 03:34:41 +0000
+Subject: [PATCH] Adds bmc reboot flag, identify reboot types
+
+This change adds a flag that bmc_state_manager writes when it shutsdown
+gracefully. This flag is read when the system starts, and it used to
+confirm the cause of the reboot is not unknown.
+
+Signed-off-by: John Edward Broadbent <jebr@google.com>
+---
+ bmc_state_manager.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++
+ bmc_state_manager.hpp | 13 ++++++++++++
+ 2 files changed, 59 insertions(+)
+
+diff --git a/bmc_state_manager.cpp b/bmc_state_manager.cpp
+index 22f2a42..2828d76 100644
+--- a/bmc_state_manager.cpp
++++ b/bmc_state_manager.cpp
+@@ -12,6 +12,8 @@
+ #include <filesystem>
+ #include <fstream>
+ #include <iostream>
++#include <optional>
++
+
+ namespace phosphor
+ {
+@@ -20,6 +22,8 @@ namespace state
+ namespace manager
+ {
+
++constexpr std::string_view flag_file =
++ "/var/google/phosphor-state-manager-reboot.flag";
+ PHOSPHOR_LOG2_USING;
+
+ // When you see server:: you know we're referencing our base class
+@@ -152,6 +156,16 @@ void BMC::executeTransition(const Transition tranReq)
+
+ method.append(sysdUnit, "replace-irreversibly");
+
++ // Explain cause of reboot to be discovered
++ try
++ {
++ writeResetFlag();
++ }
++ catch (const std::exception& e)
++ {
++ info("Unable to write flag file {ERROR}", "ERROR", e);
++ }
++
+ // Put BMC state not NotReady when issuing a BMC reboot
+ // and stop monitoring for state changes
+ this->currentBMCState(BMCState::NotReady);
+@@ -328,9 +342,41 @@ void BMC::discoverLastRebootCause()
+ this->lastRebootCause(RebootCause::POR);
+ }
+
++ // If the reason is not above check the rwfs file for a reason
++ try
++ {
++ auto res = readResetFlag();
++ this->lastRebootCause(res.value_or(RebootCause::Unknown));
++ }
++ catch (const std::exception& e)
++ {
++ info("Unable to read flag file {ERROR}", "ERROR", e);
++ }
+ return;
+ }
+
++void BMC::writeResetFlag()
++{
++ if(std::filesystem::exists(flag_file))
++ {
++ error("Reset flag is already present");
++ return;
++ }
++ // create a symlink to dev null to show graceful intent
++ std::filesystem::create_symlink("/dev/null", flag_file);
++}
++
++std::optional<BMC::RebootCause> BMC::readResetFlag()
++{
++ if(!std::filesystem::exists(flag_file))
++ {
++ return std::nullopt;
++ }
++ info("Rest flag file found");
++ std::filesystem::remove(flag_file);
++ return RebootCause::Software;
++}
++
+ } // namespace manager
+ } // namespace state
+ } // namespace phosphor
+diff --git a/bmc_state_manager.hpp b/bmc_state_manager.hpp
+index 8781e3f..66f7dbd 100644
+--- a/bmc_state_manager.hpp
++++ b/bmc_state_manager.hpp
+@@ -10,6 +10,7 @@
+
+ #include <cassert>
+ #include <chrono>
++#include <optional>
+
+ namespace phosphor
+ {
+@@ -144,6 +145,18 @@ class BMC : public BMCInherit
+ * @brief the lastRebootTime calcuated at startup.
+ **/
+ uint64_t rebootTime;
++
++ /**
++ * @brief check for the existance of readResetFlag
++ **/
++ std::optional<RebootCause> readResetFlag();
++
++ /**
++ * @brief writes the ResetFlag
++ **/
++ void writeResetFlag();
++
++
+ };
+
+ } // namespace manager
diff --git a/recipes-phosphor/state/phosphor-state-manager_git.bb_append b/recipes-phosphor/state/phosphor-state-manager_git.bb_append
new file mode 100644
index 0000000..c91b406
--- /dev/null
+++ b/recipes-phosphor/state/phosphor-state-manager_git.bb_append
@@ -0,0 +1,4 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+
+SRC_URI:append = "file://0001-Adds-bmc-reboot-flag-identify-reboot-types.patch"
+