Skip to content

Commit 025268a

Browse files
pavel-shirshovqiluo-msft
authored andcommitted
[WR]: Add reconciliation logic for teamsyncd (#725)
* Pospone QueueMap initialization until activation of counters * Generate queue maps only for front panel ports * Initial commit for teamsyncd reconc logic * Add log messages * PR refactoring * Make pending timeout configurable * if space thing * Update schema
1 parent 5803a8c commit 025268a

File tree

4 files changed

+92
-8
lines changed

4 files changed

+92
-8
lines changed

doc/swss-schema.md

+7
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,13 @@ Stores information for physical switch ports managed by the switch chip. Ports t
714714
; the elected routing-stack.
715715
; Supported range: 1-3600.
716716

717+
teamsyncd_timer = 1*4DIGIT ; teamsyncd_timer holds the time interval utilized by teamsyncd during warm-restart episodes.
718+
; The timer is started when teamsyncd starts. During the timer interval teamsyncd
719+
; will preserver all LAG interface changes, but it will not apply them. The changes
720+
; will only be applied when the timer expired. During the changes application the stale
721+
; LAG entries will be removed, the new LAG entries will be created.
722+
; Supported range: 1-9999. 0 is invalid
723+
717724

718725
### VXLAN\_TUNNEL
719726
Stores vxlan tunnels configuration

teamsyncd/teamsync.cpp

+65-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
#include <sys/socket.h>
55
#include <linux/if.h>
66
#include <netlink/route/link.h>
7+
#include <chrono>
78
#include "logger.h"
89
#include "netmsg.h"
910
#include "dbconnector.h"
1011
#include "producerstatetable.h"
12+
#include "warm_restart.h"
1113
#include "teamsync.h"
1214

1315
using namespace std;
16+
using namespace std::chrono;
1417
using namespace swss;
1518

1619
/* Taken from drivers/net/team/team.c */
@@ -22,6 +25,34 @@ TeamSync::TeamSync(DBConnector *db, DBConnector *stateDb, Select *select) :
2225
m_lagMemberTable(db, APP_LAG_MEMBER_TABLE_NAME),
2326
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME)
2427
{
28+
WarmStart::initialize("teamsyncd", "teamd");
29+
WarmStart::checkWarmStart("teamsyncd", "teamd");
30+
m_warmstart = WarmStart::isWarmStart();
31+
32+
if (m_warmstart)
33+
{
34+
m_start_time = steady_clock::now();
35+
auto warmRestartIval = WarmStart::getWarmStartTimer("teamsyncd", "teamd");
36+
m_pending_timeout = warmRestartIval ? warmRestartIval : DEFAULT_WR_PENDING_TIMEOUT;
37+
m_lagTable.create_temp_view();
38+
m_lagMemberTable.create_temp_view();
39+
SWSS_LOG_NOTICE("Starting in warmstart mode");
40+
}
41+
}
42+
43+
void TeamSync::periodic()
44+
{
45+
if (m_warmstart)
46+
{
47+
auto diff = duration_cast<seconds>(steady_clock::now() - m_start_time);
48+
if(diff.count() > m_pending_timeout)
49+
{
50+
applyState();
51+
m_warmstart = false; // apply state just once
52+
}
53+
}
54+
55+
doSelectableTask();
2556
}
2657

2758
void TeamSync::doSelectableTask()
@@ -44,6 +75,23 @@ void TeamSync::doSelectableTask()
4475
m_selectablesToRemove.clear();
4576
}
4677

78+
void TeamSync::applyState()
79+
{
80+
SWSS_LOG_NOTICE("Applying state");
81+
82+
m_lagTable.apply_temp_view();
83+
m_lagMemberTable.apply_temp_view();
84+
85+
for(auto &it: m_stateLagTablePreserved)
86+
{
87+
const auto &lagName = it.first;
88+
const auto &fvVector = it.second;
89+
m_stateLagTable.set(lagName, fvVector);
90+
}
91+
92+
m_stateLagTablePreserved.clear();
93+
}
94+
4795
void TeamSync::onMsg(int nlmsg_type, struct nl_object *obj)
4896
{
4997
struct rtnl_link *link = (struct rtnl_link *)obj;
@@ -90,7 +138,14 @@ void TeamSync::addLag(const string &lagName, int ifindex, bool admin_state,
90138
fvVector.clear();
91139
FieldValueTuple s("state", "ok");
92140
fvVector.push_back(s);
93-
m_stateLagTable.set(lagName, fvVector);
141+
if (m_warmstart)
142+
{
143+
m_stateLagTablePreserved[lagName] = fvVector;
144+
}
145+
else
146+
{
147+
m_stateLagTable.set(lagName, fvVector);
148+
}
94149

95150
/* Create the team instance */
96151
auto sync = make_shared<TeamPortSync>(lagName, ifindex, &m_lagMemberTable);
@@ -116,7 +171,15 @@ void TeamSync::removeLag(const string &lagName)
116171
if (m_teamSelectables.find(lagName) == m_teamSelectables.end())
117172
return;
118173

119-
m_stateLagTable.del(lagName);
174+
if (m_warmstart)
175+
{
176+
m_stateLagTablePreserved.erase(lagName);
177+
}
178+
else
179+
{
180+
m_stateLagTable.del(lagName);
181+
}
182+
120183
m_selectablesToRemove.insert(lagName);
121184
}
122185

teamsyncd/teamsync.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,23 @@
1111
#include "netmsg.h"
1212
#include <team.h>
1313

14+
// seconds
15+
const uint32_t DEFAULT_WR_PENDING_TIMEOUT = 70;
16+
17+
using namespace std::chrono;
18+
1419
namespace swss {
1520

1621
class TeamSync : public NetMsg
1722
{
1823
public:
1924
TeamSync(DBConnector *db, DBConnector *stateDb, Select *select);
2025

26+
void periodic();
27+
2128
/* Listen to RTM_NEWLINK, RTM_DELLINK to track team devices */
2229
virtual void onMsg(int nlmsg_type, struct nl_object *obj);
2330

24-
/* Handle all selectables add/removal events */
25-
void doSelectableTask();
26-
2731
class TeamPortSync : public Selectable
2832
{
2933
public:
@@ -54,12 +58,23 @@ class TeamSync : public NetMsg
5458
bool oper_state);
5559
void removeLag(const std::string &lagName);
5660

61+
/* valid only in WR mode */
62+
void applyState();
63+
64+
/* Handle all selectables add/removal events */
65+
void doSelectableTask();
66+
5767
private:
5868
Select *m_select;
5969
ProducerStateTable m_lagTable;
6070
ProducerStateTable m_lagMemberTable;
6171
Table m_stateLagTable;
6272

73+
bool m_warmstart;
74+
std::unordered_map<std::string, std::vector<FieldValueTuple>> m_stateLagTablePreserved;
75+
steady_clock::time_point m_start_time;
76+
uint32_t m_pending_timeout;
77+
6378
/* Store selectables needed to be updated in doSelectableTask function */
6479
std::set<std::string> m_selectablesToAdd;
6580
std::set<std::string> m_selectablesToRemove;

teamsyncd/teamsyncd.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ int main(int argc, char **argv)
3434
while (true)
3535
{
3636
Selectable *temps;
37-
s.select(&temps);
38-
39-
sync.doSelectableTask();
37+
s.select(&temps, 1000); // block for a second
38+
sync.periodic();
4039
}
4140
}
4241
catch (const std::exception& e)

0 commit comments

Comments
 (0)