Skip to content

Commit

Permalink
[portsyncd] Remove the port_config.ini dependency from portsyncd (#1107)
Browse files Browse the repository at this point in the history
* Remove the port_config.ini dependency from portsyncd
portsyncd will rely on configDB port table, not from port_config.ini
port_config.ini is used when we convert minigraph to configDB, then
everything should come from configDB.
Also for the DPB feature, we are going to deprecate port_config.ini
* Modify the vs test cases
  • Loading branch information
zhenggen-xu authored and qiluo-msft committed Oct 27, 2019
1 parent 22402e5 commit 2a1ffe8
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 132 deletions.
111 changes: 7 additions & 104 deletions portsyncd/portsyncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ bool g_init = false;

void usage()
{
cout << "Usage: portsyncd [-p port_config.ini]" << endl;
cout << " -p port_config.ini: import port lane mapping" << endl;
cout << " use configDB data if not specified" << endl;
cout << "Usage: portsyncd" << endl;
cout << " port lane mapping is from configDB" << endl;
cout << " this program will exit if configDB does not contain that info" << endl;
}

void handlePortConfigFile(ProducerStateTable &p, string file, bool warm);
Expand All @@ -50,16 +50,12 @@ int main(int argc, char **argv)
{
Logger::linkToDbNative("portsyncd");
int opt;
string port_config_file;
map<string, KeyOpFieldsValuesTuple> port_cfg_map;

while ((opt = getopt(argc, argv, "p:v:h")) != -1 )
while ((opt = getopt(argc, argv, "v:h")) != -1 )
{
switch (opt)
{
case 'p':
port_config_file.assign(optarg);
break;
case 'h':
usage();
return 1;
Expand Down Expand Up @@ -91,11 +87,9 @@ int main(int argc, char **argv)
if (!handlePortConfigFromConfigDB(p, cfgDb, warm))
{
// if port config is missing in ConfigDB
// attempt to use port_config.ini
if (!port_config_file.empty())
{
handlePortConfigFile(p, port_config_file, warm);
}
// program will exit with failure
SWSS_LOG_THROW("ConfigDB does not have port information, exiting...");
return EXIT_FAILURE;
}

LinkSync sync(&appl_db, &state_db);
Expand Down Expand Up @@ -222,97 +216,6 @@ bool handlePortConfigFromConfigDB(ProducerStateTable &p, DBConnector &cfgDb, boo
return true;
}

void handlePortConfigFile(ProducerStateTable &p, string file, bool warm)
{
cout << "Read port configuration file..." << endl;

ifstream infile(file);
if (!infile.is_open())
{
usage();
throw runtime_error("Port configuration file not found!");
}

list<string> header = {"name", "lanes", "alias", "speed", "autoneg", "fec"};
string line;
while (getline(infile, line))
{
if (line.at(0) == '#')
{
// Take this line as column header line
istringstream iss_hdr(line.substr(1));
string hdr;

header.clear();
while (! iss_hdr.eof()) {
iss_hdr >> hdr;
cout << "Adding column header '" << hdr << "'" << endl;
header.push_back(hdr);
}

continue;
}

istringstream iss(line);
map<string, string> entry;

/* Read port configuration entry */
for (auto column : header)
{
iss >> entry[column];
}

if (!warm)
{
/* If port has no alias, then use its name as alias */
string alias;
if ((entry.find("alias") != entry.end()) && (entry["alias"] != ""))
{
alias = entry["alias"];
}
else
{
alias = entry["name"];
}

FieldValueTuple lanes_attr("lanes", entry["lanes"]);
FieldValueTuple alias_attr("alias", alias);

vector<FieldValueTuple> attrs;
attrs.push_back(lanes_attr);
attrs.push_back(alias_attr);

if ((entry.find("speed") != entry.end()) && (entry["speed"] != ""))
{
FieldValueTuple speed_attr("speed", entry["speed"]);
attrs.push_back(speed_attr);
}

if ((entry.find("autoneg") != entry.end()) && (entry["autoneg"] != ""))
{
FieldValueTuple autoneg_attr("autoneg", entry["autoneg"]);
attrs.push_back(autoneg_attr);
}

if ((entry.find("fec") != entry.end()) && (entry["fec"] != ""))
{
FieldValueTuple fec_attr("fec", entry["fec"]);
attrs.push_back(fec_attr);
}

p.set(entry["name"], attrs);
}

g_portSet.insert(entry["name"]);
}

infile.close();
if (!warm)
{
notifyPortConfigDone(p);
}
}

void handlePortConfig(ProducerStateTable &p, map<string, KeyOpFieldsValuesTuple> &port_cfg_map)
{

Expand Down
101 changes: 73 additions & 28 deletions tests/test_port_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,44 +55,89 @@ def test_port_hw_lane(self, dvs):

def test_port_breakout(self, dvs, port_config):

# check port_config.ini
(exitcode, output) = dvs.runcmd(['sh', '-c', "cat %s | tail -n 1" % (port_config)])
try:
name_str, lanes_str, alias_str, index_str, speed_str = list(output.split())
except:
print "parse port_config.ini fail"

LANES_L = list(lanes_str.split(","))
assert len(LANES_L) == 4
assert int(speed_str) == 40000

# modify port_config.ini
eth = int(name_str.replace("Ethernet", ""))
index = int(index_str)
speed_str = "tenGigE0"
speed = 10000
dvs.runcmd("sed -i '$d' %s" % (port_config)) == 0
for i in range(0,4):
dvs.runcmd("sed -i '$a Ethernet%-7d %-17d %s/%-8d %-11d %d' %s" %
(eth+i, int(LANES_L[i]), speed_str, eth+i, index+i, speed, port_config)) == 0

# delete port config
# Breakout the port from 1 to 4
'''
"Ethernet0": {
"alias": "fortyGigE0/0",
"index": "0",
"lanes": "25,26,27,28",
"speed": "40000"
},
to:
"Ethernet0": {
"alias": "tenGigE0",
"index": "0",
"lanes": "25",
"speed": "10000"
},
"Ethernet1": {
"alias": "tenGigE1",
"index": "0",
"lanes": "26",
"speed": "10000"
},
"Ethernet2": {
"alias": "tenGigE2",
"index": "0",
"lanes": "27",
"speed": "10000"
},
"Ethernet3": {
"alias": "tenGigE3",
"index": "0",
"lanes": "28",
"speed": "10000"
},
'''
# Get port config from configDB
conf_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, dvs.redis_sock, 0)
portTbl = swsscommon.Table(conf_db, swsscommon.CFG_PORT_TABLE_NAME)

chg_port = "Ethernet0"

keys = portTbl.getKeys()
assert len(keys) > 0
for key in keys:
portTbl._del(key)
assert chg_port in keys

(status, fvs) = portTbl.get(chg_port)
assert(status == True)

for fv in fvs:
if fv[0] == "index":
new_index = fv[1]
if fv[0] == "lanes":
new_lanes = fv[1].split(",")

# restart to apply new port_config.ini
# Stop swss before modifing the configDB
dvs.stop_swss()
time.sleep(1)

# breakout the port in configDB
portTbl._del(chg_port)

new_ports = ["Ethernet0","Ethernet1","Ethernet2","Ethernet3"]
new_speed = "10000"
new_alias = ["tenGigE0", "tenGigE1", "tenGigE2", "tenGigE3"]

for i in range (0 ,4):
fvs = swsscommon.FieldValuePairs([("alias", new_alias[i]),
("lanes", new_lanes[i]),
("speed", new_speed),
("index", new_index)])

portTbl.set(new_ports[i], fvs)

# start to apply new port_config.ini
dvs.start_swss()
time.sleep(5)

asic_db = swsscommon.DBConnector(swsscommon.ASIC_DB, dvs.redis_sock, 0)

for i in range(0,4):
port_name = 'Ethernet{0}'.format(eth+i)
port_name = 'Ethernet{0}'.format(i)
port_oid = self.getPortOid(dvs, port_name)
port_tbl = swsscommon.Table(asic_db, 'ASIC_STATE:SAI_OBJECT_TYPE_PORT:{0}'.format(port_oid))
hw_lane_value = None
Expand All @@ -102,6 +147,6 @@ def test_port_breakout(self, dvs, port_config):
hw_lane_value = k[1]

assert hw_lane_value, "Can't get hw_lane list"
assert hw_lane_value == "1:%s" % (LANES_L[i])
assert hw_lane_value == "1:%s" % (new_lanes[i])


0 comments on commit 2a1ffe8

Please sign in to comment.