Пример #1
1
int
main(int argc, char* argv[])
{
    int rv = 0;

    auto options = handleCmdLine(argc, argv);
    handleProfileMap(options.profileMapFile);
    handlePortMap(options.portMapFile);

    sai_api_initialize(0, &test_services);
    sai_api_query(SAI_API_SWITCH, (void**)&sai_switch_api);

    constexpr std::uint32_t attrSz = 6;

    sai_attribute_t attr[attrSz];
    std::memset(attr, '\0', sizeof(attr));

    attr[0].id = SAI_SWITCH_ATTR_INIT_SWITCH;
    attr[0].value.booldata = true;

    attr[1].id = SAI_SWITCH_ATTR_SWITCH_STATE_CHANGE_NOTIFY;
    attr[1].value.ptr = reinterpret_cast<sai_pointer_t>(&on_switch_state_change);

    attr[2].id = SAI_SWITCH_ATTR_SHUTDOWN_REQUEST_NOTIFY;
    attr[2].value.ptr = reinterpret_cast<sai_pointer_t>(&on_shutdown_request);

    attr[3].id = SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY;
    attr[3].value.ptr = reinterpret_cast<sai_pointer_t>(&on_fdb_event);

    attr[4].id = SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY;
    attr[4].value.ptr = reinterpret_cast<sai_pointer_t>(&on_port_state_change);

    attr[5].id = SAI_SWITCH_ATTR_PACKET_EVENT_NOTIFY;
    attr[5].value.ptr = reinterpret_cast<sai_pointer_t>(&on_packet_event);

    sai_status_t status = sai_switch_api->create_switch(&gSwitchId, attrSz, attr);
    if (status != SAI_STATUS_SUCCESS)
    {
        exit(EXIT_FAILURE);
    }

    handleInitScript(options.initScript);

#ifdef BRCMSAI
    std::thread bcm_diag_shell_thread = std::thread(sai_diag_shell);
    bcm_diag_shell_thread.detach();
#endif

    start_sai_thrift_rpc_server(SWITCH_SAI_THRIFT_RPC_SERVER_PORT);

    sai_log_set(SAI_API_SWITCH, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_BRIDGE, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_FDB, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_PORT, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_VLAN, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_ROUTE, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_VIRTUAL_ROUTER, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_ROUTER_INTERFACE, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_NEXT_HOP, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_NEXT_HOP_GROUP, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_NEIGHBOR, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_ACL, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_MIRROR, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_LAG, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_BUFFER, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_POLICER, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_WRED, SAI_LOG_LEVEL_NOTICE);
    sai_log_set(SAI_API_QOS_MAP, SAI_LOG_LEVEL_NOTICE);

    while (1) pause();

    return rv;
}
Пример #2
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);
#ifdef SAITHRIFT
    if (options.portMapFile.size() > 0)
    {
        handlePortMap(options.portMapFile);
    }
#endif // SAITHRIFT

    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");

    g_veryFirstRun = isVeryFirstRun();

    if (options.startType == SAI_WARM_BOOT)
    {
        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.startType = SAI_COLD_BOOT;
        }
    }

    if (options.startType == SAI_WARM_BOOT && 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.startType = SAI_COLD_BOOT;
    }

    gProfileMap[SAI_KEY_BOOT_TYPE] = std::to_string(options.startType);

    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, "", "", &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 */

#ifdef SAITHRIFT
    if (options.run_rpc_server)
    {
        start_sai_thrift_rpc_server(SWITCH_SAI_THRIFT_RPC_SERVER_PORT);
        SWSS_LOG_NOTICE("rpcserver started");
    }
#endif // SAITHRIFT

    SWSS_LOG_NOTICE("syncd started");

    bool warmRestartHint = false;

    try
    {
        onSyncdStart(options.startType == SAI_WARM_BOOT);

        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;
}