Skip to content

Commit

Permalink
[intfmgrd] reach reconciled state at start when there are no interfac…
Browse files Browse the repository at this point in the history
…es configuration to process (sonic-net#1695)

* fix intfmgrd reconciliation when there are no interfaces in the system

Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
  • Loading branch information
volodymyrsamotiy authored Apr 7, 2021
1 parent 66e1aab commit 5c63670
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 10 deletions.
28 changes: 18 additions & 10 deletions cfgmgr/intfmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ IntfMgr::IntfMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
{
//Build the interface list to be replayed to Kernel
buildIntfReplayList();
if (m_pendingReplayIntfList.empty())
{
setWarmReplayDoneState();
}
}
}

Expand Down Expand Up @@ -191,16 +195,25 @@ void IntfMgr::buildIntfReplayList(void)

m_cfgLoopbackIntfTable.getKeys(intfList);
std::copy( intfList.begin(), intfList.end(), std::inserter( m_pendingReplayIntfList, m_pendingReplayIntfList.end() ) );

m_cfgVlanIntfTable.getKeys(intfList);
std::copy( intfList.begin(), intfList.end(), std::inserter( m_pendingReplayIntfList, m_pendingReplayIntfList.end() ) );

m_cfgLagIntfTable.getKeys(intfList);
std::copy( intfList.begin(), intfList.end(), std::inserter( m_pendingReplayIntfList, m_pendingReplayIntfList.end() ) );

SWSS_LOG_INFO("Found %d Total Intfs to be replayed", (int)m_pendingReplayIntfList.size() );
}

void IntfMgr::setWarmReplayDoneState()
{
m_replayDone = true;
WarmStart::setWarmStartState("intfmgrd", WarmStart::REPLAYED);
// There is no operation to be performed for intfmgr reconcillation
// Hence mark it reconciled right away
WarmStart::setWarmStartState("intfmgrd", WarmStart::RECONCILED);
}

bool IntfMgr::isIntfCreated(const string &alias)
{
vector<FieldValueTuple> temp;
Expand Down Expand Up @@ -705,7 +718,6 @@ bool IntfMgr::doIntfAddrTask(const vector<string>& keys,
void IntfMgr::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();
static bool replayDone = false;

string table_name = consumer.getTableName();

Expand Down Expand Up @@ -761,13 +773,9 @@ void IntfMgr::doTask(Consumer &consumer)

it = consumer.m_toSync.erase(it);
}
if (!replayDone && WarmStart::isWarmStart() && m_pendingReplayIntfList.empty() )

if (!m_replayDone && WarmStart::isWarmStart() && m_pendingReplayIntfList.empty() )
{
replayDone = true;
WarmStart::setWarmStartState("intfmgrd", WarmStart::REPLAYED);
// There is no operation to be performed for intfmgr reconcillation
// Hence mark it reconciled right away
WarmStart::setWarmStartState("intfmgrd", WarmStart::RECONCILED);
setWarmReplayDoneState();
}
}
3 changes: 3 additions & 0 deletions cfgmgr/intfmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class IntfMgr : public Orch
bool isIntfChangeVrf(const std::string &alias, const std::string &vrfName);
int getIntfIpCount(const std::string &alias);
void buildIntfReplayList(void);
void setWarmReplayDoneState();

void addLoopbackIntf(const std::string &alias);
void delLoopbackIntf(const std::string &alias);
Expand All @@ -53,6 +54,8 @@ class IntfMgr : public Orch

bool setIntfProxyArp(const std::string &alias, const std::string &proxy_arp);
bool setIntfGratArp(const std::string &alias, const std::string &grat_arp);

bool m_replayDone {false};
};

}
Expand Down
23 changes: 23 additions & 0 deletions tests/test_warm_reboot.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def swss_app_check_RestoreCount_single(state_db, restore_count, name):
assert int(fv[1]) == restore_count[key] + 1
elif fv[0] == "state":
assert fv[1] == "reconciled" or fv[1] == "disabled"
return status, fvs

def swss_app_check_warmstart_state(state_db, name, state):
warmtbl = swsscommon.Table(state_db, swsscommon.STATE_WARM_RESTART_TABLE_NAME)
Expand Down Expand Up @@ -445,6 +446,28 @@ def test_VlanMgrdWarmRestart(self, dvs, testlog):
intf_tbl._del("Vlan20")
time.sleep(2)

def test_IntfMgrdWarmRestartNoInterfaces(self, dvs, testlog):
""" Tests that intfmgrd reaches reconciled state when
there are no interfaces in configuration. """

state_db = swsscommon.DBConnector(swsscommon.STATE_DB, dvs.redis_sock, 0)
restore_count = swss_get_RestoreCount(dvs, state_db)

dvs.runcmd("config warm_restart enable swss")
dvs.runcmd("supervisorctl restart intfmgrd")

reached_desired_state = False
retries = 10
delay = 2
for _ in range(retries):
ok, fvs = swss_app_check_RestoreCount_single(state_db, restore_count, "intfmgrd")
if ok and dict(fvs)["state"] == "reconciled":
reached_desired_state = True
break
time.sleep(delay)

assert reached_desired_state, "intfmgrd haven't reached desired state 'reconciled', after {} sec it was {}".format(retries * delay, dict(fvs)["state"])

def test_swss_neighbor_syncup(self, dvs, testlog):

appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
Expand Down

0 comments on commit 5c63670

Please sign in to comment.