From e2246d1215c79a4f33c7c6a86d92a7b2a975965b Mon Sep 17 00:00:00 2001 From: Anand Kumar Shaw Date: Thu, 20 Aug 2026 05:43:10 +0000 Subject: [PATCH] bmcweb: persist sessions before BMC restart Write pending web sessions to durable storage and fsync before requesting a BMC Graceful Restart or Force Restart, so login sessions survive reboot instead of being lost when the process is torn down before the deferred persist runs. Tested: on SP7, login token remained valid after GracefulRestart. Signed-off-by: Anand Kumar Shaw Co-authored-by: Cursor --- include/persistent_data.hpp | 12 ++++++++++++ include/sessions.hpp | 6 ++++++ redfish-core/lib/managers.hpp | 14 ++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/include/persistent_data.hpp b/include/persistent_data.hpp index 1c463b1d87..cdf7fd3e13 100644 --- a/include/persistent_data.hpp +++ b/include/persistent_data.hpp @@ -14,6 +14,8 @@ #include #include +#include + #include #include #include @@ -359,7 +361,17 @@ class ConfigFile if (ec) { BMCWEB_LOG_ERROR("Failed to write file {}", ec.message()); + return; + } + + // Ensure session data reaches durable storage before BMC reboot can + // tear down the process or reset the platform. + if (::fsync(persistentFile.native_handle()) != 0) + { + BMCWEB_LOG_ERROR("Failed to fsync persistent data"); + return; } + SessionStore::getInstance().clearNeedWrite(); } std::string systemUuid; diff --git a/include/sessions.hpp b/include/sessions.hpp index 22aa3adf0c..1d94afb84e 100644 --- a/include/sessions.hpp +++ b/include/sessions.hpp @@ -434,6 +434,12 @@ class SessionStore { return needWrite; } + + void clearNeedWrite() + { + needWrite = false; + } + int64_t getTimeoutInSeconds() const { return std::chrono::seconds(timeoutInSeconds).count(); diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp index 2f67a4193b..69a04efbed 100644 --- a/redfish-core/lib/managers.hpp +++ b/redfish-core/lib/managers.hpp @@ -74,6 +74,15 @@ inline std::string getBMCUpdateServicePath() return "/xyz/openbmc_project/software"; } +inline void flushPersistentSessions() +{ + persistent_data::SessionStore::getInstance().applySessionTimeouts(); + if (persistent_data::SessionStore::getInstance().needsWrite()) + { + persistent_data::getConfig().writeData(); + } +} + /** * Function reboots the BMC. * @@ -82,6 +91,9 @@ inline std::string getBMCUpdateServicePath() inline void doBMCGracefulRestart( const std::shared_ptr& asyncResp) { + // Persist sessions before reboot so web UI login survives BMC reset. + flushPersistentSessions(); + const char* processName = "xyz.openbmc_project.State.BMC"; const char* objectPath = "/xyz/openbmc_project/state/bmc0"; const char* interfaceName = "xyz.openbmc_project.State.BMC"; @@ -109,6 +121,8 @@ inline void doBMCGracefulRestart( inline void doBMCForceRestart( const std::shared_ptr& asyncResp) { + flushPersistentSessions(); + const char* processName = "xyz.openbmc_project.State.BMC"; const char* objectPath = "/xyz/openbmc_project/state/bmc0"; const char* interfaceName = "xyz.openbmc_project.State.BMC";