Skip to content

Commit b3b5c41

Browse files
rkavitha-hclBibhuprasad Singh
authored and
Bibhuprasad Singh
committed
Enabling warm reboot and HALT method support in sonic-buildimage in rebootbackend process
1 parent d0e5881 commit b3b5c41

File tree

5 files changed

+93
-2
lines changed

5 files changed

+93
-2
lines changed

src/sonic-framework/rebootbackend/reboot_thread.cpp

+53
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ void RebootThread::do_reboot(void) {
117117

118118
if (m_request.method() == RebootMethod::COLD) {
119119
do_cold_reboot(s);
120+
} else if (m_request.method() == RebootMethod::HALT) {
121+
do_halt_reboot(s);
122+
} else if (m_request.method() == RebootMethod::WARM) {
123+
do_warm_reboot(s);
120124
} else {
121125
// This shouldn't be possible. Reference check_start_preconditions()
122126
SWSS_LOG_ERROR("Received unrecognized method type = %s",
@@ -163,6 +167,45 @@ void RebootThread::do_cold_reboot(swss::Select &s) {
163167
// We shouldn't be here. Platform reboot should've killed us.
164168
log_error_and_set_non_retry_failure("platform failed to reboot");
165169

170+
// Set critical state
171+
// m_critical_interface.report_critical_state("platform failed to reboot");
172+
return;
173+
}
174+
175+
void RebootThread::do_halt_reboot(swss::Select &s) {
176+
SWSS_LOG_ENTER();
177+
SWSS_LOG_NOTICE("Sending halt reboot request to platform");
178+
if (send_dbus_reboot_request() == Progress::EXIT_EARLY) {
179+
return;
180+
}
181+
182+
// Wait for platform to reboot. If we return, reboot failed.
183+
// Logging, error status and monitoring for critical state are handled within.
184+
if (wait_for_platform_reboot(s) == Progress::EXIT_EARLY) {
185+
return;
186+
}
187+
188+
// We shouldn't be here. Platform reboot halt should've killed us.
189+
log_error_and_set_non_retry_failure("platform failed to halt the system");
190+
191+
return;
192+
}
193+
194+
void RebootThread::do_warm_reboot(swss::Select &s) {
195+
SWSS_LOG_ENTER();
196+
SWSS_LOG_NOTICE("Sending warm reboot request to platform");
197+
if (send_dbus_reboot_request() == Progress::EXIT_EARLY) {
198+
return;
199+
}
200+
201+
// Wait for warm reboot. If we return, reboot failed.
202+
if (wait_for_platform_reboot(s) == Progress::EXIT_EARLY) {
203+
return;
204+
}
205+
206+
// We shouldn't be here. Platform reboot should've killed us.
207+
log_error_and_set_non_retry_failure("failed to warm reboot");
208+
166209
return;
167210
}
168211

@@ -184,9 +227,19 @@ bool RebootThread::check_start_preconditions(const RebootRequest &request,
184227
response.json_string = "RebootThread: can't Start while active";
185228
response.status = swss::StatusCode::SWSS_RC_IN_USE;
186229
} else if (request.method() != RebootMethod::COLD &&
230+
request.method() != RebootMethod::HALT &&
187231
request.method() != RebootMethod::WARM) {
188232
response.json_string = "RebootThread: Start rx'd unsupported method";
189233
response.status = swss::StatusCode::SWSS_RC_INVALID_PARAM;
234+
} else if (request.method() == RebootMethod::WARM) {
235+
if (m_status.get_last_reboot_status() ==
236+
RebootStatus_Status::RebootStatus_Status_STATUS_FAILURE) {
237+
// If the last reboot failed with a non-retriable failure, don't retry.
238+
// But, we will allow a cold boot to recover.
239+
response.json_string =
240+
"RebootThread: last WARM reboot failed with non-retriable failure";
241+
response.status = swss::StatusCode::SWSS_RC_FAILED_PRECONDITION;
242+
}
190243
} else if (request.delay() != 0) {
191244
response.json_string = "RebootThread: delayed start not supported";
192245
response.status = swss::StatusCode::SWSS_RC_INVALID_PARAM;

src/sonic-framework/rebootbackend/reboot_thread.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ThreadStatus {
3232
// Number of reboots since active.
3333
m_proto_status.set_count(0);
3434

35-
// RebootMethod is type of of reboot: cold, warm, fast from a
35+
// RebootMethod is type of of reboot: cold, halt, warm, fast from a
3636
// RebootRequest
3737
m_proto_status.set_method(gnoi::system::RebootMethod::UNKNOWN);
3838

@@ -161,6 +161,8 @@ class RebootThread {
161161
void do_reboot(void);
162162
Progress send_dbus_reboot_request();
163163
void do_cold_reboot(swss::Select &s);
164+
void do_halt_reboot(swss::Select &s);
165+
void do_warm_reboot(swss::Select &s);
164166

165167
// Inner loop select handler to wait for platform reboot.
166168
// wait for timeout

src/sonic-framework/rebootbackend/rebootbe.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ NotificationResponse RebootBE::HandleRebootRequest(
149149
if (!RebootAllowed(request.method())) {
150150
response.status = swss::StatusCode::SWSS_RC_IN_USE;
151151
response.json_string =
152-
"Reboot not allowed at this time. Reboot or "
152+
"Reboot not allowed at this time. Reboot, halt or "
153153
"post-warmboot in progress";
154154
SWSS_LOG_WARN("%s", response.json_string.c_str());
155155
return response;
@@ -161,6 +161,8 @@ NotificationResponse RebootBE::HandleRebootRequest(
161161
if (response.status == swss::StatusCode::SWSS_RC_SUCCESS) {
162162
if (request.method() == gnoi::system::RebootMethod::COLD) {
163163
SetCurrentStatus(RebManagerStatus::COLD_REBOOT_IN_PROGRESS);
164+
} else if (request.method() == gnoi::system::RebootMethod::HALT) {
165+
SetCurrentStatus(RebManagerStatus::HALT_REBOOT_IN_PROGRESS);
164166
} else if (request.method() == gnoi::system::RebootMethod::WARM) {
165167
SetCurrentStatus(RebManagerStatus::WARM_REBOOT_IN_PROGRESS);
166168
}
@@ -172,6 +174,7 @@ bool RebootBE::RebootAllowed(const gnoi::system::RebootMethod rebMethod) {
172174
RebManagerStatus current_status = GetCurrentStatus();
173175
switch (current_status) {
174176
case RebManagerStatus::COLD_REBOOT_IN_PROGRESS:
177+
case RebManagerStatus::HALT_REBOOT_IN_PROGRESS:
175178
case RebManagerStatus::WARM_REBOOT_IN_PROGRESS: {
176179
return false;
177180
}

src/sonic-framework/rebootbackend/rebootbe.h

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class RebootBE {
2424
WARM_INIT_WAIT,
2525
IDLE,
2626
COLD_REBOOT_IN_PROGRESS,
27+
HALT_REBOOT_IN_PROGRESS,
2728
WARM_REBOOT_IN_PROGRESS
2829
};
2930

src/sonic-framework/tests/reboot_thread_test.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,38 @@ TEST_F(RebootStatusTest, TestGetStatus) {
9191
EXPECT_EQ(0, response.when());
9292
}
9393

94+
TEST_F(RebootStatusTest, TestHaltGetStatus) {
95+
std::chrono::nanoseconds curr_ns =
96+
std::chrono::high_resolution_clock::now().time_since_epoch();
97+
98+
m_status.set_start_status(gnoi::system::RebootMethod::HALT, "reboot because");
99+
100+
gnoi::system::RebootStatusResponse response = m_status.get_response();
101+
EXPECT_EQ(
102+
response.status().status(),
103+
gnoi::system::RebootStatus_Status::RebootStatus_Status_STATUS_UNKNOWN);
104+
105+
m_status.set_completed_status(
106+
gnoi::system::RebootStatus_Status::RebootStatus_Status_STATUS_SUCCESS,
107+
"anything");
108+
109+
response = m_status.get_response();
110+
111+
// message should be empty while reboot is active
112+
EXPECT_THAT(response.status().message(), StrEq(""));
113+
114+
uint64_t reboot_ns = response.when();
115+
EXPECT_TRUE(reboot_ns > (uint64_t)curr_ns.count());
116+
117+
m_status.set_inactive();
118+
response = m_status.get_response();
119+
EXPECT_THAT(response.status().message(), StrEq("anything"));
120+
EXPECT_EQ(
121+
response.status().status(),
122+
gnoi::system::RebootStatus_Status::RebootStatus_Status_STATUS_SUCCESS);
123+
EXPECT_EQ(0, response.when());
124+
}
125+
94126
TEST_F(RebootStatusTest, TestGetWarmStatus) {
95127
std::chrono::nanoseconds curr_ns =
96128
std::chrono::high_resolution_clock::now().time_since_epoch();

0 commit comments

Comments
 (0)