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";