diff --git a/src/sonic-framework/rebootbackend/reboot_thread.cpp b/src/sonic-framework/rebootbackend/reboot_thread.cpp index 81c43327a467..fb59b160e8e3 100644 --- a/src/sonic-framework/rebootbackend/reboot_thread.cpp +++ b/src/sonic-framework/rebootbackend/reboot_thread.cpp @@ -117,6 +117,8 @@ void RebootThread::do_reboot(void) { if (m_request.method() == RebootMethod::COLD) { do_cold_reboot(s); + } else if (m_request.method() == RebootMethod::WARM) { + do_warm_reboot(s); } else { // This shouldn't be possible. Reference check_start_preconditions() SWSS_LOG_ERROR("Received unrecognized method type = %s", @@ -166,6 +168,25 @@ void RebootThread::do_cold_reboot(swss::Select &s) { return; } +void RebootThread::do_warm_reboot(swss::Select &s) { + SWSS_LOG_ENTER(); + SWSS_LOG_NOTICE("Sending warm reboot request to platform"); + if (send_dbus_reboot_request() == Progress::EXIT_EARLY) { + return; + } + + // Wait for warm reboot. If we return, reboot failed. + if (wait_for_platform_reboot(s) == Progress::EXIT_EARLY) { + return; + } + + // We shouldn't be here. Platform reboot should've killed us. + log_error_and_set_non_retry_failure("failed to warm reboot"); + + return; +} + + void RebootThread::reboot_thread(void) { SWSS_LOG_ENTER(); @@ -187,6 +208,15 @@ bool RebootThread::check_start_preconditions(const RebootRequest &request, request.method() != RebootMethod::WARM) { response.json_string = "RebootThread: Start rx'd unsupported method"; response.status = swss::StatusCode::SWSS_RC_INVALID_PARAM; + } else if (request.method() == RebootMethod::WARM) { + if (m_status.get_last_reboot_status() == + RebootStatus_Status::RebootStatus_Status_STATUS_FAILURE) { + // If the last reboot failed with a non-retriable failure, don't retry. + // But, we will allow a cold boot to recover. + response.json_string = + "RebootThread: last WARM reboot failed with non-retriable failure"; + response.status = swss::StatusCode::SWSS_RC_FAILED_PRECONDITION; + } } else if (request.delay() != 0) { response.json_string = "RebootThread: delayed start not supported"; response.status = swss::StatusCode::SWSS_RC_INVALID_PARAM; diff --git a/src/sonic-framework/rebootbackend/reboot_thread.h b/src/sonic-framework/rebootbackend/reboot_thread.h index 46fded6bc38e..ee36e3cd01c5 100644 --- a/src/sonic-framework/rebootbackend/reboot_thread.h +++ b/src/sonic-framework/rebootbackend/reboot_thread.h @@ -161,6 +161,7 @@ class RebootThread { void do_reboot(void); Progress send_dbus_reboot_request(); void do_cold_reboot(swss::Select &s); + void do_warm_reboot(swss::Select &s); // Inner loop select handler to wait for platform reboot. // wait for timeout diff --git a/src/sonic-framework/rebootbackend/rebootbe.cpp b/src/sonic-framework/rebootbackend/rebootbe.cpp index 0a4705e71ffe..70bc7b6549af 100644 --- a/src/sonic-framework/rebootbackend/rebootbe.cpp +++ b/src/sonic-framework/rebootbackend/rebootbe.cpp @@ -13,6 +13,7 @@ #include "reboot_interfaces.h" #include "select.h" #include "status_code_util.h" +#include "warm_restart.h" namespace rebootbackend { @@ -46,6 +47,13 @@ void RebootBE::Start() { s.addSelectable(&m_Done); s.addSelectable(&m_RebootThreadFinished); + + if (swss::WarmStart::isWarmStart()) { + SetCurrentStatus(RebManagerStatus::WARM_INIT_WAIT); + } else { + SWSS_LOG_NOTICE("Warm restart not enabled"); + } + SWSS_LOG_NOTICE("RebootBE entering operational loop"); while (true) { swss::Selectable *sel;