Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions portsyncd/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
INCLUDES = -I $(top_srcdir)
INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/warmrestart

bin_PROGRAMS = portsyncd

Expand All @@ -8,7 +8,7 @@ else
DBGFLAGS = -g
endif

portsyncd_SOURCES = portsyncd.cpp linksync.cpp
portsyncd_SOURCES = portsyncd.cpp linksync.cpp $(top_srcdir)/warmrestart/warm_restart.cpp $(top_srcdir)/warmrestart/warm_restart.h

portsyncd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON)
portsyncd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON)
Expand Down
72 changes: 38 additions & 34 deletions portsyncd/linksync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "linkcache.h"
#include "portsyncd/linksync.h"
#include "warm_restart.h"

#include <iostream>
#include <set>
Expand Down Expand Up @@ -41,52 +42,55 @@ LinkSync::LinkSync(DBConnector *appl_db, DBConnector *state_db) :
m_portTable(appl_db, APP_PORT_TABLE_NAME),
m_statePortTable(state_db, STATE_PORT_TABLE_NAME)
{
/* See the comments for g_portSet in portsyncd.cpp */
for (string port : g_portSet)
if (!WarmStart::isWarmStart())
{
vector<FieldValueTuple> temp;
if (m_portTable.get(port, temp))
/* See the comments for g_portSet in portsyncd.cpp */
for (string port : g_portSet)
{
for (auto it : temp)
vector<FieldValueTuple> temp;
if (m_portTable.get(port, temp))
{
if (fvField(it) == "admin_status")
for (auto it : temp)
{
g_portSet.erase(port);
break;
if (fvField(it) == "admin_status")
{
g_portSet.erase(port);
break;
}
}
}
}
}

struct if_nameindex *if_ni, *idx_p;
if_ni = if_nameindex();
if (if_ni == NULL)
{
return;
}

for (idx_p = if_ni; ! (idx_p->if_index == 0 && idx_p->if_name == NULL); idx_p++)
{
string key = idx_p->if_name;
if (key.compare(0, INTFS_PREFIX.length(), INTFS_PREFIX))
struct if_nameindex *if_ni, *idx_p;
if_ni = if_nameindex();
if (if_ni == NULL)
{
continue;
return;
}

m_ifindexOldNameMap[idx_p->if_index] = key;

/* Bring down the existing kernel interfaces */
string cmd, res;
SWSS_LOG_INFO("Bring down old interface %s(%d)", key.c_str(), idx_p->if_index);
cmd = "ip link set " + key + " down";
try
{
swss::exec(cmd, res);
}
catch (...)
for (idx_p = if_ni; ! (idx_p->if_index == 0 && idx_p->if_name == NULL); idx_p++)
{
/* Ignore error in this flow ; */
SWSS_LOG_WARN("Failed to bring down old interface %s(%d)", key.c_str(), idx_p->if_index);
string key = idx_p->if_name;
if (key.compare(0, INTFS_PREFIX.length(), INTFS_PREFIX))
{
continue;
}

m_ifindexOldNameMap[idx_p->if_index] = key;

/* Bring down the existing kernel interfaces */
string cmd, res;
SWSS_LOG_INFO("Bring down old interface %s(%d)", key.c_str(), idx_p->if_index);
cmd = "ip link set " + key + " down";
try
{
swss::exec(cmd, res);
}
catch (...)
{
/* Ignore error in this flow ; */
SWSS_LOG_WARN("Failed to bring down old interface %s(%d)", key.c_str(), idx_p->if_index);
}
}
}
}
Expand Down
25 changes: 21 additions & 4 deletions portsyncd/portsyncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <set>
#include <map>
#include <list>
#include <sys/stat.h>
#include "dbconnector.h"
#include "select.h"
#include "netdispatcher.h"
Expand All @@ -14,6 +15,7 @@
#include "portsyncd/linksync.h"
#include "subscriberstatetable.h"
#include "exec.h"
#include "warm_restart.h"

using namespace std;
using namespace swss;
Expand Down Expand Up @@ -42,6 +44,7 @@ void handlePortConfigFile(ProducerStateTable &p, string file);
void handlePortConfigFromConfigDB(ProducerStateTable &p, DBConnector &cfgDb);
void handleVlanIntfFile(string file);
void handlePortConfig(ProducerStateTable &p, map<string, KeyOpFieldsValuesTuple> &port_cfg_map);
void checkPortInitDone(DBConnector *appl_db);

int main(int argc, char **argv)
{
Expand Down Expand Up @@ -72,6 +75,15 @@ int main(int argc, char **argv)
ProducerStateTable p(&appl_db, APP_PORT_TABLE_NAME);
SubscriberStateTable portCfg(&cfgDb, CFG_PORT_TABLE_NAME);

WarmStart::checkWarmStart("portsyncd");
if (WarmStart::isWarmStart())
{
/* clear the init port config buffer */
cout << "portsyncd warm start" << endl;
deque<KeyOpFieldsValuesTuple> vkco;
portCfg.pops(vkco);
}

LinkSync sync(&appl_db, &state_db);
NetDispatcher::getInstance().registerMessageHandler(RTM_NEWLINK, &sync);
NetDispatcher::getInstance().registerMessageHandler(RTM_DELLINK, &sync);
Expand All @@ -84,15 +96,20 @@ int main(int argc, char **argv)
netlink.registerGroup(RTNLGRP_LINK);
cout << "Listen to link messages..." << endl;

if (!port_config_file.empty())
/* For portsyncd warm start, don't process init port config again */
if (!WarmStart::isWarmStart())
{
handlePortConfigFile(p, port_config_file);
} else {
handlePortConfigFromConfigDB(p, cfgDb);
if (!port_config_file.empty())
{
handlePortConfigFile(p, port_config_file);
} else {
handlePortConfigFromConfigDB(p, cfgDb);
}
}

s.addSelectable(&netlink);
s.addSelectable(&portCfg);

while (true)
{
Selectable *temps;
Expand Down
89 changes: 89 additions & 0 deletions tests/test_warm_reboot.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,95 @@ def how_many_entries_exist(db, table):
return len(tbl.getKeys())


def test_PortSyncdWarmRestart(dvs):

conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0)
appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, dvs.redis_sock, 0)
state_db = swsscommon.DBConnector(swsscommon.STATE_DB, dvs.redis_sock, 0)

# enable warm restart
# TODO: use cfg command to config it
create_entry_tbl(
conf_db,
swsscommon.CFG_WARM_RESTART_TABLE_NAME, "swss",
[
("enable", "true"),
]
)

dvs.runcmd("ifconfig Ethernet16 up")
dvs.runcmd("ifconfig Ethernet20 up")

time.sleep(1)

dvs.runcmd("ifconfig Ethernet16 11.0.0.1/29 up")
dvs.runcmd("ifconfig Ethernet20 11.0.0.9/29 up")

dvs.servers[4].runcmd("ip link set down dev eth0") == 0
dvs.servers[4].runcmd("ip link set up dev eth0") == 0
dvs.servers[4].runcmd("ifconfig eth0 11.0.0.2/29")
dvs.servers[4].runcmd("ip route add default via 11.0.0.1")

dvs.servers[5].runcmd("ip link set down dev eth0") == 0
dvs.servers[5].runcmd("ip link set up dev eth0") == 0
dvs.servers[5].runcmd("ifconfig eth0 11.0.0.10/29")
dvs.servers[5].runcmd("ip route add default via 11.0.0.9")

time.sleep(1)

# Ethernet port oper status should be up
check_port_oper_status(appl_db, "Ethernet16", "up")
check_port_oper_status(appl_db, "Ethernet20", "up")

# Ping should work between servers via vs vlan interfaces
ping_stats = dvs.servers[4].runcmd("ping -c 1 11.0.0.10")
time.sleep(1)

neighTbl = swsscommon.Table(appl_db, "NEIGH_TABLE")
(status, fvs) = neighTbl.get("Ethernet16:11.0.0.2")
assert status == True

(status, fvs) = neighTbl.get("Ethernet20:11.0.0.10")
assert status == True

restart_count = swss_get_RestartCount(state_db)

# restart portsyncd
dvs.runcmd(['sh', '-c', 'pkill -x portsyncd; cp /var/log/swss/sairedis.rec /var/log/swss/sairedis.rec.b; echo > /var/log/swss/sairedis.rec'])
dvs.runcmd(['sh', '-c', 'supervisorctl start portsyncd'])
time.sleep(2)

# No create/set/remove operations should be passed down to syncd for portsyncd warm restart
num = dvs.runcmd(['sh', '-c', 'grep \|c\| /var/log/swss/sairedis.rec | wc -l'])
assert num == '0\n'
num = dvs.runcmd(['sh', '-c', 'grep \|s\| /var/log/swss/sairedis.rec | wc -l'])
assert num == '0\n'
num = dvs.runcmd(['sh', '-c', 'grep \|r\| /var/log/swss/sairedis.rec | wc -l'])
assert num == '0\n'

#new ip on server 5
dvs.servers[5].runcmd("ifconfig eth0 11.0.0.11/29")

# Ping should work between servers via vs Ethernet interfaces
ping_stats = dvs.servers[4].runcmd("ping -c 1 11.0.0.11")

# new neighbor learn on VS
(status, fvs) = neighTbl.get("Ethernet20:11.0.0.11")
assert status == True

# Port state change reflected in appDB correctly
dvs.servers[6].runcmd("ip link set down dev eth0") == 0
dvs.servers[6].runcmd("ip link set up dev eth0") == 0
time.sleep(1)

check_port_oper_status(appl_db, "Ethernet16", "up")
check_port_oper_status(appl_db, "Ethernet20", "up")
check_port_oper_status(appl_db, "Ethernet24", "up")


swss_app_check_RestartCount_single(state_db, restart_count, "portsyncd")


def test_VlanMgrdWarmRestart(dvs):

conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0)
Expand Down