Skip to content

Commit

Permalink
Add support for fabric monitor daemon (swss part). (sonic-net#2920)
Browse files Browse the repository at this point in the history
* Add support for fabric monitor daemon (swss part).
  • Loading branch information
jfeng-arista committed Dec 2, 2023
1 parent 8dc0a85 commit d839eec
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 1 deletion.
9 changes: 8 additions & 1 deletion cfgmgr/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LIBNL_LIBS = -lnl-genl-3 -lnl-route-3 -lnl-3
SAIMETA_LIBS = -lsaimeta -lsaimetadata -lzmq
COMMON_LIBS = -lswsscommon

bin_PROGRAMS = vlanmgrd teammgrd portmgrd intfmgrd buffermgrd vrfmgrd nbrmgrd vxlanmgrd sflowmgrd natmgrd coppmgrd tunnelmgrd macsecmgrd
bin_PROGRAMS = vlanmgrd teammgrd portmgrd intfmgrd buffermgrd vrfmgrd nbrmgrd vxlanmgrd sflowmgrd natmgrd coppmgrd tunnelmgrd macsecmgrd fabricmgrd

cfgmgrdir = $(datadir)/swss

Expand Down Expand Up @@ -46,6 +46,11 @@ portmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLA
portmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLAGS_ASAN)
portmgrd_LDADD = $(LDFLAGS_ASAN) $(COMMON_LIBS) $(SAIMETA_LIBS)

fabricmgrd_SOURCES = fabricmgrd.cpp fabricmgr.cpp $(COMMON_ORCH_SOURCE) shellcmd.h
fabricmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLAGS_ASAN)
fabricmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLAGS_ASAN)
fabricmgrd_LDADD = $(LDFLAGS_ASAN) $(COMMON_LIBS) $(SAIMETA_LIBS)

intfmgrd_SOURCES = intfmgrd.cpp intfmgr.cpp $(top_srcdir)/lib/subintf.cpp $(COMMON_ORCH_SOURCE) shellcmd.h
intfmgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLAGS_ASAN)
intfmgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLAGS_ASAN)
Expand Down Expand Up @@ -110,6 +115,7 @@ natmgrd_LDADD += -lgcovpreload
coppmgrd_LDADD += -lgcovpreload
tunnelmgrd_LDADD += -lgcovpreload
macsecmgrd_LDADD += -lgcovpreload
fabricmgrd_LDADD += -lgcovpreload
endif

if ASAN_ENABLED
Expand All @@ -126,5 +132,6 @@ natmgrd_SOURCES += $(top_srcdir)/lib/asan.cpp
coppmgrd_SOURCES += $(top_srcdir)/lib/asan.cpp
tunnelmgrd_SOURCES += $(top_srcdir)/lib/asan.cpp
macsecmgrd_SOURCES += $(top_srcdir)/lib/asan.cpp
fabricmgrd_SOURCES += $(top_srcdir)/lib/asan.cpp
endif

119 changes: 119 additions & 0 deletions cfgmgr/fabricmgr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include "logger.h"
#include "dbconnector.h"
#include "producerstatetable.h"
#include "tokenize.h"
#include "ipprefix.h"
#include "fabricmgr.h"
#include "exec.h"
#include "shellcmd.h"
#include <swss/redisutility.h>

using namespace std;
using namespace swss;

FabricMgr::FabricMgr(DBConnector *cfgDb, DBConnector *appDb, const vector<string> &tableNames) :
Orch(cfgDb, tableNames),
m_cfgFabricMonitorTable(cfgDb, CFG_FABRIC_MONITOR_DATA_TABLE_NAME),
m_cfgFabricPortTable(cfgDb, CFG_FABRIC_MONITOR_PORT_TABLE_NAME),
m_appFabricMonitorTable(appDb, APP_FABRIC_MONITOR_DATA_TABLE_NAME),
m_appFabricPortTable(appDb, APP_FABRIC_MONITOR_PORT_TABLE_NAME)
{
}

void FabricMgr::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();

auto table = consumer.getTableName();

auto it = consumer.m_toSync.begin();
while (it != consumer.m_toSync.end())
{
KeyOpFieldsValuesTuple t = it->second;

string key = kfvKey(t);
string op = kfvOp(t);

if (op == SET_COMMAND)
{

string monErrThreshCrcCells, monErrThreshRxCells;
string monPollThreshRecovery, monPollThreshIsolation;
string isolateStatus;
string alias, lanes;
std::vector<FieldValueTuple> field_values;
string value;

for (auto i : kfvFieldsValues(t))
{
if (fvField(i) == "monErrThreshCrcCells")
{
monErrThreshCrcCells = fvValue(i);
writeConfigToAppDb(key, "monErrThreshCrcCells", monErrThreshCrcCells);
}
else if (fvField(i) == "monErrThreshRxCells")
{
monErrThreshRxCells = fvValue(i);
writeConfigToAppDb(key, "monErrThreshRxCells", monErrThreshRxCells);
}
else if (fvField(i) == "monPollThreshRecovery")
{
monPollThreshRecovery = fvValue(i);
writeConfigToAppDb(key, "monPollThreshRecovery", monPollThreshRecovery);
}
else if (fvField(i) == "monPollThreshIsolation")
{
monPollThreshIsolation = fvValue(i);
writeConfigToAppDb(key, "monPollThreshIsolation", monPollThreshIsolation);
}
else if (fvField(i) == "alias")
{
alias = fvValue(i);
writeConfigToAppDb(key, "alias", alias);
}
else if (fvField(i) == "lanes")
{
lanes = fvValue(i);
writeConfigToAppDb(key, "lanes", lanes);
}
else if (fvField(i) == "isolateStatus")
{
isolateStatus = fvValue(i);
writeConfigToAppDb(key, "isolateStatus", isolateStatus);
}
else
{
field_values.emplace_back(i);
}
}

for (auto &entry : field_values)
{
writeConfigToAppDb(key, fvField(entry), fvValue(entry));
}

}
it = consumer.m_toSync.erase(it);
}
}

bool FabricMgr::writeConfigToAppDb(const std::string &key, const std::string &field, const std::string &value)
{
vector<FieldValueTuple> fvs;
FieldValueTuple fv(field, value);
fvs.push_back(fv);
if (key == "FABRIC_MONITOR_DATA")
{
m_appFabricMonitorTable.set(key, fvs);
SWSS_LOG_NOTICE("Write FABRIC_MONITOR:%s %s to %s", key.c_str(), field.c_str(), value.c_str());
}
else
{
m_appFabricPortTable.set(key, fvs);
SWSS_LOG_NOTICE("Write FABRIC_PORT:%s %s to %s", key.c_str(), field.c_str(), value.c_str());
}

return true;
}


30 changes: 30 additions & 0 deletions cfgmgr/fabricmgr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include "dbconnector.h"
#include "orch.h"
#include "producerstatetable.h"

#include <map>
#include <set>
#include <string>

namespace swss {


class FabricMgr : public Orch
{
public:
FabricMgr(DBConnector *cfgDb, DBConnector *appDb, const std::vector<std::string> &tableNames);

using Orch::doTask;
private:
Table m_cfgFabricMonitorTable;
Table m_cfgFabricPortTable;
Table m_appFabricMonitorTable;
Table m_appFabricPortTable;

void doTask(Consumer &consumer);
bool writeConfigToAppDb(const std::string &alias, const std::string &field, const std::string &value);
};

}
73 changes: 73 additions & 0 deletions cfgmgr/fabricmgrd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <fstream>
#include <iostream>
#include <mutex>
#include <unistd.h>
#include <vector>

#include "exec.h"
#include "fabricmgr.h"
#include "schema.h"
#include "select.h"

using namespace std;
using namespace swss;

/* select() function timeout retry time, in millisecond */
#define SELECT_TIMEOUT 1000

int main(int argc, char **argv)
{
Logger::linkToDbNative("fabricmgrd");
SWSS_LOG_ENTER();

SWSS_LOG_NOTICE("--- Starting fabricmgrd ---");

try
{
vector<string> cfg_fabric_tables = {
CFG_FABRIC_MONITOR_DATA_TABLE_NAME,
CFG_FABRIC_MONITOR_PORT_TABLE_NAME,
};

DBConnector cfgDb("CONFIG_DB", 0);
DBConnector appDb("APPL_DB", 0);

FabricMgr fabricmgr(&cfgDb, &appDb, cfg_fabric_tables);

// TODO: add tables in stateDB which interface depends on to monitor list
vector<Orch *> cfgOrchList = {&fabricmgr};

swss::Select s;
for (Orch *o : cfgOrchList)
{
s.addSelectables(o->getSelectables());
}

while (true)
{
Selectable *sel;
int ret;

ret = s.select(&sel, SELECT_TIMEOUT);
if (ret == Select::ERROR)
{
SWSS_LOG_NOTICE("Error: %s!", strerror(errno));
continue;
}
if (ret == Select::TIMEOUT)
{
fabricmgr.doTask();
continue;
}

auto *c = (Executor *)sel;
c->execute();
}
}
catch (const exception &e)
{
SWSS_LOG_ERROR("Runtime error: %s", e.what());
}
return -1;
}

48 changes: 48 additions & 0 deletions tests/test_fabric_port.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from swsscommon import swsscommon
from dvslib.dvs_database import DVSDatabase


class TestVirtualChassis(object):
def test_voq_switch_fabric_link(self, vst):
"""Test fabric link manual isolation commands in VOQ switch.
By issuing config fabric port isolation command, the value
of isolateStatus field in config_db get changed. This test validates appl_db
updates of a fabric link isolateStatus as the value in config_db changed.
"""

dvss = vst.dvss
for name in dvss.keys():
dvs = dvss[name]
# Get the config info
config_db = dvs.get_config_db()
metatbl = config_db.get_entry("DEVICE_METADATA", "localhost")

cfg_switch_type = metatbl.get("switch_type")
if cfg_switch_type == "fabric":

# get config_db information
cdb = dvs.get_config_db()

# set config_db to isolateStatus: True
cdb.update_entry("FABRIC_PORT", "Fabric1", {"isolateStatus": "True"})
cdb.wait_for_field_match("FABRIC_PORT", "Fabric1", {"isolateStatus": "True"})

# check if appl_db value changes to isolateStatus: True
adb = dvs.get_app_db()
adb.wait_for_field_match("FABRIC_PORT_TABLE", "Fabric1", {"isolateStatus": "True"})

# cleanup
cdb.update_entry("FABRIC_PORT", "Fabric1", {"isolateStatus": "False"})
cdb.wait_for_field_match("FABRIC_PORT", "Fabric1", {"isolateStatus": "False"})
adb.wait_for_field_match("FABRIC_PORT_TABLE", "Fabric1", {"isolateStatus": "False"})
else:
print( "We do not check switch type:", cfg_switch_type )


# Add Dummy always-pass test at end as workaroud
# for issue when Flaky fail on final test it invokes module tear-down before retrying
def test_nonflaky_dummy():
pass


0 comments on commit d839eec

Please sign in to comment.