From 0c257c373e78a01856e056204b7f37d407ec7b32 Mon Sep 17 00:00:00 2001 From: Kavitha Ramalingam Date: Wed, 13 Nov 2024 20:01:17 +0530 Subject: [PATCH] gNOI Warm Reboot - rebootbackend changes --- .../rebootbackend/gnoi_reboot_dbus.h | 72 ---------- .../rebootbackend/init_thread.h | 136 ------------------ .../rebootbackend/reboot_thread.cpp | 29 ++++ .../rebootbackend/reboot_thread.h | 1 + .../rebootbackend/rebootbe.cpp | 8 ++ src/sonic-framework/tests/rebootbe_test.cpp | 1 - 6 files changed, 38 insertions(+), 209 deletions(-) delete mode 100644 src/sonic-framework/rebootbackend/gnoi_reboot_dbus.h delete mode 100644 src/sonic-framework/rebootbackend/init_thread.h diff --git a/src/sonic-framework/rebootbackend/gnoi_reboot_dbus.h b/src/sonic-framework/rebootbackend/gnoi_reboot_dbus.h deleted file mode 100644 index bde79f7c3873..000000000000 --- a/src/sonic-framework/rebootbackend/gnoi_reboot_dbus.h +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * This file was automatically generated by dbusxx-xml2cpp; DO NOT EDIT! - */ - -#ifndef __dbusxx__rebootbackend_gnoi_reboot_dbus_h__PROXY_MARSHAL_H -#define __dbusxx__rebootbackend_gnoi_reboot_dbus_h__PROXY_MARSHAL_H - -#include -#include - -namespace org { -namespace SONiC { -namespace HostService { - -class gnoi_reboot_proxy -: public ::DBus::InterfaceProxy -{ -public: - - gnoi_reboot_proxy() - : ::DBus::InterfaceProxy("org.SONiC.HostService.gnoi_reboot") - { - } - -public: - - /* properties exported by this interface */ -public: - - /* methods exported by this interface, - * this functions will invoke the corresponding methods on the remote objects - */ - void issue_reboot(const std::vector< std::string >& options, int32_t& argout0, std::string& argout1) - { - ::DBus::CallMessage call; - ::DBus::MessageIter wi = call.writer(); - - wi << options; - call.member("issue_reboot"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> argout0; - ri >> argout1; - } - - void get_reboot_status(int32_t& argout0, std::string& argout1) - { - ::DBus::CallMessage call; - call.member("get_reboot_status"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - ri >> argout0; - ri >> argout1; - } - - -public: - - /* signal handlers for this interface - */ - -private: - - /* unmarshalers (to unpack the DBus message before calling the actual signal handler) - */ -}; - -} } } -#endif //__dbusxx__rebootbackend_gnoi_reboot_dbus_h__PROXY_MARSHAL_H diff --git a/src/sonic-framework/rebootbackend/init_thread.h b/src/sonic-framework/rebootbackend/init_thread.h deleted file mode 100644 index 50c27d6c8c34..000000000000 --- a/src/sonic-framework/rebootbackend/init_thread.h +++ /dev/null @@ -1,136 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "dbconnector.h" -#include "notificationproducer.h" -#include "reboot_common.h" -#include "reboot_interfaces.h" -#include "redis_utils.h" -#include "select.h" -#include "selectableevent.h" -#include "selectabletimer.h" -#include "subscriberstatetable.h" -#include "system/system.pb.h" - -namespace rebootbackend { - -// Holds a thread safe representation of the InitThread internal state. -// Thread-safe: the expectation is one thread will write and multiple threads -// will read. -class InitThreadStatus { - public: - enum ThreadStatus { - NOT_STARTED = 0, - PENDING = 1, - WAITING_FOR_REGISTRATION = 2, - WAITING_FOR_RECONCILIATION = 3, - WAITING_FOR_STATE_VERIFICATION = 4, - WAITING_FOR_UNFREEZE = 5, - FINALIZE = 6, - DONE = 7, - ERROR = 8, - }; - - enum ErrorCondition { - NO_ERROR = 0, - UNKNOWN = 1, - INTERNAL_ERROR = 2, - REGISTRATION_FAILED = 3, - RECONCILIATION_FAILED = 4, - STATE_VERIFICATION_FAILED = 5, - UNFREEZE_FAILED = 6, - DETECTED_CRITICAL_STATE = 7, - }; - - struct DetailedStatus { - gnoi::system::RebootStatusResponse thread_state; - InitThreadStatus::ThreadStatus detailed_thread_status = - InitThreadStatus::ThreadStatus::NOT_STARTED; - InitThreadStatus::ErrorCondition detailed_thread_error_condition = - InitThreadStatus::ErrorCondition::NO_ERROR; - }; - - InitThreadStatus() { - m_status.detailed_thread_status = ThreadStatus::NOT_STARTED; - m_status.detailed_thread_error_condition = ErrorCondition::NO_ERROR; - - m_status.thread_state.set_active(false); - m_status.thread_state.set_method(gnoi::system::RebootMethod::COLD); - m_status.thread_state.mutable_status()->set_status( - gnoi::system::RebootStatus_Status::RebootStatus_Status_STATUS_SUCCESS); - m_status.thread_state.mutable_status()->set_message(""); - } - - void set_start_status() { - const std::lock_guard lock(m_mutex); - m_status.detailed_thread_status = ThreadStatus::PENDING; - m_status.detailed_thread_error_condition = ErrorCondition::NO_ERROR; - - m_status.thread_state.set_active(true); - m_status.thread_state.set_method(gnoi::system::RebootMethod::NSF); - m_status.thread_state.mutable_status()->set_status( - gnoi::system::RebootStatus_Status::RebootStatus_Status_STATUS_UNKNOWN); - m_status.thread_state.mutable_status()->set_message(""); - } - - bool get_active(void) { - const std::lock_guard lock(m_mutex); - return m_status.thread_state.active(); - } - - void set_detailed_thread_status(ThreadStatus new_status) { - const std::lock_guard lock(m_mutex); - if (m_status.thread_state.active()) { - m_status.detailed_thread_status = new_status; - } - } - - void set_success() { - const std::lock_guard lock(m_mutex); - if (m_status.thread_state.active()) { - m_status.detailed_thread_status = ThreadStatus::DONE; - m_status.thread_state.mutable_status()->set_status( - gnoi::system::RebootStatus_Status:: - RebootStatus_Status_STATUS_SUCCESS); - } - } - - void set_error(ErrorCondition error_condition, - const std::string &error_message) { - const std::lock_guard lock(m_mutex); - if (m_status.thread_state.active()) { - m_status.detailed_thread_status = ThreadStatus::ERROR; - m_status.detailed_thread_error_condition = error_condition; - m_status.thread_state.mutable_status()->set_status( - gnoi::system::RebootStatus_Status:: - RebootStatus_Status_STATUS_FAILURE); - m_status.thread_state.mutable_status()->set_message(error_message); - } - } - - void set_inactive() { - const std::lock_guard lock(m_mutex); - m_status.thread_state.set_active(false); - } - - DetailedStatus get_detailed_thread_status() { - const std::lock_guard lock(m_mutex); - return m_status; - } - - gnoi::system::RebootStatusResponse get_response() { - const std::lock_guard lock(m_mutex); - return m_status.thread_state; - } - - private: - std::mutex m_mutex; - DetailedStatus m_status; -}; - - -} // namespace rebootbackend diff --git a/src/sonic-framework/rebootbackend/reboot_thread.cpp b/src/sonic-framework/rebootbackend/reboot_thread.cpp index 81c43327a467..14f3d4522d9e 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,24 @@ 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 +207,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..3bf119bd30ec 100644 --- a/src/sonic-framework/rebootbackend/rebootbe.cpp +++ b/src/sonic-framework/rebootbackend/rebootbe.cpp @@ -1,4 +1,5 @@ #include "rebootbe.h" + #include #include @@ -13,6 +14,7 @@ #include "reboot_interfaces.h" #include "select.h" #include "status_code_util.h" +#include "warm_restart.h" namespace rebootbackend { @@ -46,6 +48,12 @@ 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; diff --git a/src/sonic-framework/tests/rebootbe_test.cpp b/src/sonic-framework/tests/rebootbe_test.cpp index 67cd3cc4322c..0ac1460faa7b 100644 --- a/src/sonic-framework/tests/rebootbe_test.cpp +++ b/src/sonic-framework/tests/rebootbe_test.cpp @@ -201,7 +201,6 @@ class RebootBEAutoStartTest : public RebootBETest, public ::testing::WithParamInterface { protected: RebootBEAutoStartTest() { - start_rebootbe(); std::this_thread::sleep_for(std::chrono::milliseconds(50));