in syncd/Syncd.cpp [4169:4373]
sai_status_t Syncd::processNotifySyncd(
_In_ const swss::KeyOpFieldsValuesTuple &kco)
{
SWSS_LOG_ENTER();
auto& key = kfvKey(kco);
sai_status_t status = SAI_STATUS_SUCCESS;
auto redisNotifySyncd = sai_deserialize_redis_notify_syncd(key);
if (redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_INVOKE_DUMP)
{
SWSS_LOG_NOTICE("Invoking SAI failure dump");
std::string ret_str;
int ret = swss::exec(SAI_FAILURE_DUMP_SCRIPT, ret_str);
if (ret != 0)
{
SWSS_LOG_ERROR("Error in executing SAI failure dump %s", ret_str.c_str());
status = SAI_STATUS_FAILURE;
}
sendNotifyResponse(status);
return status;
}
if (!m_commandLineOptions->m_enableTempView)
{
SWSS_LOG_NOTICE("received %s, ignored since TEMP VIEW is not used, returning success", key.c_str());
sendNotifyResponse(SAI_STATUS_SUCCESS);
return SAI_STATUS_SUCCESS;
}
if (m_veryFirstRun && m_firstInitWasPerformed && redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW)
{
/*
* Make sure that when second INIT view arrives, then we will jump to
* next section, since second init view may create switch that already
* exists and will fail with creating multiple switches error.
*/
m_veryFirstRun = false;
}
else if (m_veryFirstRun)
{
SWSS_LOG_NOTICE("very first run is TRUE, op = %s", key.c_str());
/*
* On the very first start of syncd, "compile" view is directly applied
* on device, since it will make it easier to switch to new asic state
* later on when we restart orch agent.
*/
if (redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW)
{
/*
* On first start we just do "apply" directly on asic so we set
* init to false instead of true.
*/
m_asicInitViewMode = false;
m_firstInitWasPerformed = true;
// we need to clear current temp view to make space for new one
clearTempView();
}
else if (redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW)
{
m_veryFirstRun = false;
m_asicInitViewMode = false;
#ifdef MELLANOX
bool applyViewInFastFastBoot = m_commandLineOptions->m_startType == SAI_START_TYPE_FASTFAST_BOOT ||
m_commandLineOptions->m_startType == SAI_START_TYPE_EXPRESS_BOOT ||
m_commandLineOptions->m_startType == SAI_START_TYPE_FAST_BOOT;
#else
bool applyViewInFastFastBoot = m_commandLineOptions->m_startType == SAI_START_TYPE_FASTFAST_BOOT ||
m_commandLineOptions->m_startType == SAI_START_TYPE_EXPRESS_BOOT;
#endif
if (applyViewInFastFastBoot)
{
// express/fastfast boot configuration end
status = onApplyViewInFastFastBoot();
}
SWSS_LOG_NOTICE("setting very first run to FALSE, op = %s", key.c_str());
}
else if (redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_INSPECT_ASIC)
{
SWSS_LOG_NOTICE("syncd switched to INSPECT ASIC mode");
inspectAsic();
sendNotifyResponse(SAI_STATUS_SUCCESS);
}
else
{
SWSS_LOG_THROW("unknown operation: %s", key.c_str());
}
sendNotifyResponse(status);
return status;
}
if (redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW)
{
if (m_asicInitViewMode)
{
SWSS_LOG_WARN("syncd is already in asic INIT VIEW mode, but received init again, orchagent restarted before apply?");
}
m_asicInitViewMode = true;
clearTempView();
m_createdInInitView.clear();
// NOTE: Currently as WARN to be easier to spot, later should be NOTICE.
SWSS_LOG_WARN("syncd switched to INIT VIEW mode, all op will be saved to TEMP view");
sendNotifyResponse(SAI_STATUS_SUCCESS);
}
else if (redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW)
{
m_asicInitViewMode = false;
// NOTE: Currently as WARN to be easier to spot, later should be NOTICE.
SWSS_LOG_WARN("syncd received APPLY VIEW, will translate");
try
{
status = applyView();
}
catch(...)
{
/*
* If apply view will fail with exception, try to send fail
* response to sairedis, since later there can be switch shutdown
* notification sent, and it will be synchronized with mutex, and
* it will not be processed until get response timeout will hit.
*/
sendNotifyResponse(SAI_STATUS_FAILURE);
throw;
}
sendNotifyResponse(status);
if (status == SAI_STATUS_SUCCESS)
{
/*
* We successfully applied new view, VID mapping could change, so
* we need to clear local db, and all new VIDs will be queried
* using redis.
*
* TODO possible race condition - get notification when new view is
* applied and cache have old values, and notification start's
* translating vid/rid, we need to stop processing notifications
* for transition (queue can still grow), possible fdb
* notifications but fdb learning was disabled on warm boot, so
* there should be no issue.
*/
m_translator->clearLocalCache();
m_createdInInitView.clear();
}
else
{
/*
* Apply view failed. It can fail in 2 ways, ether nothing was
* executed, on asic, or asic is inconsistent state then we should
* die or hang.
*/
return status;
}
}
else if (redisNotifySyncd == SAI_REDIS_NOTIFY_SYNCD_INSPECT_ASIC)
{
SWSS_LOG_NOTICE("syncd switched to INSPECT ASIC mode");
inspectAsic();
sendNotifyResponse(SAI_STATUS_SUCCESS);
}
else
{
SWSS_LOG_ERROR("unknown operation: %s", key.c_str());
sendNotifyResponse(SAI_STATUS_NOT_IMPLEMENTED);
SWSS_LOG_THROW("notify syncd %s operation failed", key.c_str());
}
return SAI_STATUS_SUCCESS;
}