syncd/HardReiniter.cpp (99 lines of code) (raw):
#include "HardReiniter.h"
#include "VidManager.h"
#include "SingleReiniter.h"
#include "RedisClient.h"
#include "swss/logger.h"
#include "meta/sai_serialize.h"
using namespace syncd;
HardReiniter::HardReiniter(
_In_ std::shared_ptr<RedisClient> client,
_In_ std::shared_ptr<VirtualOidTranslator> translator,
_In_ std::shared_ptr<sairedis::SaiInterface> sai,
_In_ std::shared_ptr<NotificationHandler> handler):
m_vendorSai(sai),
m_translator(translator),
m_client(client),
m_handler(handler)
{
SWSS_LOG_ENTER();
// empty
}
HardReiniter::~HardReiniter()
{
SWSS_LOG_ENTER();
// empty
}
void HardReiniter::readAsicState()
{
SWSS_LOG_ENTER();
SWSS_LOG_TIMER("read asic state");
// Repopulate asic view from redis db after hard asic initialize.
m_vidToRidMap = m_client->getVidToRidMap();
m_ridToVidMap = m_client->getRidToVidMap();
for (auto& v2r: m_vidToRidMap)
{
auto switchId = VidManager::switchIdQuery(v2r.first);
m_switchVidToRid[switchId][v2r.first] = v2r.second;
}
for (auto& r2v: m_ridToVidMap)
{
auto switchId = VidManager::switchIdQuery(r2v.second);
m_switchRidToVid[switchId][r2v.first] = r2v.second;
}
auto asicStateKeys = m_client->getAsicStateKeys();
for (const auto &key: asicStateKeys)
{
auto mk = key.substr(key.find_first_of(":") + 1); // skip asic key
sai_object_meta_key_t metaKey;
sai_deserialize_object_meta_key(mk, metaKey);
// if object is non object id then first item will be switch id
auto switchId = VidManager::switchIdQuery(metaKey.objectkey.key.object_id);
m_switchMap[switchId].push_back(key);
}
SWSS_LOG_NOTICE("loaded %zu switches", m_switchMap.size());
for (auto& kvp: m_switchMap)
{
SWSS_LOG_NOTICE("switch VID: %s", sai_serialize_object_id(kvp.first).c_str());
}
}
std::map<sai_object_id_t, std::shared_ptr<syncd::SaiSwitch>> HardReiniter::hardReinit()
{
SWSS_LOG_ENTER();
readAsicState();
std::vector<std::shared_ptr<SingleReiniter>> vec;
// perform hard reinit on all switches
for (auto& kvp: m_switchMap)
{
auto sr = std::make_shared<SingleReiniter>(
m_client,
m_translator,
m_vendorSai,
m_handler,
m_switchVidToRid.at(kvp.first),
m_switchRidToVid.at(kvp.first),
kvp.second);
sr->hardReinit();
vec.push_back(sr);
}
// since vid and rid maps contains all switches
// we need to combine them
ObjectIdMap vid2rid;
ObjectIdMap rid2vid;
for (auto&sr: vec)
{
auto map = sr->getTranslatedVid2Rid();
for (auto&kvp: map)
{
vid2rid[kvp.first] = kvp.second;
rid2vid[kvp.second] = kvp.first;
}
}
if (vid2rid.size() != rid2vid.size())
{
SWSS_LOG_THROW("FATAL: vid2rid %zu != rid2vid %zu",
vid2rid.size(),
rid2vid.size());
}
// now some object could be removed from switch then we need to execute
// post actions, and since those actions will be executed on switches which
// will also modify redis database we need to execute this after we put vid
// and rid map
/*
* NOTE: clear can be done after recreating all switches unless vid/rid map
* will be per switch. An all this must be ATOMIC.
*
* This needs to be addressed when we want to support multiple switches.
*/
m_client->setVidAndRidMap(vid2rid);
std::map<sai_object_id_t, std::shared_ptr<syncd::SaiSwitch>> switches;
for (auto& sr: vec)
{
sr->postRemoveActions();
auto sw = sr->getSwitch();
switches[sw->getVid()] = sw;
}
return switches;
}