-
Notifications
You must be signed in to change notification settings - Fork 539
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Warm reboot: Add common warm start functions to be used by all SWSS p…
…rocesses (#547) * Add common warm start functions to be used by all SWSS processes Signed-off-by: Jipan Yang <[email protected]> * Use updated state schema Signed-off-by: Jipan Yang <[email protected]> * Adapt to the new warm reboot schema Signed-off-by: Jipan Yang <[email protected]> * Use the new Table::getEntry() and Table::setEntry to replace redisClient operations Signed-off-by: Jipan Yang <[email protected]> * use the new Table:hget() and Table:hset() APIs Signed-off-by: Jipan Yang <[email protected]> * Add illustration about warm start knob usage Signed-off-by: Jipan Yang <[email protected]>
- Loading branch information
Showing
2 changed files
with
153 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#include <string> | ||
#include "logger.h" | ||
#include "schema.h" | ||
#include "warm_restart.h" | ||
|
||
namespace swss { | ||
|
||
const WarmStart::WarmStartStateNameMap WarmStart::warmStartStateNameMap = | ||
{ | ||
{INIT, "init"}, | ||
{RESTORED, "restored"}, | ||
{RECONCILED, "reconciled"} | ||
}; | ||
|
||
WarmStart &WarmStart::getInstance() | ||
{ | ||
static WarmStart m_warmStart; | ||
return m_warmStart; | ||
} | ||
|
||
/* | ||
* <1> Upon system reboot, the system enable knob will be checked. | ||
* If enabled, database data will be preserved, if not, database will be flushed. | ||
* No need to check docker level knobs in this case since the whole system is being rebooted . | ||
* <2> Upon docker service start, first to check system knob. | ||
* if enabled, docker warm start should be performed, otherwise system warm reboot will be ruined. | ||
* If system knob disabled, while docker knob enabled, this is likely an individual docker warm restart request. | ||
* Within each application which should take care warm start case, | ||
* when the system knob or docker knob enabled, we do further check on the | ||
* actual warm start state ( restart_count), if no warm start state data available, | ||
* the database has been flushed, do cold start. Otherwise warm start. | ||
*/ | ||
|
||
// Check warm start flag at the very begining of application, do it once for each process. | ||
bool WarmStart::checkWarmStart(const std::string &app_name, const std::string &docker_name) | ||
{ | ||
auto& warmStart = getInstance(); | ||
|
||
if (warmStart.m_stateDb) | ||
{ | ||
return true; | ||
} | ||
|
||
warmStart.m_stateDb = std::make_shared<swss::DBConnector>(STATE_DB, swss::DBConnector::DEFAULT_UNIXSOCKET, 0); | ||
warmStart.m_stateWarmRestartTable = std::unique_ptr<Table>(new Table(warmStart.m_stateDb.get(), STATE_WARM_RESTART_TABLE_NAME)); | ||
|
||
warmStart.m_cfgDb = std::make_shared<swss::DBConnector>(CONFIG_DB, swss::DBConnector::DEFAULT_UNIXSOCKET, 0); | ||
warmStart.m_cfgWarmRestartTable = std::unique_ptr<Table>(new Table(warmStart.m_cfgDb.get(), CFG_WARM_RESTART_TABLE_NAME)); | ||
|
||
warmStart.enabled = false; | ||
|
||
std::string value; | ||
// Check system level warm restart config first | ||
warmStart.m_cfgWarmRestartTable->hget("system", "enable", value); | ||
if (value == "true") | ||
{ | ||
warmStart.enabled = true; | ||
} | ||
|
||
// docker level warm restart configuration | ||
warmStart.m_cfgWarmRestartTable->hget(docker_name, "enable", value); | ||
if (value == "true") | ||
{ | ||
warmStart.enabled = true; | ||
} | ||
|
||
// For cold start, the whole state db will be flushed including warm start table. | ||
// Create the entry for this app here. | ||
if (!warmStart.enabled) | ||
{ | ||
warmStart.m_stateWarmRestartTable->hset(app_name, "restart_count", "0"); | ||
return true; | ||
} | ||
|
||
uint32_t restart_count = 0; | ||
warmStart.m_stateWarmRestartTable->hget(app_name, "restart_count", value); | ||
if (value == "") | ||
{ | ||
SWSS_LOG_WARN("%s doing warm start, but restart_count not found in stateDB %s table, fall back to cold start", | ||
app_name.c_str(), STATE_WARM_RESTART_TABLE_NAME); | ||
warmStart.enabled = false; | ||
warmStart.m_stateWarmRestartTable->hset(app_name, "restart_count", "0"); | ||
return true; | ||
} | ||
else | ||
{ | ||
restart_count = (uint32_t)stoul(value); | ||
} | ||
|
||
restart_count++; | ||
warmStart.m_stateWarmRestartTable->hset(app_name, "restart_count", std::to_string(restart_count)); | ||
SWSS_LOG_NOTICE("%s doing warm start, restart count %d", app_name.c_str(), restart_count); | ||
|
||
return true; | ||
} | ||
|
||
bool WarmStart::isWarmStart() | ||
{ | ||
auto& warmStart = getInstance(); | ||
|
||
return warmStart.enabled; | ||
} | ||
|
||
// Set the state restored flag | ||
void WarmStart::setWarmStartState(const std::string &app_name, WarmStartState state) | ||
{ | ||
auto& warmStart = getInstance(); | ||
|
||
warmStart.m_stateWarmRestartTable->hset(app_name, "state", warmStartStateNameMap.at(state).c_str()); | ||
SWSS_LOG_NOTICE("%s warm start state changed to %s", app_name.c_str(), warmStartStateNameMap.at(state).c_str()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#ifndef SWSS_WARM_RESTART_H | ||
#define SWSS_WARM_RESTART_H | ||
|
||
#include <string> | ||
#include "dbconnector.h" | ||
#include "table.h" | ||
|
||
namespace swss { | ||
|
||
class WarmStart | ||
{ | ||
public: | ||
enum WarmStartState | ||
{ | ||
INIT, | ||
RESTORED, | ||
RECONCILED, | ||
}; | ||
|
||
typedef std::map<WarmStartState, std::string> WarmStartStateNameMap; | ||
static const WarmStartStateNameMap warmStartStateNameMap; | ||
|
||
static WarmStart &getInstance(); | ||
|
||
static bool checkWarmStart(const std::string &app_name, const std::string &docker_name = "swss"); | ||
static bool isWarmStart(); | ||
static void setWarmStartState(const std::string &app_name, WarmStartState state); | ||
private: | ||
std::shared_ptr<swss::DBConnector> m_stateDb; | ||
std::shared_ptr<swss::DBConnector> m_cfgDb; | ||
std::unique_ptr<Table> m_stateWarmRestartTable; | ||
std::unique_ptr<Table> m_cfgWarmRestartTable; | ||
bool enabled; | ||
}; | ||
|
||
} | ||
|
||
#endif |