bool ComparisonLogic::checkAsicVsDatabaseConsistency()

in syncd/ComparisonLogic.cpp [2506:2656]


bool ComparisonLogic::checkAsicVsDatabaseConsistency(
        _In_ std::shared_ptr<VirtualOidTranslator> translator)
{
    SWSS_LOG_ENTER();

    bool hasErrors = false;

    {
        SWSS_LOG_TIMER("consistency check");

        SWSS_LOG_WARN("performing consistency check");

        for (const auto &pair: m_temp->m_soAll)
        {
            const auto &obj = pair.second;

            const auto &attrs = obj->getAllAttributes();

            // get object meta key for get (object id or *entry)

            sai_object_meta_key_t meta_key = obj->m_meta_key;

            // translate all VID's to RIDs in non object is's

            translator->translateVidToRid(meta_key);

            auto info = sai_metadata_get_object_type_info(obj->getObjectType());

            sai_attribute_t attr;

            memset(&attr, 0, sizeof(attr));

            if (attrs.size() == 0)
            {
                // get first attribute and do a get query to see if object exist's

                auto meta = info->attrmetadata[0];

                sai_status_t status = m_vendorSai->get(meta_key, 1, &attr);

                switch (status)
                {
                    case SAI_STATUS_SUCCESS:
                    case SAI_STATUS_BUFFER_OVERFLOW:
                        continue;

                    case SAI_STATUS_NOT_IMPLEMENTED:
                    case SAI_STATUS_NOT_SUPPORTED:

                        SWSS_LOG_WARN("GET api for %s is not implemented on %s",
                                meta->attridname,
                                obj->m_str_object_id.c_str());
                    continue;
                }

                SWSS_LOG_ERROR("failed to get %s on %s: %s",
                        meta->attridname,
                        obj->m_str_object_id.c_str(),
                        sai_serialize_status(status).c_str());

                hasErrors = true;

                continue;
            }

            for (const auto &ap: attrs)
            {
                const auto &saiAttr = ap.second;

                auto meta = saiAttr->getAttrMetadata();

                // deserialize existing attribute so deserialize will allocate
                // memory for all list's

                attr.id = meta->attrid;

                sai_deserialize_attr_value(saiAttr->getStrAttrValue(), *meta, attr, false);

                // translate all VIDs from DB to RIDs for compare

                translator->translateVidToRid(obj->getObjectType(), 1, &attr);

                // get attr value with RIDs

                const std::string& dbValue = sai_serialize_attr_value(*meta, attr);

                sai_status_t status = m_vendorSai->get(meta_key, 1, &attr);

                if (meta->attrid == SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST && meta->objecttype == SAI_OBJECT_TYPE_QOS_MAP && status == SAI_STATUS_SUCCESS)
                {
                    // order does not matter on this list

                    if (BestCandidateFinder::hasEqualQosMapList(attr.value.qosmap, saiAttr->getSaiAttr()->value.qosmap))
                    {
                        sai_deserialize_free_attribute_value(meta->attrvaluetype, attr);
                        continue;
                    }
                }

                // free possible allocated lists

                if (status != SAI_STATUS_SUCCESS)
                {
                    SWSS_LOG_ERROR("failed to get %s on %s %s",
                            meta->attridname,
                            obj->m_str_object_id.c_str(),
                            sai_serialize_status(status).c_str());

                    hasErrors = true;

                    sai_deserialize_free_attribute_value(meta->attrvaluetype, attr);
                    continue;
                }

                const std::string &asicValue = sai_serialize_attr_value(*meta, attr);

                sai_deserialize_free_attribute_value(meta->attrvaluetype, attr);

                // pointers will not be equal since those will be from
                // different process memory maps so just check if both pointers
                // are NULL or both are SET

                if (meta->attrvaluetype == SAI_ATTR_VALUE_TYPE_POINTER)
                {
                    if (attr.value.ptr == NULL && saiAttr->getSaiAttr()->value.ptr == NULL)
                        continue;

                    if (attr.value.ptr != NULL && saiAttr->getSaiAttr()->value.ptr != NULL)
                        continue;
                }

                if (asicValue == dbValue)
                    continue;

                SWSS_LOG_ERROR("value missmatch: %s on %s: ASIC: %s DB: %s, inconsistent state!",
                        meta->attridname,
                        obj->m_str_object_id.c_str(),
                        asicValue.c_str(),
                        dbValue.c_str());

                hasErrors = true;
            }
        }

        swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_INFO);
    }

    swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_NOTICE);

    return hasErrors == false;
}