diff --git a/src/sonic-framework/rebootbackend/reboot_thread.cpp b/src/sonic-framework/rebootbackend/reboot_thread.cpp index fc758b3610c2..0f1a1cbaa290 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::HALT) { + do_halt_reboot(s); } else { // This shouldn't be possible. Reference check_start_preconditions() SWSS_LOG_ERROR("Received unrecognized method type = %s", @@ -163,6 +165,27 @@ void RebootThread::do_cold_reboot(swss::Select &s) { return; } +void RebootThread::do_halt_reboot(swss::Select &s) { + SWSS_LOG_ENTER(); + SWSS_LOG_NOTICE("Sending halt reboot request to platform"); + if (send_dbus_reboot_request() == Progress::EXIT_EARLY) { + return; + } + + // Wait for platform to reboot. If we return, reboot failed. + // Logging, error status and monitoring for critical state are handled within. + 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("platform failed to reboot"); + + // Set critical state + m_critical_interface.report_critical_state("platform failed to reboot"); + return; +} + void RebootThread::reboot_thread(void) { SWSS_LOG_ENTER(); diff --git a/src/sonic-framework/rebootbackend/reboot_thread.h b/src/sonic-framework/rebootbackend/reboot_thread.h index a1799f342d7b..991b297f623d 100644 --- a/src/sonic-framework/rebootbackend/reboot_thread.h +++ b/src/sonic-framework/rebootbackend/reboot_thread.h @@ -36,7 +36,7 @@ class ThreadStatus { // Number of reboots since active. m_proto_status.set_count(0); - // RebootMethod is type of of reboot: cold, nsf, warm, fast from a + // RebootMethod is type of of reboot: cold, halt, nsf, warm, fast from a // RebootRequest m_proto_status.set_method(gnoi::system::RebootMethod::UNKNOWN); @@ -165,6 +165,7 @@ class RebootThread { void do_reboot(void); Progress send_dbus_reboot_request(); void do_cold_reboot(swss::Select &s); + void do_halt_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 1b2a88c078ca..a9a69febefab 100644 --- a/src/sonic-framework/rebootbackend/rebootbe.cpp +++ b/src/sonic-framework/rebootbackend/rebootbe.cpp @@ -180,6 +180,8 @@ NotificationResponse RebootBE::handle_reboot_request( if (response.status == swss::StatusCode::SWSS_RC_SUCCESS) { if (request.method() == gnoi::system::RebootMethod::COLD) { SetCurrentStatus(NsfManagerStatus::COLD_REBOOT_IN_PROGRESS); + } else if (request.method() == gnoi::system::RebootMethod::HALT) { + SetCurrentStatus(NsfManagerStatus::HALT_REBOOT_IN_PROGRESS); } else if (request.method() == gnoi::system::RebootMethod::NSF) { SetCurrentStatus(NsfManagerStatus::NSF_REBOOT_IN_PROGRESS); } @@ -191,6 +193,7 @@ bool RebootBE::reboot_allowed(const gnoi::system::RebootMethod reboot_method) { NsfManagerStatus current_status = GetCurrentStatus(); switch (current_status) { case NsfManagerStatus::COLD_REBOOT_IN_PROGRESS: + case NsfManagerStatus::HALT_REBOOT_IN_PROGRESS: case NsfManagerStatus::NSF_REBOOT_IN_PROGRESS: { return false; } diff --git a/src/sonic-framework/rebootbackend/rebootbe.h b/src/sonic-framework/rebootbackend/rebootbe.h index 65fee28aebba..2a2b9d551202 100644 --- a/src/sonic-framework/rebootbackend/rebootbe.h +++ b/src/sonic-framework/rebootbackend/rebootbe.h @@ -29,6 +29,7 @@ class RebootBE { NSF_INIT_WAIT, IDLE, COLD_REBOOT_IN_PROGRESS, + HALT_REBOOT_IN_PROGRESS, NSF_REBOOT_IN_PROGRESS };