Esempio n. 1
0
void WatermarkOrch::doTask(NotificationConsumer &consumer)
{
    if (!gPortsOrch->isPortReady())
    {
        return;
    }

    std::string op;
    std::string data;
    std::vector<swss::FieldValueTuple> values;

    consumer.pop(op, data, values);

    Table * table = NULL;

    if (op == "PERSISTENT")
    {
        table = m_persistentWatermarkTable.get();
    }
    else if (op == "USER")
    {
        table = m_userWatermarkTable.get();
    }
    else
    {
        SWSS_LOG_WARN("Unknown watermark clear request op: %s", op.c_str());
        return;
    }

    if(data == CLEAR_PG_HEADROOM_REQUEST)
    {
        clearSingleWm(table,
        "SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES",
        m_pg_ids);
    }
    else if(data == CLEAR_PG_SHARED_REQUEST)
    {
        clearSingleWm(table,
        "SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES",
        m_pg_ids);
    }
    else if(data == CLEAR_QUEUE_SHARED_UNI_REQUEST)
    {
        clearSingleWm(table,
        "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
        m_unicast_queue_ids);
    }
    else if(data == CLEAR_QUEUE_SHARED_MULTI_REQUEST)
    {
        clearSingleWm(table,
        "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES",
        m_multicast_queue_ids);
    }
    else
    {
        SWSS_LOG_WARN("Unknown watermark clear request data: %s", data.c_str());
        return;
    }
}
sai_status_t refresh_read_only(
        _In_ const sai_attr_metadata_t *meta,
        _In_ sai_object_id_t object_id,
        _In_ sai_object_id_t switch_id)
{
    SWSS_LOG_ENTER();

    /*
     * Read only, must be per switch since maybe different implemented,
     * different order maybe on the queues.
     */

    switch (g_vs_switch_type)
    {
        case SAI_VS_SWITCH_TYPE_BCM56850:
            return refresh_read_only_BCM56850(meta, object_id, switch_id);

        case SAI_VS_SWITCH_TYPE_MLNX2700:
            return refresh_read_only_MLNX2700(meta, object_id, switch_id);

        default:
            break;
    }

    SWSS_LOG_WARN("need to recalculate RO: %s", meta->attridname);

    return SAI_STATUS_NOT_IMPLEMENTED;
}
Esempio n. 3
0
bool handleRestartQuery(swss::NotificationConsumer &restartQuery)
{
    SWSS_LOG_ENTER();

    std::string op;
    std::string data;
    std::vector<swss::FieldValueTuple> values;

    restartQuery.pop(op, data, values);

    SWSS_LOG_DEBUG("op = %d", op.c_str());

    if (op == "COLD")
    {
        SWSS_LOG_NOTICE("received COLD switch shutdown event");
        return false;
    }

    if (op == "WARM")
    {
        SWSS_LOG_NOTICE("received WARM switch shutdown event");
        return true;
    }

    SWSS_LOG_WARN("received '%s' unknown switch shutdown event, assuming COLD", op.c_str());
    return false;
}
void processFdbEntriesForAging()
{
    SWSS_LOG_ENTER();

    if (!g_recursive_mutex.try_lock())
    {
        return;
    }

    SWSS_LOG_INFO("fdb infos to process: %zu", g_fdb_info_set.size());

    uint32_t current = (uint32_t)time(NULL);

    // find aged fdb entries

    for (auto it = g_fdb_info_set.begin(); it != g_fdb_info_set.end();)
    {
        sai_attribute_t attr;

        attr.id = SAI_SWITCH_ATTR_FDB_AGING_TIME;

        sai_status_t status = vs_generic_get(SAI_OBJECT_TYPE_SWITCH, it->fdb_entry.switch_id, 1, &attr);

        if (status != SAI_STATUS_SUCCESS)
        {
            SWSS_LOG_WARN("failed to get FDB aging time for switch %s",
                    sai_serialize_object_id(it->fdb_entry.switch_id).c_str());

            ++it;
            continue;
        }

        uint32_t aging_time = attr.value.u32;

        if (aging_time == 0)
        {
            // aging is disabled
            ++it;
            continue;
        }

        if ((current - it->timestamp) >= aging_time)
        {
            fdb_info_t fi = *it;

            processFdbInfo(fi, SAI_FDB_EVENT_AGED);

            it = g_fdb_info_set.erase(it);
        }
        else
        {
            ++it;
        }
    }

    g_recursive_mutex.unlock();
}
Esempio n. 5
0
void Select::addSelectable(Selectable *selectable)
{
    if(find(m_objects.begin(), m_objects.end(), selectable) != m_objects.end())
    {
        SWSS_LOG_WARN("Selectable is already added to the list, ignoring.");
        return;
    }
    m_objects.push_back(selectable);
}
void handleCmdLine(int argc, char **argv)
{
    SWSS_LOG_ENTER();

    while(true)
    {
        static struct option long_options[] =
        {
            { "useTempView",      no_argument,       0, 'u' },
            { "help",             no_argument,       0, 'h' },
            { "skipNotifySyncd",  no_argument,       0, 'C' },
            { "enableDebug",      no_argument,       0, 'd' },
            { 0,                  0,                 0,  0  }
        };

        const char* const optstring = "hCdu";

        int option_index;

        int c = getopt_long(argc, argv, optstring, long_options, &option_index);

        if (c == -1)
            break;

        switch (c)
        {
            case 'd':
                swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG);
                break;

            case 'u':
                g_useTempView = false;
                break;

            case 'C':
                g_notifySyncd = false;
                break;

            case 'h':
                printUsage();
                exit(EXIT_SUCCESS);

            case '?':
                SWSS_LOG_WARN("unknown option %c", optopt);
                printUsage();
                exit(EXIT_FAILURE);

            default:
                SWSS_LOG_ERROR("getopt_long failure");
                exit(EXIT_FAILURE);
        }
    }
}
Esempio n. 7
0
void handleProfileMap(const std::string& profileMapFile)
{
    SWSS_LOG_ENTER();

    if (profileMapFile.size() == 0)
        return;

    std::ifstream profile(profileMapFile);

    if (!profile.is_open())
    {
        SWSS_LOG_ERROR("failed to open profile map file: %s : %s", profileMapFile.c_str(), strerror(errno));
        exit(EXIT_FAILURE);
    }

    std::string line;

    while(getline(profile, line))
    {
        if (line.size() > 0 && (line[0] == '#' || line[0] == ';'))
            continue;

        size_t pos = line.find("=");

        if (pos == std::string::npos)
        {
            SWSS_LOG_WARN("not found '=' in line %s", line.c_str());
            continue;
        }

        std::string key = line.substr(0, pos);
        std::string value = line.substr(pos + 1);

        gProfileMap[key] = value;

        SWSS_LOG_INFO("insert: %s:%s", key.c_str(), value.c_str());
    }
}
Esempio n. 8
0
static int profile_get_next_value(
        _In_ sai_switch_profile_id_t profile_id,
        _Out_ const char** variable,
        _Out_ const char** value)
{
    SWSS_LOG_ENTER();

    if (value == NULL)
    {
        SWSS_LOG_INFO("resetting profile map iterator");

        return 0;
    }

    if (variable == NULL)
    {
        SWSS_LOG_WARN("variable is null");
        return -1;
    }

    SWSS_LOG_INFO("iterator reached end");
    return -1;
}
Esempio n. 9
0
int profile_get_next_value(
        _In_ sai_switch_profile_id_t profile_id,
        _Out_ const char** variable,
        _Out_ const char** value)
{
    SWSS_LOG_ENTER();

    if (value == NULL)
    {
        SWSS_LOG_INFO("resetting profile map iterator");

        gProfileIter = gProfileMap.begin();
        return 0;
    }

    if (variable == NULL)
    {
        SWSS_LOG_WARN("variable is null");
        return -1;
    }

    if (gProfileIter == gProfileMap.end())
    {
        SWSS_LOG_INFO("iterator reached end");
        return -1;
    }

    *variable = gProfileIter->first.c_str();
    *value = gProfileIter->second.c_str();

    SWSS_LOG_INFO("key: %s:%s", *variable, *value);

    gProfileIter++;

    return 0;
}
Esempio n. 10
0
const char* profile_get_value(
        _In_ sai_switch_profile_id_t profile_id,
        _In_ const char* variable)
{
    SWSS_LOG_ENTER();

    if (variable == NULL)
    {
        SWSS_LOG_WARN("variable is null");
        return NULL;
    }

    auto it = gProfileMap.find(variable);

    if (it == gProfileMap.end())
    {
        SWSS_LOG_INFO("%s: NULL", variable);
        return NULL;
    }

    SWSS_LOG_INFO("%s: %s", variable, it->second.c_str());

    return it->second.c_str();
}
Esempio n. 11
0
WatermarkOrch::WatermarkOrch(DBConnector *db, const string tableName):
    Orch(db, tableName)
{
    SWSS_LOG_ENTER();

    m_countersDb = make_shared<DBConnector>(COUNTERS_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
    m_appDb = make_shared<DBConnector>(APPL_DB, DBConnector::DEFAULT_UNIXSOCKET, 0);
    m_countersTable = make_shared<Table>(m_countersDb.get(), COUNTERS_TABLE);
    m_periodicWatermarkTable = make_shared<Table>(m_countersDb.get(), PERIODIC_WATERMARKS_TABLE);
    m_persistentWatermarkTable = make_shared<Table>(m_countersDb.get(), PERSISTENT_WATERMARKS_TABLE);
    m_userWatermarkTable = make_shared<Table>(m_countersDb.get(), USER_WATERMARKS_TABLE);

    m_clearNotificationConsumer = new swss::NotificationConsumer(
            m_appDb.get(),
            "WATERMARK_CLEAR_REQUEST");
    auto clearNotifier = new Notifier(m_clearNotificationConsumer, this, "WM_CLEAR_NOTIFIER");
    Orch::addExecutor(clearNotifier);

    auto intervT = timespec { .tv_sec = DEFAULT_TELEMETRY_INTERVAL , .tv_nsec = 0 };
    m_telemetryTimer = new SelectableTimer(intervT);
    auto executorT = new ExecutableTimer(m_telemetryTimer, this, "WM_TELEMETRY_TIMER");
    Orch::addExecutor(executorT);
    m_telemetryTimer->start();

    m_telemetryInterval = DEFAULT_TELEMETRY_INTERVAL;
}

WatermarkOrch::~WatermarkOrch()
{
    SWSS_LOG_ENTER();
}

void WatermarkOrch::doTask(Consumer &consumer)
{
    SWSS_LOG_ENTER();

    if (!gPortsOrch->isPortReady())
    {
        return;
    }

    auto it = consumer.m_toSync.begin();
    while (it != consumer.m_toSync.end())
    {
        KeyOpFieldsValuesTuple t = it->second;

        string key = kfvKey(t);
        string op = kfvOp(t);
        std::vector<FieldValueTuple> fvt = kfvFieldsValues(t);

        if (op == SET_COMMAND)
        {
            if (key == "TELEMETRY_INTERVAL")
            {
                for (std::pair<std::basic_string<char>, std::basic_string<char> > i: fvt)
                {
                    if (i.first == "interval")
                    {
                        m_telemetryInterval = to_uint<uint32_t>(i.second.c_str());
                    }
                    else
                    {
                        SWSS_LOG_WARN("Unsupported key: %s", i.first.c_str());
                    }
                }
            }
        }
        else if (op == DEL_COMMAND)
        {
            SWSS_LOG_WARN("Unsupported op %s", op.c_str());
        }
        else
        {
            SWSS_LOG_ERROR("Unknown operation type %s\n", op.c_str());
        }

        consumer.m_toSync.erase(it++);
    }
}
Esempio n. 12
0
cmdOptions handleCmdLine(int argc, char **argv)
{
    SWSS_LOG_ENTER();

    cmdOptions options = {};

    const int defaultCountersThreadIntervalInSeconds = 1;

    options.countersThreadIntervalInSeconds = defaultCountersThreadIntervalInSeconds;

    while(true)
    {
        static struct option long_options[] =
        {
            { "diag",             no_argument,       0, 'd' },
            { "nocounters",       no_argument,       0, 'N' },
            { "warmStart",        no_argument,       0, 'w' },
            { "profile",          required_argument, 0, 'p' },
            { "countersInterval", required_argument, 0, 'i' },
            { 0,                  0,                 0,  0  }
        };

        int option_index = 0;

        int c = getopt_long(argc, argv, "dNwp:i:", long_options, &option_index);

        if (c == -1)
            break;

        switch (c)
        {
            case 'N':
                SWSS_LOG_NOTICE("disable counters thread");
                options.disableCountersThread = true;
                break;

            case 'd':
                SWSS_LOG_NOTICE("enable diag shell");
                options.diagShell = true;
                break;

            case 'p':
                SWSS_LOG_NOTICE("profile map file: %s", optarg);
                options.profileMapFile = std::string(optarg);
                break;

            case 'i':
                {
                    SWSS_LOG_NOTICE("counters thread interval: %s", optarg);

                    int interval = std::stoi(std::string(optarg));

                    if (interval == 0)
                    {
                        // use zero interval to disable counters thread
                        options.disableCountersThread = true;
                    }
                    else
                    {
                        options.countersThreadIntervalInSeconds =
                            std::max(defaultCountersThreadIntervalInSeconds, interval);
                    }

                    break;
                }

            case 'w':
                SWSS_LOG_NOTICE("warm start request");
                options.warmStart = true;
                break;

            case '?':
                SWSS_LOG_WARN("unknown get opti option %c", optopt);
                exit(EXIT_FAILURE);
                break;

            default:
                SWSS_LOG_ERROR("getopt_long failure");
                exit(EXIT_FAILURE);
        }
    }

    return options;
}
Esempio n. 13
0
int main(int argc, char **argv)
{
    swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG);

    SWSS_LOG_ENTER();

    auto options = handleCmdLine(argc, argv);

    handleProfileMap(options.profileMapFile);

    swss::DBConnector *db = new swss::DBConnector(ASIC_DB, "localhost", 6379, 0);
    swss::DBConnector *dbNtf = new swss::DBConnector(ASIC_DB, "localhost", 6379, 0);

    g_redisClient = new swss::RedisClient(db);

    updateLogLevel();

    swss::ConsumerTable *asicState = new swss::ConsumerTable(db, "ASIC_STATE");
    swss::NotificationConsumer *notifySyncdQuery = new swss::NotificationConsumer(db, "NOTIFYSYNCDREQUERY");
    swss::NotificationConsumer *restartQuery = new swss::NotificationConsumer(db, "RESTARTQUERY");

    // at the end we cant use producer consumer concept since
    // if one proces will restart there may be something in the queue
    // also "remove" from response queue will also trigger another "response"
    getRequest = new swss::ConsumerTable(db, "GETREQUEST");
    getResponse  = new swss::ProducerTable(db, "GETRESPONSE");
    notifications = new swss::NotificationProducer(dbNtf, "NOTIFICATIONS");
    notifySyncdResponse = new swss::NotificationProducer(db, "NOTIFYSYNCDRESPONSE");

#ifdef MLNXSAI
    /* This file is included in Mellanox SAI package. */
    std::string mlnx_config_file = "/usr/share/sai_2700.xml";
    gProfileMap[SAI_KEY_INIT_CONFIG_FILE] = mlnx_config_file;
#endif /* MLNX_SAI */

    g_veryFirstRun = isVeryFirstRun();

    if (options.warmStart)
    {
        const char *warmBootReadFile = profile_get_value(0, SAI_KEY_WARM_BOOT_READ_FILE);

        SWSS_LOG_NOTICE("using warmBootReadFile: '%s'", warmBootReadFile);

        if (warmBootReadFile == NULL || access(warmBootReadFile, F_OK) == -1)
        {
            SWSS_LOG_WARN("user requested warmStart but warmBootReadFile is not specified or not accesible, forcing cold start");

            options.warmStart = false;
        }
    }

    if (options.warmStart && g_veryFirstRun)
    {
        SWSS_LOG_WARN("warm start requested, but this is very first syncd start, forcing cold start");

        // we force cold start since if it's first run then redis db is not complete
        // so redis asic view will not reflect warm boot asic state, if this happen
        // then orch agent needs to be restarted as well to repopulate asic view
        options.warmStart = false;
    }

//    gProfileMap[SAI_KEY_WARM_BOOT] = options.warmStart ? "1" : "0";

    sai_api_initialize(0, (service_method_table_t*)&test_services);

    populate_sai_apis();

    initialize_common_api_pointers();

    sai_status_t status = sai_switch_api->initialize_switch(0, "0xb850", "", &switch_notifications);

    if (status != SAI_STATUS_SUCCESS)
    {
        SWSS_LOG_ERROR("fail to sai_initialize_switch: %d", status);
        exit(EXIT_FAILURE);
    }

#ifdef BRCMSAI

    if (options.diagShell)
    {
        SWSS_LOG_NOTICE("starting bcm diag shell thread");

        std::thread bcm_diag_shell_thread = std::thread(sai_diag_shell);
        bcm_diag_shell_thread.detach();
    }

#endif /* BRCMSAI */

    SWSS_LOG_NOTICE("syncd started");

    bool warmRestartHint = false;

    try
    {
        onSyncdStart(options.warmStart);

        if (options.disableCountersThread == false)
        {
            SWSS_LOG_NOTICE("starting counters thread");

            startCountersThread(options.countersThreadIntervalInSeconds);
        }

        SWSS_LOG_NOTICE("syncd listening for events");

        swss::Select s;

        s.addSelectable(getRequest);
        s.addSelectable(asicState);
        s.addSelectable(notifySyncdQuery);
        s.addSelectable(restartQuery);

        while(true)
        {
            swss::Selectable *sel;

            int fd;

            int result = s.select(&sel, &fd);

            if (sel == restartQuery)
            {
                warmRestartHint = handleRestartQuery(*restartQuery);
                break;
            }

            if (sel == notifySyncdQuery)
            {
                notifySyncd(*notifySyncdQuery);
                continue;
            }

            if (result == swss::Select::OBJECT)
            {
                processEvent(*(swss::ConsumerTable*)sel);
            }
        }
    }
    catch(const std::exception &e)
    {
        SWSS_LOG_ERROR("Runtime error: %s", e.what());

        exit(EXIT_FAILURE);
    }

    endCountersThread();

    if (warmRestartHint)
    {
        const char *warmBootWriteFile = profile_get_value(0, SAI_KEY_WARM_BOOT_WRITE_FILE);

        SWSS_LOG_NOTICE("using warmBootWriteFile: '%s'", warmBootWriteFile);

        if (warmBootWriteFile == NULL)
        {
            SWSS_LOG_WARN("user requested warm shutdown but warmBootWriteFile is not specified, forcing cold shutdown");

            warmRestartHint = false;
        }
    }

    sai_switch_api->shutdown_switch(warmRestartHint);

    SWSS_LOG_NOTICE("calling api uninitialize");

    sai_api_uninitialize();

    SWSS_LOG_NOTICE("uninitialize finished");

    return EXIT_SUCCESS;
}
Esempio n. 14
0
/*
 * Before stopping orchagent for warm restart, basic state check is preferred to
 * ensure orchagent is not in transient state, so a deterministic state may be restored after restart.
 *
 * Here is to implement orchagent_restart_check binary which may talk to orchagent and
 * ask it to do self-check, return "READY " signal and freeze if everything is ok,
 * otherwise "NOT_READY" signal should be returned.
 *
 * Optionally:
 *            if --noFreeze option is provided, orchagent won't freeze.
 *            if --skipPendingTaskCheck option is provided, orchagent won't use
 *                 whether there is pending task existing as state check criterion.
 */
int main(int argc, char **argv)
{
    swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_INFO);
    SWSS_LOG_ENTER();

    std::string skipPendingTaskCheck = "fasle";
    std::string noFreeze            = "fasle";
    /* Default wait time is 1000 millisecond */
    int waitTime = 1000;

    const char* const optstring = "nsw:";
    while(true)
    {
        static struct option long_options[] =
        {
            { "noFreeze",                no_argument,       0, 'n' },
            { "skipPendingTaskCheck",    no_argument,       0, 's' },
            { "waitTime",                required_argument, 0, 'w' }
        };

        int option_index = 0;

        int c = getopt_long(argc, argv, optstring, long_options, &option_index);

        if (c == -1)
        {
            break;
        }

        switch (c)
        {
            case 'n':
                SWSS_LOG_NOTICE("Won't freeze orchagent even if check succeeded");
                noFreeze = "true";
                break;
            case 's':
                SWSS_LOG_NOTICE("Skipping pending task check for orchagent");
                skipPendingTaskCheck = "true";
                break;
            case 'w':
                SWSS_LOG_NOTICE("Wait time for response from orchagent set to %s milliseconds", optarg);
                waitTime = atoi(optarg);
                break;
            case 'h':
                printUsage();
                exit(EXIT_SUCCESS);

            case '?':
                SWSS_LOG_WARN("unknown option %c", optopt);
                printUsage();
                exit(EXIT_FAILURE);

            default:
                SWSS_LOG_ERROR("getopt_long failure");
                exit(EXIT_FAILURE);
        }
    }

    swss::DBConnector db(APPL_DB, swss::DBConnector::DEFAULT_UNIXSOCKET, 0);
    // Send warm restart query via "RESTARTCHECK" notification channel
    swss::NotificationProducer restartQuery(&db, "RESTARTCHECK");
    // Will listen for the reply on "RESTARTCHECKREPLY" channel
    swss::NotificationConsumer restartQueryReply(&db, "RESTARTCHECKREPLY");

    std::vector<swss::FieldValueTuple> values;
    values.emplace_back("NoFreeze", noFreeze);
    values.emplace_back("SkipPendingTaskCheck", skipPendingTaskCheck);
    std::string op = "orchagent";
    SWSS_LOG_NOTICE("requested %s to do warm restart state check", op.c_str());
    restartQuery.send(op, op, values);


    swss::Select s;
    s.addSelectable(&restartQueryReply);
    swss::Selectable *sel;
    std::string op_ret, data;
    values.clear();
    int result = s.select(&sel, waitTime);
    if (result == swss::Select::OBJECT)
    {
        restartQueryReply.pop(op_ret, data, values);
        if (data == "READY")
        {
            SWSS_LOG_NOTICE("RESTARTCHECK success, %s is frozen and ready for warm restart", op_ret.c_str());
            std::cout << "RESTARTCHECK succeeded" << std::endl;
            return EXIT_SUCCESS;
        }
        else
        {
            SWSS_LOG_NOTICE("RESTARTCHECK failed, %s is not ready for warm restart with status %s",
                    op_ret.c_str(), data.c_str());
        }
    }
    else if (result == swss::Select::TIMEOUT)
    {
        SWSS_LOG_NOTICE("RESTARTCHECK for %s timed out", op_ret.c_str());
    }
    else
    {
        SWSS_LOG_NOTICE("RESTARTCHECK for %s error", op_ret.c_str());
    }
    std::cout << "RESTARTCHECK failed" << std::endl;
    return EXIT_FAILURE;
}
sai_status_t refresh_read_only_BCM56850(
        _In_ const sai_attr_metadata_t *meta,
        _In_ sai_object_id_t object_id,
        _In_ sai_object_id_t switch_id)
{
    SWSS_LOG_ENTER();

    if (meta->objecttype == SAI_OBJECT_TYPE_SWITCH)
    {
        switch (meta->attrid)
        {
            case SAI_SWITCH_ATTR_PORT_NUMBER:
                return SAI_STATUS_SUCCESS;

            case SAI_SWITCH_ATTR_CPU_PORT:
            case SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID:
            case SAI_SWITCH_ATTR_DEFAULT_TRAP_GROUP:
            case SAI_SWITCH_ATTR_DEFAULT_VLAN_ID:
            case SAI_SWITCH_ATTR_DEFAULT_STP_INST_ID:
            case SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID:
                return SAI_STATUS_SUCCESS;

            case SAI_SWITCH_ATTR_ACL_ENTRY_MINIMUM_PRIORITY:
            case SAI_SWITCH_ATTR_ACL_ENTRY_MAXIMUM_PRIORITY:
                return SAI_STATUS_SUCCESS;

            case SAI_SWITCH_ATTR_NUMBER_OF_ECMP_GROUPS:
                return SAI_STATUS_SUCCESS;

                /*
                 * We don't need to recalculate port list, since now we assume
                 * that port list will not change.
                 */

            case SAI_SWITCH_ATTR_PORT_LIST:
                return SAI_STATUS_SUCCESS;

            case SAI_SWITCH_ATTR_QOS_MAX_NUMBER_OF_CHILDS_PER_SCHEDULER_GROUP:
                return SAI_STATUS_SUCCESS;
        }
    }

    if (meta->objecttype == SAI_OBJECT_TYPE_PORT)
    {
        switch (meta->attrid)
        {
            case SAI_PORT_ATTR_QOS_NUMBER_OF_QUEUES:
            case SAI_PORT_ATTR_QOS_QUEUE_LIST:
                return refresh_qos_queues(meta, object_id, switch_id);

            case SAI_PORT_ATTR_NUMBER_OF_INGRESS_PRIORITY_GROUPS:
            case SAI_PORT_ATTR_INGRESS_PRIORITY_GROUP_LIST:
                return refresh_ingress_priority_group(meta, object_id, switch_id);

            case SAI_PORT_ATTR_QOS_NUMBER_OF_SCHEDULER_GROUPS:
            case SAI_PORT_ATTR_QOS_SCHEDULER_GROUP_LIST:
                return refresh_scheduler_groups(meta, object_id, switch_id);

                /*
                 * This status is based on hostif vEthernetX status.
                 */

            case SAI_PORT_ATTR_OPER_STATUS:
                return SAI_STATUS_SUCCESS;
        }
    }

    if (meta->objecttype == SAI_OBJECT_TYPE_SCHEDULER_GROUP)
    {
        switch (meta->attrid)
        {
            case SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT:
            case SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST:
                return refresh_scheduler_groups(meta, object_id, switch_id);
        }
    }

    if (meta->objecttype == SAI_OBJECT_TYPE_BRIDGE && meta->attrid == SAI_BRIDGE_ATTR_PORT_LIST)
    {
        return refresh_bridge_port_list(meta, object_id, switch_id);
    }

    if (meta->objecttype == SAI_OBJECT_TYPE_VLAN && meta->attrid == SAI_VLAN_ATTR_MEMBER_LIST)
    {
        return refresh_vlan_member_list(meta, object_id, switch_id);
    }

    if (meta_unittests_enabled())
    {
        SWSS_LOG_NOTICE("unittests enabled, SET could be performed on %s, not recalculating", meta->attridname);

        return SAI_STATUS_SUCCESS;
    }

    SWSS_LOG_WARN("need to recalculate RO: %s", meta->attridname);

    return SAI_STATUS_NOT_IMPLEMENTED;
}
Esempio n. 16
0
cmdOptions handleCmdLine(int argc, char **argv)
{
    SWSS_LOG_ENTER();

    cmdOptions options = {};

    const int defaultCountersThreadIntervalInSeconds = 1;

    options.countersThreadIntervalInSeconds = defaultCountersThreadIntervalInSeconds;

#ifdef SAITHRIFT
    options.run_rpc_server = false;
    const char* const optstring = "dNt:p:i:rm:h";
#else
    const char* const optstring = "dNt:p:i:h";
#endif // SAITHRIFT

    while(true)
    {
        static struct option long_options[] =
        {
            { "diag",             no_argument,       0, 'd' },
            { "nocounters",       no_argument,       0, 'N' },
            { "startType",        required_argument, 0, 't' },
            { "profile",          required_argument, 0, 'p' },
            { "countersInterval", required_argument, 0, 'i' },
            { "help",             no_argument,       0, 'h' },
#ifdef SAITHRIFT
            { "rpcserver",        no_argument,       0, 'r' },
            { "portmap",          required_argument, 0, 'm' },
#endif // SAITHRIFT
            { 0,                  0,                 0,  0  }
        };

        int option_index = 0;

        int c = getopt_long(argc, argv, optstring, long_options, &option_index);

        if (c == -1)
            break;

        switch (c)
        {
            case 'N':
                SWSS_LOG_NOTICE("disable counters thread");
                options.disableCountersThread = true;
                break;

            case 'd':
                SWSS_LOG_NOTICE("enable diag shell");
                options.diagShell = true;
                break;

            case 'p':
                SWSS_LOG_NOTICE("profile map file: %s", optarg);
                options.profileMapFile = std::string(optarg);
                break;

            case 'i':
                {
                    SWSS_LOG_NOTICE("counters thread interval: %s", optarg);

                    int interval = std::stoi(std::string(optarg));

                    if (interval == 0)
                    {
                        // use zero interval to disable counters thread
                        options.disableCountersThread = true;
                    }
                    else
                    {
                        options.countersThreadIntervalInSeconds =
                            std::max(defaultCountersThreadIntervalInSeconds, interval);
                    }

                    break;
                }

            case 't':
                SWSS_LOG_NOTICE("start type: %s", optarg);
                if (std::string(optarg) == "cold")
                {
                    options.startType = SAI_COLD_BOOT;
                }
                else if (std::string(optarg) == "warm")
                {
                    options.startType = SAI_WARM_BOOT;
                }
                else if (std::string(optarg) == "fast")
                {
                    options.startType = SAI_FAST_BOOT;
                }
                else
                {
                    SWSS_LOG_ERROR("unknown start type %s", optarg);
                    exit(EXIT_FAILURE);
                }
                break;

#ifdef SAITHRIFT
            case 'r':
                SWSS_LOG_NOTICE("enable rpc server");
                options.run_rpc_server = true;
                break;
            case 'm':
                SWSS_LOG_NOTICE("port map file: %s", optarg);
                options.portMapFile = std::string(optarg);
                break;
#endif // SAITHRIFT

            case 'h':
                printUsage();
                exit(EXIT_SUCCESS);

            case '?':
                SWSS_LOG_WARN("unknown option %c", optopt);
                printUsage();
                exit(EXIT_FAILURE);

            default:
                SWSS_LOG_ERROR("getopt_long failure");
                exit(EXIT_FAILURE);
        }
    }

    return options;
}