Skip to content

Commit

Permalink
Error Handling Framework changes
Browse files Browse the repository at this point in the history
  • Loading branch information
sivamukka committed Oct 18, 2019
1 parent aaa8133 commit d07b893
Show file tree
Hide file tree
Showing 7 changed files with 325 additions and 2 deletions.
4 changes: 3 additions & 1 deletion common/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ libswsscommon_la_SOURCES = \
exec.cpp \
subscriberstatetable.cpp \
timestamp.cpp \
warm_restart.cpp
warm_restart.cpp \
errormap.cpp \
errorlistener.cpp

libswsscommon_la_CXXFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(LIBNL_CFLAGS)
libswsscommon_la_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(LIBNL_CPPFLAGS)
Expand Down
82 changes: 82 additions & 0 deletions common/errorlistener.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2019 Broadcom Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <vector>
#include "errorlistener.h"
#include "common/json.h"
#include "common/json.hpp"
using json = nlohmann::json;

namespace swss {

/* Creates an error listener object that listens for h/w errors on table entries
* in the APP_DB table that the caller is intereted in. */

ErrorListener::ErrorListener(std::string appTableName, int errFlags)
{
SWSS_LOG_ENTER();

m_errorFlags = errFlags;
m_errorChannelName = getErrorChannelName(appTableName);
m_errorNotificationsDb = new DBConnector(ERROR_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
m_errorNotificationConsumer = new swss::NotificationConsumer(m_errorNotificationsDb,
m_errorChannelName);
}

ErrorListener::~ErrorListener()
{
SWSS_LOG_ENTER();
delete m_errorNotificationConsumer;
delete m_errorNotificationsDb;
}

/* Returns the Error notification corresponding to an entry in the APP_DB.
* Owner of the error listener object calls this function whenever there is
* a select event on the error listerner.
* 0 is returned if a failure or postive ack of interest is read successfully.
* -1 is returned if there are no errors of interest to the caller. */
int ErrorListener::getError(std::string &key, std::string &opCode,
std::vector<swss::FieldValueTuple> &attrs)
{
std::string op, data;
std::vector<swss::FieldValueTuple> values;

SWSS_LOG_ENTER();

m_errorNotificationConsumer->pop(op, data, values);
SWSS_LOG_DEBUG("ErrorListener op: %s data: %s", op.c_str(), data.c_str());

json j = json::parse(data);

// Filter the error notifications that the caller is not interested in.
if (!(((m_errorFlags & ERR_NOTIFY_POSITIVE_ACK) && (j["rc"] == "SWSS_RC_SUCCESS")) ||
((m_errorFlags & ERR_NOTIFY_FAIL) && (j["rc"] != "SWSS_RC_SUCCESS"))))
{
return -1;
}

key = j["key"];
opCode = j["operation"];
for (json::iterator it = j.begin(); it != j.end(); ++it)
{
if(it.key() != "key" && it.key() != "operation")
{
attrs.emplace_back(it.key(), it.value());
}
}
return 0;
}
}
64 changes: 64 additions & 0 deletions common/errorlistener.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2019 Broadcom Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef SWSS_ERRORLISTENER_H
#define SWSS_ERRORLISTENER_H

#include "notificationconsumer.h"
#include "selectable.h"
#include "table.h"
#include <dbconnector.h>

// Error notifications of interest to the error listener
typedef enum
{
ERR_NOTIFY_FAIL = 1,
ERR_NOTIFY_POSITIVE_ACK
} error_notify_flags_t;

namespace swss {

class ErrorListener : public Selectable
{
public:
ErrorListener(std::string appTableName, int errFlags);
~ErrorListener();

static std::string getErrorChannelName(std::string& appTableName)
{
std::string errorChnl = "ERROR_";
errorChnl += appTableName + "_CHANNEL";

return errorChnl;
}

int getFd() { return m_errorNotificationConsumer->getFd(); }
uint64_t readData() { return m_errorNotificationConsumer->readData(); }
bool hasData() { return m_errorNotificationConsumer->hasData(); }
bool hasCachedData() override { return m_errorNotificationConsumer->hasCachedData(); }
bool initializedWithData() override { return m_errorNotificationConsumer->initializedWithData(); }
void updateAfterRead() override { m_errorNotificationConsumer->updateAfterRead(); }
int getError(std::string &key, std::string &opCode, std::vector<swss::FieldValueTuple> &attrs);

private:
swss::NotificationConsumer *m_errorNotificationConsumer;
DBConnector *m_errorNotificationsDb;
int m_errorFlags;
std::string m_errorChannelName;
};

}
#endif /* SWSS_ERRORLISTENER_H */
105 changes: 105 additions & 0 deletions common/errormap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2019 Broadcom Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "error.h"
#include "logger.h"
#include "errormap.h"

namespace swss {

ErrorMap::~ErrorMap() { }

const ErrorMap::SwssStrToRCMap ErrorMap::m_swssStrToRC = {
{ std::make_pair("SWSS_RC_SUCCESS", SWSS_RC_SUCCESS) },
{ std::make_pair("SWSS_RC_INVALID_PARAM", SWSS_RC_INVALID_PARAM) },
{ std::make_pair("SWSS_RC_UNAVAIL", SWSS_RC_UNAVAIL) },
{ std::make_pair("SWSS_RC_NOT_FOUND", SWSS_RC_NOT_FOUND) },
{ std::make_pair("SWSS_RC_NO_MEMORY", SWSS_RC_NO_MEMORY) },
{ std::make_pair("SWSS_RC_EXISTS", SWSS_RC_EXISTS) },
{ std::make_pair("SWSS_RC_TABLE_FULL", SWSS_RC_TABLE_FULL) },
{ std::make_pair("SWSS_RC_IN_USE", SWSS_RC_IN_USE) },
{ std::make_pair("SWSS_RC_NOT_IMPLEMENTED", SWSS_RC_NOT_IMPLEMENTED) },
{ std::make_pair("SWSS_RC_FAILURE", SWSS_RC_FAILURE) }
};

const ErrorMap::SaiToSwssRCMap ErrorMap::m_saiToSwssRC = {
{ "SAI_STATUS_SUCCESS", "SWSS_RC_SUCCESS" },
{ "SAI_STATUS_INVALID_PARAMETER", "SWSS_RC_INVALID_PARAM" },
{ "SAI_STATUS_NOT_SUPPORTED", "SWSS_RC_UNAVAIL" },
{ "SAI_STATUS_ITEM_NOT_FOUND", "SWSS_RC_NOT_FOUND" },
{ "SAI_STATUS_NO_MEMEORY", "SWSS_RC_NO_MEMORY" },
{ "SAI_STATUS_ITEM_ALREADY_EXISTS", "SWSS_RC_EXISTS" },
{ "SAI_STATUS_TABLE_FULL", "SWSS_RC_TABLE_FULL" },
{ "SAI_STATUS_OBJECT_IN_USE", "SWSS_RC_IN_USE" },
{ "SAI_STATUS_NOT_IMPLEMENTED", "SWSS_RC_NOT_IMPLEMENTED" },
{ "SAI_STATUS_FAILURE", "SWSS_RC_FAILURE" }
};

ErrorMap &ErrorMap::getInstance()
{
static ErrorMap m_errorMap;
return m_errorMap;
}

std::string ErrorMap::getSwssRCStr(const std::string &saiRCStr)
{
std::string swssRCStr;

if (m_saiToSwssRC.find(saiRCStr) == m_saiToSwssRC.end())
{
SWSS_LOG_ERROR("Failed to map SAI error %s to SWSS error code", saiRCStr.c_str());
swssRCStr = "SWSS_RC_UNKNOWN";
}
else
{
swssRCStr = m_saiToSwssRC.at(saiRCStr);
}
return swssRCStr;
}

ErrorMap::SwssRC ErrorMap::getSwssRC(const std::string &swssRCStr)
{
for (auto &elem : m_swssStrToRC)
{
if (elem.first == swssRCStr)
{
return elem.second;
break;
}
}

/* Error mapping is not found */
SWSS_LOG_ERROR("Invalid SWSS error string %s is received", swssRCStr.c_str());
return SWSS_RC_UNKNOWN;
}

std::string ErrorMap::getSaiRCStr(SwssRC rc)
{
for (auto &elem : m_swssStrToRC)
{
if (elem.second == rc)
{
return elem.first;
}
}

/* Error mapping is not found */
SWSS_LOG_ERROR("Invalid SWSS error code %d is received", rc);

return "SWSS_RC_UNKNOWN";
}

};
62 changes: 62 additions & 0 deletions common/errormap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2019 Broadcom Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef SWSS_COMMON_ERRORMAP_H
#define SWSS_COMMON_ERRORMAP_H

#include <string>
#include <map>
#include <vector>

namespace swss {

class ErrorMap
{
public:
enum SwssRC
{
SWSS_RC_SUCCESS,
SWSS_RC_INVALID_PARAM,
SWSS_RC_UNAVAIL,
SWSS_RC_NOT_FOUND,
SWSS_RC_NO_MEMORY,
SWSS_RC_EXISTS,
SWSS_RC_TABLE_FULL,
SWSS_RC_IN_USE,
SWSS_RC_NOT_IMPLEMENTED,
SWSS_RC_FAILURE,
SWSS_RC_UNKNOWN
};

typedef std::map<std::string, std::string> SaiToSwssRCMap;
typedef std::vector<std::pair<std::string, SwssRC>> SwssStrToRCMap;

static const SwssStrToRCMap m_swssStrToRC;
static const SaiToSwssRCMap m_saiToSwssRC;

static ErrorMap &getInstance();
static std::string getSwssRCStr(const std::string &saiRCStr);
static SwssRC getSwssRC(const std::string &swssRCStr);
static std::string getSaiRCStr(SwssRC rc);

private:
ErrorMap() = default;
~ErrorMap();
};

}

#endif /* SWSS_COMMON_ERRORMAP_H */
7 changes: 7 additions & 0 deletions common/schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace swss {
#define FLEX_COUNTER_DB 5
#define STATE_DB 6
#define SNMP_OVERLAY_DB 7
#define ERROR_DB 8

/***** APPLICATION DATABASE *****/

Expand Down Expand Up @@ -200,6 +201,8 @@ namespace swss {
#define CFG_DEBUG_COUNTER_TABLE_NAME "DEBUG_COUNTER"
#define CFG_DEBUG_COUNTER_DROP_REASON_TABLE_NAME "DEBUG_COUNTER_DROP_REASON"

#define CFG_BGP_ERROR_TABLE_NAME "BGP_ERROR_CFG_TABLE"

/***** STATE DATABASE *****/

#define STATE_SWITCH_CAPABILITY_TABLE_NAME "SWITCH_CAPABILITY_TABLE"
Expand Down Expand Up @@ -239,6 +242,10 @@ namespace swss {
#define CFG_DTEL_QUEUE_REPORT_TABLE_NAME "DTEL_QUEUE_REPORT"
#define CFG_DTEL_EVENT_TABLE_NAME "DTEL_EVENT"

/***** ERROR DATABASE *****/
#define ERROR_NEIGH_TABLE_NAME "ERROR_NEIGH_TABLE"
#define ERROR_ROUTE_TABLE_NAME "ERROR_ROUTE_TABLE"

}

#endif
3 changes: 2 additions & 1 deletion common/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const TableNameSeparatorMap TableBase::tableNameSeparatorMap = {
{ CONFIG_DB, TABLE_NAME_SEPARATOR_VBAR },
{ PFC_WD_DB, TABLE_NAME_SEPARATOR_COLON },
{ FLEX_COUNTER_DB, TABLE_NAME_SEPARATOR_COLON },
{ STATE_DB, TABLE_NAME_SEPARATOR_VBAR }
{ STATE_DB, TABLE_NAME_SEPARATOR_VBAR },
{ ERROR_DB, TABLE_NAME_SEPARATOR_COLON }
};

Table::Table(const DBConnector *db, const string &tableName)
Expand Down

0 comments on commit d07b893

Please sign in to comment.