in syncd/ComparisonLogic.cpp [2027:2154]
void ComparisonLogic::removeCurrentObjectDependencyTree(
_In_ AsicView ¤tView,
_In_ AsicView &temporaryView,
_In_ const std::shared_ptr<SaiObj>& currentObj)
{
SWSS_LOG_ENTER();
if (!currentObj->isOidObject())
{
// we should be able to remove non object right away since it's leaf
removeExistingObjectFromCurrentView(currentView, temporaryView, currentObj);
return;
}
// check reference count and remove other objects if necessary
const int count = currentView.getVidReferenceCount(currentObj->getVid());
if (count)
{
SWSS_LOG_INFO("similar best match has reference count: %d, will need to remove other objects", count);
auto* info = sai_metadata_get_object_type_info(currentObj->getObjectType());
// use reverse dependency graph to locate objects where current object can be used
// need to lookout on loops on some objects
for (size_t i = 0; i < info->revgraphmemberscount; i++)
{
auto *revgraph = info->revgraphmembers[i];
if (revgraph->structmember)
{
SWSS_LOG_THROW("struct fields not supported yet, FIXME");
}
SWSS_LOG_INFO("used on %s:%s",
sai_serialize_object_type(revgraph->depobjecttype).c_str(),
revgraph->attrmetadata->attridname);
// TODO it could be not processed, or matched, since on matched we
// can still break the link
auto objs = currentView.getObjectsByObjectType(revgraph->depobjecttype);
for (auto& obj: objs)
{
// NOTE: current object can have multiple OID attributes that
// they can have the same value, but they can have different
// attributes (like set/create_only)
auto status = obj->getObjectStatus();
if (status != SAI_OBJECT_STATUS_NOT_PROCESSED &&
status != SAI_OBJECT_STATUS_MATCHED)
{
continue;
}
auto attr = obj->tryGetSaiAttr(revgraph->attrmetadata->attrid);
if (attr == nullptr)
{
// no such attribute
continue;
}
if (revgraph->attrmetadata->attrvaluetype != SAI_ATTR_VALUE_TYPE_OBJECT_ID &&
revgraph->attrmetadata->attrvaluetype != SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID)
{
// currently we only support reference on OID, not list
SWSS_LOG_THROW("attr value type %d, not supported yet, FIXME",
revgraph->attrmetadata->attrvaluetype);
}
if (attr->getOid() != currentObj->getVid())
{
// VID is not matching, skip this attribute
continue;
}
// we found object and attribute that is using current VID,
// it's possible this VID is used on multiple attributes on the
// same object
SWSS_LOG_INFO("found reference object: %s", obj->m_str_object_id.c_str());
if (revgraph->attrmetadata->iscreateonly && status == SAI_OBJECT_STATUS_NOT_PROCESSED)
{
// attribute is create only, and object was not processed
// yet this means that we need to remove object, since we
// can't break the link
removeCurrentObjectDependencyTree(currentView, temporaryView, obj); // recursion
}
else if (revgraph->attrmetadata->iscreateandset && status == SAI_OBJECT_STATUS_NOT_PROCESSED)
{
if (revgraph->attrmetadata->allownullobjectid)
{
// we can also remove entire object here too
SWSS_LOG_THROW("break the link is not implemented yet, FIXME");
}
else
{
// attribute is create and set, but not allow null object id
// so probably attribute is mandatory on create, we can't break
// the link, but we can remove entire object
removeCurrentObjectDependencyTree(currentView, temporaryView, obj); // recursion
}
}
else if (revgraph->attrmetadata->iscreateandset && status == SAI_OBJECT_STATUS_MATCHED)
{
SWSS_LOG_THROW("matched break the link is not implemented yet, FIXME");
}
else
{
SWSS_LOG_THROW("remove on %s, obj status: %d, not supported, FIXME", revgraph->attrmetadata->attridname, status);
}
}
}
}
removeExistingObjectFromCurrentView(currentView, temporaryView, currentObj);
}