diff --git a/cfgmgr/intfmgr.cpp b/cfgmgr/intfmgr.cpp index 24516fff1a65..a5bc092df9ba 100644 --- a/cfgmgr/intfmgr.cpp +++ b/cfgmgr/intfmgr.cpp @@ -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(); + } } } @@ -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 temp; @@ -705,7 +718,6 @@ bool IntfMgr::doIntfAddrTask(const vector& keys, void IntfMgr::doTask(Consumer &consumer) { SWSS_LOG_ENTER(); - static bool replayDone = false; string table_name = consumer.getTableName(); @@ -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(); } } diff --git a/cfgmgr/intfmgr.h b/cfgmgr/intfmgr.h index 35d62a424d0e..e72a10be969b 100644 --- a/cfgmgr/intfmgr.h +++ b/cfgmgr/intfmgr.h @@ -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); @@ -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}; }; } diff --git a/tests/test_warm_reboot.py b/tests/test_warm_reboot.py index 84f2e57b8753..c7d6f5a67315 100644 --- a/tests/test_warm_reboot.py +++ b/tests/test_warm_reboot.py @@ -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) @@ -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)