Skip to content

Commit 7e3b2c6

Browse files
authored
[Evpn Warmreboot] Added Dependancy check logic in VrfMgr (sonic-net#1466)
* [Evpn Warmreboot] Added Dependancy check logic in VrfMgr This was done to ensure for EVPN warm-reboot the order of data replay to kernel is maintained across various submodules and the kernel programming will be successful. * Marking Vrfmgrd and Intfmgrd to reconcile immediately after replay There is no reconcile operation required in vrfmgrd and intfmgrd, hence immediately after replay these are marked as reconciled
1 parent a960e2e commit 7e3b2c6

File tree

5 files changed

+71
-2
lines changed

5 files changed

+71
-2
lines changed

cfgmgr/intfmgr.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ using namespace swss;
2424

2525
IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, const vector<string> &tableNames) :
2626
Orch(cfgDb, tableNames),
27+
m_cfgIntfTable(cfgDb, CFG_INTF_TABLE_NAME),
28+
m_cfgVlanIntfTable(cfgDb, CFG_VLAN_INTF_TABLE_NAME),
29+
m_cfgLagIntfTable(cfgDb, CFG_LAG_INTF_TABLE_NAME),
30+
m_cfgLoopbackIntfTable(cfgDb, CFG_LOOPBACK_INTERFACE_TABLE_NAME),
2731
m_statePortTable(stateDb, STATE_PORT_TABLE_NAME),
2832
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME),
2933
m_stateVlanTable(stateDb, STATE_VLAN_TABLE_NAME),
@@ -34,6 +38,12 @@ IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
3438
if (!WarmStart::isWarmStart())
3539
{
3640
flushLoopbackIntfs();
41+
WarmStart::setWarmStartState("intfmgrd", WarmStart::WSDISABLED);
42+
}
43+
else
44+
{
45+
//Build the interface list to be replayed to Kernel
46+
buildIntfReplayList();
3747
}
3848
}
3949

@@ -172,6 +182,25 @@ int IntfMgr::getIntfIpCount(const string &alias)
172182
return std::stoi(res);
173183
}
174184

185+
void IntfMgr::buildIntfReplayList(void)
186+
{
187+
vector<string> intfList;
188+
189+
m_cfgIntfTable.getKeys(intfList);
190+
std::copy( intfList.begin(), intfList.end(), std::inserter( m_pendingReplayIntfList, m_pendingReplayIntfList.end() ) );
191+
192+
m_cfgLoopbackIntfTable.getKeys(intfList);
193+
std::copy( intfList.begin(), intfList.end(), std::inserter( m_pendingReplayIntfList, m_pendingReplayIntfList.end() ) );
194+
195+
m_cfgVlanIntfTable.getKeys(intfList);
196+
std::copy( intfList.begin(), intfList.end(), std::inserter( m_pendingReplayIntfList, m_pendingReplayIntfList.end() ) );
197+
198+
m_cfgLagIntfTable.getKeys(intfList);
199+
std::copy( intfList.begin(), intfList.end(), std::inserter( m_pendingReplayIntfList, m_pendingReplayIntfList.end() ) );
200+
201+
SWSS_LOG_INFO("Found %d Total Intfs to be replayed", (int)m_pendingReplayIntfList.size() );
202+
}
203+
175204
bool IntfMgr::isIntfCreated(const string &alias)
176205
{
177206
vector<FieldValueTuple> temp;
@@ -676,6 +705,7 @@ bool IntfMgr::doIntfAddrTask(const vector<string>& keys,
676705
void IntfMgr::doTask(Consumer &consumer)
677706
{
678707
SWSS_LOG_ENTER();
708+
static bool replayDone = false;
679709

680710
auto it = consumer.m_toSync.begin();
681711
while (it != consumer.m_toSync.end())
@@ -693,6 +723,11 @@ void IntfMgr::doTask(Consumer &consumer)
693723
it++;
694724
continue;
695725
}
726+
else
727+
{
728+
//Entry programmed, remove it from pending list if present
729+
m_pendingReplayIntfList.erase(keys[0]);
730+
}
696731
}
697732
else if (keys.size() == 2)
698733
{
@@ -701,6 +736,11 @@ void IntfMgr::doTask(Consumer &consumer)
701736
it++;
702737
continue;
703738
}
739+
else
740+
{
741+
//Entry programmed, remove it from pending list if present
742+
m_pendingReplayIntfList.erase(keys[0] + config_db_key_delimiter + keys[1] );
743+
}
704744
}
705745
else
706746
{
@@ -709,4 +749,13 @@ void IntfMgr::doTask(Consumer &consumer)
709749

710750
it = consumer.m_toSync.erase(it);
711751
}
752+
753+
if (!replayDone && WarmStart::isWarmStart() && m_pendingReplayIntfList.empty() )
754+
{
755+
replayDone = true;
756+
WarmStart::setWarmStartState("intfmgrd", WarmStart::REPLAYED);
757+
// There is no operation to be performed for intfmgr reconcillation
758+
// Hence mark it reconciled right away
759+
WarmStart::setWarmStartState("intfmgrd", WarmStart::RECONCILED);
760+
}
712761
}

cfgmgr/intfmgr.h

+3
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ class IntfMgr : public Orch
1919

2020
private:
2121
ProducerStateTable m_appIntfTableProducer;
22+
Table m_cfgIntfTable, m_cfgVlanIntfTable, m_cfgLagIntfTable, m_cfgLoopbackIntfTable;
2223
Table m_statePortTable, m_stateLagTable, m_stateVlanTable, m_stateVrfTable, m_stateIntfTable;
2324

2425
std::set<std::string> m_subIntfList;
2526
std::set<std::string> m_loopbackIntfList;
27+
std::set<std::string> m_pendingReplayIntfList;
2628

2729
void setIntfIp(const std::string &alias, const std::string &opCmd, const IpPrefix &ipPrefix);
2830
void setIntfVrf(const std::string &alias, const std::string &vrfName);
@@ -36,6 +38,7 @@ class IntfMgr : public Orch
3638
bool isIntfCreated(const std::string &alias);
3739
bool isIntfChangeVrf(const std::string &alias, const std::string &vrfName);
3840
int getIntfIpCount(const std::string &alias);
41+
void buildIntfReplayList(void);
3942

4043
void addLoopbackIntf(const std::string &alias);
4144
void delLoopbackIntf(const std::string &alias);

cfgmgr/vrfmgr.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ VrfMgr::VrfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, con
102102
<< IP_CMD << " -6 rule add pref " << TABLE_LOCAL_PREF << " table local && " << IP_CMD << " -6 rule del pref 0";
103103
EXEC_WITH_ERROR_THROW(cmd.str(), res);
104104
}
105+
106+
if (!WarmStart::isWarmStart())
107+
{
108+
WarmStart::setWarmStartState("vrfmgrd", WarmStart::WSDISABLED);
109+
}
105110
}
106111

107112
uint32_t VrfMgr::getFreeTable(void)

cfgmgr/vrfmgrd.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ mutex gDbMutex;
3535
int main(int argc, char **argv)
3636
{
3737
Logger::linkToDbNative("vrfmgrd");
38+
bool isWarmStart = false;
3839
SWSS_LOG_ENTER();
3940

4041
SWSS_LOG_NOTICE("--- Starting vrfmgrd ---");
@@ -56,6 +57,8 @@ int main(int argc, char **argv)
5657

5758
VrfMgr vrfmgr(&cfgDb, &appDb, &stateDb, cfg_vrf_tables);
5859

60+
isWarmStart = WarmStart::isWarmStart();
61+
5962
// TODO: add tables in stateDB which interface depends on to monitor list
6063
std::vector<Orch *> cfgOrchList = {&vrfmgr};
6164

@@ -69,6 +72,7 @@ int main(int argc, char **argv)
6972
while (true)
7073
{
7174
Selectable *sel;
75+
static bool firstReadTimeout = true;
7276
int ret;
7377

7478
ret = s.select(&sel, SELECT_TIMEOUT);
@@ -80,6 +84,14 @@ int main(int argc, char **argv)
8084
if (ret == Select::TIMEOUT)
8185
{
8286
vrfmgr.doTask();
87+
if (isWarmStart && firstReadTimeout)
88+
{
89+
firstReadTimeout = false;
90+
WarmStart::setWarmStartState("vrfmgrd", WarmStart::REPLAYED);
91+
// There is no operation to be performed for vrfmgrd reconcillation
92+
// Hence mark it reconciled right away
93+
WarmStart::setWarmStartState("vrfmgrd", WarmStart::RECONCILED);
94+
}
8395
continue;
8496
}
8597

tests/test_warm_reboot.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def swss_check_RestoreCount(dvs, state_db, restore_count):
4646
if fv[0] == "restore_count":
4747
assert int(fv[1]) == restore_count[key] + 1
4848
elif fv[0] == "state":
49-
assert fv[1] == "reconciled"
49+
assert fv[1] == "reconciled" or fv[1] == "disabled"
5050

5151
def check_port_oper_status(appl_db, port_name, state):
5252
portTbl = swsscommon.Table(appl_db, swsscommon.APP_PORT_TABLE_NAME)
@@ -76,7 +76,7 @@ def swss_app_check_RestoreCount_single(state_db, restore_count, name):
7676
if fv[0] == "restore_count":
7777
assert int(fv[1]) == restore_count[key] + 1
7878
elif fv[0] == "state":
79-
assert fv[1] == "reconciled"
79+
assert fv[1] == "reconciled" or fv[1] == "disabled"
8080

8181
def swss_app_check_warmstart_state(state_db, name, state):
8282
warmtbl = swsscommon.Table(state_db, swsscommon.STATE_WARM_RESTART_TABLE_NAME)

0 commit comments

Comments
 (0)