diff --git a/syncd/CommandLineOptions.cpp b/syncd/CommandLineOptions.cpp index 3ad68b886..493af0a87 100644 --- a/syncd/CommandLineOptions.cpp +++ b/syncd/CommandLineOptions.cpp @@ -94,6 +94,9 @@ sai_start_type_t CommandLineOptions::startTypeStringToStartType( if (startType == STRING_SAI_START_TYPE_FASTFAST_BOOT) return SAI_START_TYPE_FASTFAST_BOOT; + if (startType == STRING_SAI_START_TYPE_EXPRESS_BOOT) + return SAI_START_TYPE_EXPRESS_BOOT; + if (startType == STRING_SAI_START_TYPE_UNKNOWN) return SAI_START_TYPE_UNKNOWN; @@ -121,6 +124,9 @@ std::string CommandLineOptions::startTypeToString( case SAI_START_TYPE_FASTFAST_BOOT: return STRING_SAI_START_TYPE_FASTFAST_BOOT; + case SAI_START_TYPE_EXPRESS_BOOT: + return STRING_SAI_START_TYPE_EXPRESS_BOOT; + case SAI_START_TYPE_UNKNOWN: return STRING_SAI_START_TYPE_UNKNOWN; diff --git a/syncd/CommandLineOptions.h b/syncd/CommandLineOptions.h index 26adc5ec6..f3243e747 100644 --- a/syncd/CommandLineOptions.h +++ b/syncd/CommandLineOptions.h @@ -10,6 +10,7 @@ #define STRING_SAI_START_TYPE_WARM_BOOT "warm" #define STRING_SAI_START_TYPE_FAST_BOOT "fast" #define STRING_SAI_START_TYPE_FASTFAST_BOOT "fastfast" +#define STRING_SAI_START_TYPE_EXPRESS_BOOT "express" #define STRING_SAI_START_TYPE_UNKNOWN "unknown" namespace syncd @@ -28,6 +29,12 @@ namespace syncd */ SAI_START_TYPE_FASTFAST_BOOT = 3, + /** + * A special type of boot used by Cisco platforms to start in 'express' + * boot mode + */ + SAI_START_TYPE_EXPRESS_BOOT = 4, + /** * Set at last, just for error purpose. */ diff --git a/syncd/CommandLineOptionsParser.cpp b/syncd/CommandLineOptionsParser.cpp index 620e5383f..a7c034d73 100644 --- a/syncd/CommandLineOptionsParser.cpp +++ b/syncd/CommandLineOptionsParser.cpp @@ -166,7 +166,7 @@ void CommandLineOptionsParser::printUsage() std::cout << " -p --profile profile" << std::endl; std::cout << " Provide profile map file" << std::endl; std::cout << " -t --startType type" << std::endl; - std::cout << " Specify start type (cold|warm|fast|fastfast)" << std::endl; + std::cout << " Specify start type (cold|warm|fast|fastfast|express)" << std::endl; std::cout << " -u --useTempView" << std::endl; std::cout << " Use temporary view between init and apply" << std::endl; std::cout << " -S --disableExitSleep" << std::endl; diff --git a/syncd/RequestShutdownCommandLineOptions.cpp b/syncd/RequestShutdownCommandLineOptions.cpp index abfb0ef78..2b303a4d1 100644 --- a/syncd/RequestShutdownCommandLineOptions.cpp +++ b/syncd/RequestShutdownCommandLineOptions.cpp @@ -37,7 +37,9 @@ void RequestShutdownCommandLineOptions::setRestartType( #define STRING_RESTART_COLD "COLD" #define STRING_RESTART_WARM "WARM" #define STRING_RESTART_FAST "FAST" +#define STRING_RESTART_EXPRESS "EXPRESS" #define STRING_RESTART_PRE_SHUTDOWN "PRE-SHUTDOWN" +#define STRING_RESTART_PRE_EXPRESS_SHUTDOWN "PRE-EXPRESS-SHUTDOWN" syncd_restart_type_t RequestShutdownCommandLineOptions::stringToRestartType( _In_ const std::string& restartType) @@ -53,9 +55,15 @@ syncd_restart_type_t RequestShutdownCommandLineOptions::stringToRestartType( if (restartType == STRING_RESTART_FAST) return SYNCD_RESTART_TYPE_FAST; + if (restartType == STRING_RESTART_EXPRESS) + return SYNCD_RESTART_TYPE_EXPRESS; + if (restartType == STRING_RESTART_PRE_SHUTDOWN) return SYNCD_RESTART_TYPE_PRE_SHUTDOWN; + if (restartType == STRING_RESTART_PRE_EXPRESS_SHUTDOWN) + return SYNCD_RESTART_TYPE_PRE_EXPRESS_SHUTDOWN; + SWSS_LOG_WARN("unknown restart type '%s' returning COLD", restartType.c_str()); return SYNCD_RESTART_TYPE_COLD; @@ -77,9 +85,15 @@ std::string RequestShutdownCommandLineOptions::restartTypeToString( case SYNCD_RESTART_TYPE_FAST: return STRING_RESTART_FAST; + case SYNCD_RESTART_TYPE_EXPRESS: + return STRING_RESTART_EXPRESS; + case SYNCD_RESTART_TYPE_PRE_SHUTDOWN: return STRING_RESTART_PRE_SHUTDOWN; + case SYNCD_RESTART_TYPE_PRE_EXPRESS_SHUTDOWN: + return STRING_RESTART_PRE_EXPRESS_SHUTDOWN; + default: SWSS_LOG_WARN("unknown restart type '%d' returning COLD", restartType); diff --git a/syncd/RequestShutdownCommandLineOptions.h b/syncd/RequestShutdownCommandLineOptions.h index 781f7b8d5..4fc9d030c 100644 --- a/syncd/RequestShutdownCommandLineOptions.h +++ b/syncd/RequestShutdownCommandLineOptions.h @@ -16,6 +16,10 @@ namespace syncd SYNCD_RESTART_TYPE_PRE_SHUTDOWN, + SYNCD_RESTART_TYPE_EXPRESS, + + SYNCD_RESTART_TYPE_PRE_EXPRESS_SHUTDOWN, + } syncd_restart_type_t; class RequestShutdownCommandLineOptions diff --git a/syncd/RequestShutdownCommandLineOptionsParser.cpp b/syncd/RequestShutdownCommandLineOptionsParser.cpp index 2bcf9d037..417b90524 100644 --- a/syncd/RequestShutdownCommandLineOptionsParser.cpp +++ b/syncd/RequestShutdownCommandLineOptionsParser.cpp @@ -23,7 +23,9 @@ std::shared_ptr RequestShutdownCommandLineOpt { "cold", no_argument, 0, 'c' }, { "warm", no_argument, 0, 'w' }, { "fast", no_argument, 0, 'f' }, + { "express", no_argument, 0, 'e' }, { "pre", no_argument, 0, 'p' }, // Requesting pre shutdown + { "pxe", no_argument, 0, 'z' }, // Requesting pre-express shutdown { "help", no_argument, 0, 'h' }, { "globalContext", required_argument, 0, 'g' }, @@ -37,7 +39,7 @@ std::shared_ptr RequestShutdownCommandLineOpt { int option_index = 0; - int c = getopt_long(argc, argv, "cwfpg:x:h", long_options, &option_index); + int c = getopt_long(argc, argv, "cwfepzg:x:h", long_options, &option_index); if (c == -1) break; @@ -59,11 +61,21 @@ std::shared_ptr RequestShutdownCommandLineOpt optionSpecified = true; break; + case 'e': + options->setRestartType(SYNCD_RESTART_TYPE_EXPRESS); + optionSpecified = true; + break; + case 'p': options->setRestartType(SYNCD_RESTART_TYPE_PRE_SHUTDOWN); optionSpecified = true; break; + case 'z': + options->setRestartType(SYNCD_RESTART_TYPE_PRE_EXPRESS_SHUTDOWN); + optionSpecified = true; + break; + case 'g': options->m_globalContext = (uint32_t)std::stoul(optarg); break; @@ -98,7 +110,7 @@ void RequestShutdownCommandLineOptionsParser::printUsage() { SWSS_LOG_ENTER(); - std::cout << "Usage: syncd_request_shutdown [-w] [--warm] [-p] [--pre] [-c] [--cold] [-f] [--fast] [-g idx] [-x contextConfig] [-h] [--help]" << std::endl; + std::cout << "Usage: syncd_request_shutdown [-w] [--warm] [-p] [--pre] [-c] [--cold] [-f] [--fast] [-e] [--express] [-z --pxe] [-g idx] [-x contextConfig] [-h] [--help]" << std::endl; std::cerr << std::endl; @@ -112,6 +124,10 @@ void RequestShutdownCommandLineOptionsParser::printUsage() std::cerr << " For cold restart" << std::endl; std::cerr << " -f --fast" << std::endl; std::cerr << " For fast restart" << std::endl; + std::cerr << " -e --express" << std::endl; + std::cerr << " For express restart" << std::endl; + std::cerr << " -z --pxe" << std::endl; + std::cerr << " For express pre-shutdown" << std::endl; std::cout << " -g --globalContext " << std::endl; std::cout << " Global context index to load from context config file" << std::endl; std::cout << " -x --contextConfig" << std::endl; diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index a54384e82..8adb1404e 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -217,10 +217,11 @@ Syncd::~Syncd() void Syncd::performStartupLogic() { SWSS_LOG_ENTER(); + // ignore warm logic here if syncd starts in fast-boot, express-boot or Mellanox fastfast boot mode - // ignore warm logic here if syncd starts in fast-boot or Mellanox fastfast boot mode - - if (m_isWarmStart && m_commandLineOptions->m_startType != SAI_START_TYPE_FASTFAST_BOOT && m_commandLineOptions->m_startType != SAI_START_TYPE_FAST_BOOT) + if (m_isWarmStart && m_commandLineOptions->m_startType != SAI_START_TYPE_FASTFAST_BOOT && + m_commandLineOptions->m_startType != SAI_START_TYPE_EXPRESS_BOOT && + m_commandLineOptions->m_startType != SAI_START_TYPE_FAST_BOOT) { SWSS_LOG_WARN("override command line startType=%s via SAI_START_TYPE_WARM_BOOT", CommandLineOptions::startTypeToString(m_commandLineOptions->m_startType).c_str()); @@ -3675,9 +3676,10 @@ sai_status_t Syncd::processNotifySyncd( m_asicInitViewMode = false; - if (m_commandLineOptions->m_startType == SAI_START_TYPE_FASTFAST_BOOT) + if (m_commandLineOptions->m_startType == SAI_START_TYPE_FASTFAST_BOOT || + m_commandLineOptions->m_startType == SAI_START_TYPE_EXPRESS_BOOT) { - // fastfast boot configuration end + // express/fastfast boot configuration end status = onApplyViewInFastFastBoot(); } @@ -4716,6 +4718,39 @@ sai_status_t Syncd::setRestartWarmOnAllSwitches( return result; } +sai_status_t Syncd::setFastAPIEnableOnAllSwitches() +{ + SWSS_LOG_ENTER(); + + sai_status_t result = SAI_STATUS_SUCCESS; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_FAST_API_ENABLE; + attr.value.booldata = true; + + for (auto& sw: m_switches) + { + auto rid = sw.second->getRid(); + + auto strRid = sai_serialize_object_id(rid); + + auto status = m_vendorSai->set(SAI_OBJECT_TYPE_SWITCH, rid, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to set SAI_SWITCH_ATTR_PRE_SHUTDOWN=true: %s:%s", + strRid.c_str(), + sai_serialize_status(status).c_str()); + + result = status; + break; + } + } + + return result; +} + sai_status_t Syncd::setPreShutdownOnAllSwitches() { SWSS_LOG_ENTER(); @@ -4933,7 +4968,7 @@ void Syncd::run() shutdownType = handleRestartQuery(*m_restartQuery); - if (shutdownType != SYNCD_RESTART_TYPE_PRE_SHUTDOWN) + if (shutdownType != SYNCD_RESTART_TYPE_PRE_SHUTDOWN && shutdownType != SYNCD_RESTART_TYPE_PRE_EXPRESS_SHUTDOWN) { // break out the event handling loop to shutdown syncd runMainLoop = false; @@ -4943,7 +4978,7 @@ void Syncd::run() // Handle switch pre-shutdown and wait for the final shutdown // event - SWSS_LOG_TIMER("warm pre-shutdown"); + SWSS_LOG_TIMER("%s pre-shutdown", (shutdownType == SYNCD_RESTART_TYPE_PRE_SHUTDOWN) ? "warm" : "express"); m_manager->removeAllCounters(); @@ -4960,6 +4995,23 @@ void Syncd::run() continue; } + if (shutdownType == SYNCD_RESTART_TYPE_PRE_EXPRESS_SHUTDOWN) + { + SWSS_LOG_NOTICE("express boot, enable fast API pre-shutdown"); + status = setFastAPIEnableOnAllSwitches(); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to set SAI_SWITCH_ATTR_FAST_API_ENABLE=true: %s for express pre-shutdown. Fall back to cold restart", + sai_serialize_status(status).c_str()); + + shutdownType = SYNCD_RESTART_TYPE_COLD; + + warmRestartTable.setFlagFailed(); + continue; + } + } + status = setPreShutdownOnAllSwitches(); if (status == SAI_STATUS_SUCCESS) @@ -5052,7 +5104,7 @@ void Syncd::run() } } - if (shutdownType == SYNCD_RESTART_TYPE_FAST || shutdownType == SYNCD_RESTART_TYPE_WARM) + if (shutdownType == SYNCD_RESTART_TYPE_FAST || shutdownType == SYNCD_RESTART_TYPE_WARM || shutdownType == SYNCD_RESTART_TYPE_EXPRESS) { setUninitDataPlaneOnRemovalOnAllSwitches(); } @@ -5066,7 +5118,7 @@ void Syncd::run() // Stop notification thread after removing switch m_processor->stopNotificationsProcessingThread(); - if (shutdownType == SYNCD_RESTART_TYPE_WARM) + if (shutdownType == SYNCD_RESTART_TYPE_WARM || shutdownType == SYNCD_RESTART_TYPE_EXPRESS) { warmRestartTable.setWarmShutdown(status == SAI_STATUS_SUCCESS); } diff --git a/syncd/Syncd.h b/syncd/Syncd.h index b7622bf01..a19fcd972 100644 --- a/syncd/Syncd.h +++ b/syncd/Syncd.h @@ -103,6 +103,8 @@ namespace syncd sai_status_t setRestartWarmOnAllSwitches( _In_ bool flag); + sai_status_t setFastAPIEnableOnAllSwitches(); + sai_status_t setPreShutdownOnAllSwitches(); sai_status_t setUninitDataPlaneOnRemovalOnAllSwitches(); diff --git a/syncd/scripts/syncd_init_common.sh b/syncd/scripts/syncd_init_common.sh index baad55198..c538c23e8 100644 --- a/syncd/scripts/syncd_init_common.sh +++ b/syncd/scripts/syncd_init_common.sh @@ -50,6 +50,11 @@ case "$(cat /proc/cmdline)" in FASTFAST_REBOOT='yes' fi ;; + *SONIC_BOOT_TYPE=express*) + if [ -e /var/warmboot/warm-starting ]; then + EXPRESS_REBOOT='yes' + fi + ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists SYSTEM_FAST_REBOOT=`sonic-db-cli STATE_DB hget "FAST_RESTART_ENABLE_TABLE|system" enable` @@ -89,6 +94,8 @@ function set_start_type() CMD_ARGS+=" -t fast" elif [ x"$FASTFAST_REBOOT" == x"yes" ]; then CMD_ARGS+=" -t fastfast" + elif [ x"$EXPRESS_REBOOT" == x"yes" ]; then + CMD_ARGS+=" -t express" fi } diff --git a/unittest/syncd/TestCommandLineOptions.cpp b/unittest/syncd/TestCommandLineOptions.cpp index a6d04676d..508418767 100644 --- a/unittest/syncd/TestCommandLineOptions.cpp +++ b/unittest/syncd/TestCommandLineOptions.cpp @@ -13,7 +13,7 @@ R"(Usage: syncd [-d] [-p profile] [-t type] [-u] [-S] [-U] [-C] [-s] [-z mode] [ -p --profile profile Provide profile map file -t --startType type - Specify start type (cold|warm|fast|fastfast) + Specify start type (cold|warm|fast|fastfast|express) -u --useTempView Use temporary view between init and apply -S --disableExitSleep