Skip to content

Commit

Permalink
[WR]: Add reconciliation logic for teamsyncd (sonic-net#725)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
pavel-shirshov authored and qiluo-msft committed Dec 23, 2018
1 parent 5803a8c commit 025268a
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 8 deletions.
7 changes: 7 additions & 0 deletions doc/swss-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,13 @@ Stores information for physical switch ports managed by the switch chip. Ports t
; the elected routing-stack.
; Supported range: 1-3600.

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


### VXLAN\_TUNNEL
Stores vxlan tunnels configuration
Expand Down
67 changes: 65 additions & 2 deletions teamsyncd/teamsync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
#include <sys/socket.h>
#include <linux/if.h>
#include <netlink/route/link.h>
#include <chrono>
#include "logger.h"
#include "netmsg.h"
#include "dbconnector.h"
#include "producerstatetable.h"
#include "warm_restart.h"
#include "teamsync.h"

using namespace std;
using namespace std::chrono;
using namespace swss;

/* Taken from drivers/net/team/team.c */
Expand All @@ -22,6 +25,34 @@ TeamSync::TeamSync(DBConnector *db, DBConnector *stateDb, Select *select) :
m_lagMemberTable(db, APP_LAG_MEMBER_TABLE_NAME),
m_stateLagTable(stateDb, STATE_LAG_TABLE_NAME)
{
WarmStart::initialize("teamsyncd", "teamd");
WarmStart::checkWarmStart("teamsyncd", "teamd");
m_warmstart = WarmStart::isWarmStart();

if (m_warmstart)
{
m_start_time = steady_clock::now();
auto warmRestartIval = WarmStart::getWarmStartTimer("teamsyncd", "teamd");
m_pending_timeout = warmRestartIval ? warmRestartIval : DEFAULT_WR_PENDING_TIMEOUT;
m_lagTable.create_temp_view();
m_lagMemberTable.create_temp_view();
SWSS_LOG_NOTICE("Starting in warmstart mode");
}
}

void TeamSync::periodic()
{
if (m_warmstart)
{
auto diff = duration_cast<seconds>(steady_clock::now() - m_start_time);
if(diff.count() > m_pending_timeout)
{
applyState();
m_warmstart = false; // apply state just once
}
}

doSelectableTask();
}

void TeamSync::doSelectableTask()
Expand All @@ -44,6 +75,23 @@ void TeamSync::doSelectableTask()
m_selectablesToRemove.clear();
}

void TeamSync::applyState()
{
SWSS_LOG_NOTICE("Applying state");

m_lagTable.apply_temp_view();
m_lagMemberTable.apply_temp_view();

for(auto &it: m_stateLagTablePreserved)
{
const auto &lagName = it.first;
const auto &fvVector = it.second;
m_stateLagTable.set(lagName, fvVector);
}

m_stateLagTablePreserved.clear();
}

void TeamSync::onMsg(int nlmsg_type, struct nl_object *obj)
{
struct rtnl_link *link = (struct rtnl_link *)obj;
Expand Down Expand Up @@ -90,7 +138,14 @@ void TeamSync::addLag(const string &lagName, int ifindex, bool admin_state,
fvVector.clear();
FieldValueTuple s("state", "ok");
fvVector.push_back(s);
m_stateLagTable.set(lagName, fvVector);
if (m_warmstart)
{
m_stateLagTablePreserved[lagName] = fvVector;
}
else
{
m_stateLagTable.set(lagName, fvVector);
}

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

m_stateLagTable.del(lagName);
if (m_warmstart)
{
m_stateLagTablePreserved.erase(lagName);
}
else
{
m_stateLagTable.del(lagName);
}

m_selectablesToRemove.insert(lagName);
}

Expand Down
21 changes: 18 additions & 3 deletions teamsyncd/teamsync.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,23 @@
#include "netmsg.h"
#include <team.h>

// seconds
const uint32_t DEFAULT_WR_PENDING_TIMEOUT = 70;

using namespace std::chrono;

namespace swss {

class TeamSync : public NetMsg
{
public:
TeamSync(DBConnector *db, DBConnector *stateDb, Select *select);

void periodic();

/* Listen to RTM_NEWLINK, RTM_DELLINK to track team devices */
virtual void onMsg(int nlmsg_type, struct nl_object *obj);

/* Handle all selectables add/removal events */
void doSelectableTask();

class TeamPortSync : public Selectable
{
public:
Expand Down Expand Up @@ -54,12 +58,23 @@ class TeamSync : public NetMsg
bool oper_state);
void removeLag(const std::string &lagName);

/* valid only in WR mode */
void applyState();

/* Handle all selectables add/removal events */
void doSelectableTask();

private:
Select *m_select;
ProducerStateTable m_lagTable;
ProducerStateTable m_lagMemberTable;
Table m_stateLagTable;

bool m_warmstart;
std::unordered_map<std::string, std::vector<FieldValueTuple>> m_stateLagTablePreserved;
steady_clock::time_point m_start_time;
uint32_t m_pending_timeout;

/* Store selectables needed to be updated in doSelectableTask function */
std::set<std::string> m_selectablesToAdd;
std::set<std::string> m_selectablesToRemove;
Expand Down
5 changes: 2 additions & 3 deletions teamsyncd/teamsyncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ int main(int argc, char **argv)
while (true)
{
Selectable *temps;
s.select(&temps);

sync.doSelectableTask();
s.select(&temps, 1000); // block for a second
sync.periodic();
}
}
catch (const std::exception& e)
Expand Down

0 comments on commit 025268a

Please sign in to comment.