vslib/ResourceLimiterParser.cpp (114 lines of code) (raw):

#include "ResourceLimiterParser.h" #include "swss/logger.h" #include "swss/tokenize.h" #include "meta/sai_serialize.h" #include <fstream> using namespace saivs; std::shared_ptr<ResourceLimiterContainer> ResourceLimiterParser::parseFromFile( _In_ const char* fileName) { SWSS_LOG_ENTER(); if (fileName == nullptr) { SWSS_LOG_NOTICE("file name is NULL, returning empty limiter"); return std::make_shared<ResourceLimiterContainer>(); } std::string file(fileName); std::ifstream ifs(file); if (!ifs.is_open()) { SWSS_LOG_WARN("failed to open resource limiter file: %s", file.c_str()); return std::make_shared<ResourceLimiterContainer>(); } SWSS_LOG_NOTICE("loading resource limits from: %s", file.c_str()); std::string line; auto container = std::make_shared<ResourceLimiterContainer>(); while (getline(ifs, line)) { /* * line can be in 2 forms: * * SAI_OBJECT_TYPE_XXX=limit * N:SAI_OBJECT_TYPE_XXX=limit * * where N is switchIndex (0..255) - SAI_VS_SWITCH_INDEX_MAX * if N is not specified then zero (0) is assumed */ if (line.size() > 0 && (line[0] == '#' || line[0] == ';')) { continue; } SWSS_LOG_INFO("line: %s", line.c_str()); auto toks = swss::tokenize(line, '='); if (toks.size() != 2) { SWSS_LOG_ERROR("expected 2 tokens, got: %zu on line: %s", toks.size(), line.c_str()); continue; } auto tokens = swss::tokenize(toks.at(0), ':'); if (tokens.size() == 2) { parseLineWithIndex(container, tokens, toks.at(1)); } else if (tokens.size() == 1) { parseLineWithNoIndex(container, tokens, toks.at(1)); } else { SWSS_LOG_ERROR("expected 1 or 2 tokens in line %s, got %zu", line.c_str(), tokens.size()); } } return container; } void ResourceLimiterParser::parseLineWithIndex( _In_ std::shared_ptr<ResourceLimiterContainer> container, _In_ const std::vector<std::string>& tokens, _In_ const std::string& strLimit) { SWSS_LOG_ENTER(); auto swidx = tokens.at(0); auto strObjectType = tokens.at(1); uint32_t switchIndex; if (sscanf(swidx.c_str(), "%u", & switchIndex) != 1) { SWSS_LOG_ERROR("failed to parse switchIndex: %s", swidx.c_str()); return; } parse(container, switchIndex, strObjectType, strLimit); } void ResourceLimiterParser::parseLineWithNoIndex( _In_ std::shared_ptr<ResourceLimiterContainer> container, _In_ const std::vector<std::string>& tokens, _In_ const std::string& strLimit) { SWSS_LOG_ENTER(); auto strObjectType = tokens.at(0); parse(container, ResourceLimiter::DEFAULT_SWITCH_INDEX, strObjectType, strLimit); } void ResourceLimiterParser::parse( _In_ std::shared_ptr<ResourceLimiterContainer> container, _In_ uint32_t switchIndex, _In_ const std::string& strObjectType, _In_ const std::string& strLimit) { SWSS_LOG_ENTER(); sai_object_type_t objectType; try { sai_deserialize_object_type(strObjectType, objectType); } catch(const std::exception& e) { SWSS_LOG_ERROR("failed to deserialize '%s' as object type: %s", strObjectType.c_str(), e.what()); return; } size_t limit; if (sscanf(strLimit.c_str(), "%zu", &limit) != 1) { SWSS_LOG_ERROR("failed to parse '%s' as limit", strLimit.c_str()); return; } auto limiter = container->getResourceLimiter(switchIndex); if (limiter == nullptr) { limiter = std::make_shared<ResourceLimiter>(switchIndex); container->insert(switchIndex, limiter); } SWSS_LOG_NOTICE("adding limit on switch index %u, %s = %zu", switchIndex, sai_serialize_object_type(objectType).c_str(), limit); limiter->setObjectTypeLimit(objectType, limit); }