Skip to content

Commit 829b219

Browse files
[tunnelmgrd]: Warm boot support (sonic-net#2166)
* [tunnelmgrd]: Warm boot support Signed-off-by: Lawrence Lee <[email protected]>
1 parent ad65b0a commit 829b219

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed

cfgmgr/tunnelmgr.cpp

+44-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "tokenize.h"
1010
#include "shellcmd.h"
1111
#include "exec.h"
12+
#include "warm_restart.h"
1213

1314
using namespace std;
1415
using namespace swss;
@@ -107,7 +108,8 @@ static int cmdIpTunnelRouteDel(const std::string& pfx, std::string & res)
107108
TunnelMgr::TunnelMgr(DBConnector *cfgDb, DBConnector *appDb, const std::vector<std::string> &tableNames) :
108109
Orch(cfgDb, tableNames),
109110
m_appIpInIpTunnelTable(appDb, APP_TUNNEL_DECAP_TABLE_NAME),
110-
m_cfgPeerTable(cfgDb, CFG_PEER_SWITCH_TABLE_NAME)
111+
m_cfgPeerTable(cfgDb, CFG_PEER_SWITCH_TABLE_NAME),
112+
m_cfgTunnelTable(cfgDb, CFG_TUNNEL_TABLE_NAME)
111113
{
112114
std::vector<string> peer_keys;
113115
m_cfgPeerTable.getKeys(peer_keys);
@@ -126,6 +128,23 @@ TunnelMgr::TunnelMgr(DBConnector *cfgDb, DBConnector *appDb, const std::vector<s
126128
}
127129
}
128130
}
131+
132+
if (WarmStart::isWarmStart())
133+
{
134+
std::vector<string> tunnel_keys;
135+
m_cfgTunnelTable.getKeys(tunnel_keys);
136+
137+
for (auto tunnel: tunnel_keys)
138+
{
139+
m_tunnelReplay.insert(tunnel);
140+
}
141+
if (m_tunnelReplay.empty())
142+
{
143+
finalizeWarmReboot();
144+
}
145+
146+
}
147+
129148

130149
auto consumerStateTable = new swss::ConsumerStateTable(appDb, APP_TUNNEL_ROUTE_TABLE_NAME,
131150
TableConsumable::DEFAULT_POP_BATCH_SIZE, default_orch_pri);
@@ -191,6 +210,11 @@ void TunnelMgr::doTask(Consumer &consumer)
191210
++it;
192211
}
193212
}
213+
214+
if (!replayDone && m_tunnelReplay.empty() && WarmStart::isWarmStart())
215+
{
216+
finalizeWarmReboot();
217+
}
194218
}
195219

196220
bool TunnelMgr::doTunnelTask(const KeyOpFieldsValuesTuple & t)
@@ -230,8 +254,16 @@ bool TunnelMgr::doTunnelTask(const KeyOpFieldsValuesTuple & t)
230254
SWSS_LOG_NOTICE("Peer/Remote IP not configured");
231255
}
232256

233-
m_appIpInIpTunnelTable.set(tunnelName, kfvFieldsValues(t));
257+
/* If the tunnel is already in hardware (i.e. present in the replay),
258+
* don't try to create it again since it will cause an OA crash
259+
* (warmboot case)
260+
*/
261+
if (m_tunnelReplay.find(tunnelName) == m_tunnelReplay.end())
262+
{
263+
m_appIpInIpTunnelTable.set(tunnelName, kfvFieldsValues(t));
264+
}
234265
}
266+
m_tunnelReplay.erase(tunnelName);
235267
m_tunnelCache[tunnelName] = tunInfo;
236268
}
237269
else
@@ -356,3 +388,13 @@ bool TunnelMgr::configIpTunnel(const TunnelInfo& tunInfo)
356388

357389
return true;
358390
}
391+
392+
393+
void TunnelMgr::finalizeWarmReboot()
394+
{
395+
replayDone = true;
396+
WarmStart::setWarmStartState("tunnelmgrd", WarmStart::REPLAYED);
397+
SWSS_LOG_NOTICE("tunnelmgrd warmstart state set to REPLAYED");
398+
WarmStart::setWarmStartState("tunnelmgrd", WarmStart::RECONCILED);
399+
SWSS_LOG_NOTICE("tunnelmgrd warmstart state set to RECONCILED");
400+
}

cfgmgr/tunnelmgr.h

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "producerstatetable.h"
55
#include "orch.h"
66

7+
#include <set>
8+
79
namespace swss {
810

911
struct TunnelInfo
@@ -28,12 +30,18 @@ class TunnelMgr : public Orch
2830

2931
bool configIpTunnel(const TunnelInfo& info);
3032

33+
void finalizeWarmReboot();
34+
3135
ProducerStateTable m_appIpInIpTunnelTable;
3236
Table m_cfgPeerTable;
37+
Table m_cfgTunnelTable;
3338

3439
std::map<std::string, TunnelInfo > m_tunnelCache;
3540
std::map<std::string, IpPrefix> m_intfCache;
3641
std::string m_peerIp;
42+
43+
std::set<std::string> m_tunnelReplay;
44+
bool replayDone = false;
3745
};
3846

3947
}

cfgmgr/tunnelmgrd.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "exec.h"
1212
#include "schema.h"
1313
#include "tunnelmgr.h"
14+
#include "warm_restart.h"
1415

1516
using namespace std;
1617
using namespace swss;
@@ -54,6 +55,9 @@ int main(int argc, char **argv)
5455
DBConnector cfgDb("CONFIG_DB", 0);
5556
DBConnector appDb("APPL_DB", 0);
5657

58+
WarmStart::initialize("tunnelmgrd", "swss");
59+
WarmStart::checkWarmStart("tunnelmgrd", "swss");
60+
5761
TunnelMgr tunnelmgr(&cfgDb, &appDb, cfgTunTables);
5862

5963
std::vector<Orch *> cfgOrchList = {&tunnelmgr};

tests/test_warm_reboot.py

+29
Original file line numberDiff line numberDiff line change
@@ -2365,6 +2365,35 @@ def test_EverflowWarmReboot(self, dvs, dvs_acl):
23652365
dvs.start_swss()
23662366
dvs.check_swss_ready()
23672367

2368+
def test_TunnelMgrdWarmRestart(self, dvs):
2369+
tunnel_name = "MuxTunnel0"
2370+
tunnel_table = "TUNNEL_DECAP_TABLE"
2371+
tunnel_params = {
2372+
"tunnel_type": "IPINIP",
2373+
"dst_ip": "10.1.0.32",
2374+
"dscp_mode": "uniform",
2375+
"ecn_mode": "standard",
2376+
"ttl_mode": "pipe"
2377+
}
2378+
2379+
pubsub = dvs.SubscribeAppDbObject(tunnel_table)
2380+
2381+
dvs.runcmd("config warm_restart enable swss")
2382+
config_db = dvs.get_config_db()
2383+
config_db.create_entry("TUNNEL", tunnel_name, tunnel_params)
2384+
2385+
app_db = dvs.get_app_db()
2386+
app_db.wait_for_matching_keys(tunnel_table, [tunnel_name])
2387+
2388+
nadd, ndel = dvs.CountSubscribedObjects(pubsub)
2389+
assert nadd == len(tunnel_params)
2390+
assert ndel == 1 # Expect 1 deletion as part of table creation
2391+
2392+
dvs.runcmd("supervisorctl restart tunnelmgrd")
2393+
dvs.check_services_ready()
2394+
nadd, ndel = dvs.CountSubscribedObjects(pubsub)
2395+
assert nadd == 0
2396+
assert ndel == 0
23682397

23692398
# Add Dummy always-pass test at end as workaroud
23702399
# for issue when Flaky fail on final test it invokes module tear-down before retrying

0 commit comments

Comments
 (0)