saisdkdump/saisdkdump.cpp (140 lines of code) (raw):

#include <iostream> #include <sstream> #include <ctime> #include <sstream> #include <unistd.h> #include <getopt.h> #include "swss/logger.h" extern "C" { #include <sai.h> } // TODO split to multiple cpp std::string sai_profile = "/tmp/sai.profile"; void print_usage() { SWSS_LOG_ENTER(); std::cerr << "Following SAI dump options can be specified:" << std::endl; std::cerr << "-------------------------------------------" << std::endl; std::cerr << "--dump_file -f Full path for dump file" << std::endl; std::cerr << "--profile -p Full path to SAI profile file [ default is " << sai_profile << " ]" << std::endl; std::cerr << "--help -h usage" << std::endl; } __attribute__((__noreturn__)) void exit_with_sai_failure(const char *msg, sai_status_t status) { SWSS_LOG_ENTER(); if (msg) { std::cerr << msg << " rc=" << status << std::endl; } SWSS_LOG_ERROR("saisdkdump exited with SAI rc: 0x%x, msg: %s .", status, (msg != NULL ? msg : "")); exit(EXIT_FAILURE); } const char* profile_get_value( _In_ sai_switch_profile_id_t profile_id, _In_ const char* variable) { SWSS_LOG_ENTER(); return sai_profile.c_str(); } int profile_get_next_value( _In_ sai_switch_profile_id_t profile_id, _Out_ const char** variable, _Out_ const char** value) { SWSS_LOG_ENTER(); return -1; } sai_service_method_table_t test_services = { profile_get_value, profile_get_next_value }; int main(int argc, char **argv) { swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_NOTICE); SWSS_LOG_ENTER(); static struct option longOptions[] = { { "help", no_argument, 0, 'h' }, { "dump_file", required_argument, 0, 'f' }, { "profile", required_argument, 0, 'p' } }; bool fileSpecified = false; std::string fileName; int option_index = 0; int c = 0; while ((c = getopt_long(argc, argv, "hf:p:", longOptions, &option_index)) != -1) { switch (c) { case 'f': if (optarg != NULL) { fileName = std::string(optarg); fileSpecified = true; } break; case 'p': if (optarg != NULL) { sai_profile = std::string(optarg); } break; case 'h': print_usage(); break; default: SWSS_LOG_ERROR("getopt failure"); exit(EXIT_FAILURE); } } if (!fileSpecified) { std::ostringstream strStream; time_t t = time(NULL); struct tm local_tm; struct tm *now = localtime_r(&t, &local_tm); strStream << "/tmp/saisdkdump_" << now->tm_mday << "_" << now->tm_mon + 1 << "_" << now->tm_year + 1900 << "_" << now->tm_hour << "_" << now->tm_min << "_" << now->tm_sec; fileName = strStream.str(); SWSS_LOG_INFO("The dump file is not specified, generated \"%s\" file name", fileName.c_str()); } sai_status_t status = sai_api_initialize(0, (sai_service_method_table_t*)&test_services); if (status != SAI_STATUS_SUCCESS) { exit_with_sai_failure("Failed to initialize SAI api", status); } sai_switch_api_t* switch_api; status = sai_api_query(SAI_API_SWITCH, (void**) &switch_api); if (status != SAI_STATUS_SUCCESS) { exit_with_sai_failure("Failed to query switch api", status); } sai_object_id_t switch_id; const uint32_t AttributesCount = 2; sai_attribute_t attrs[AttributesCount]; attrs[0].id = SAI_SWITCH_ATTR_INIT_SWITCH; attrs[0].value.booldata = false; attrs[1].id = SAI_SWITCH_ATTR_UNINIT_DATA_PLANE_ON_REMOVAL; attrs[1].value.booldata = false; status = switch_api->create_switch(&switch_id, AttributesCount, attrs); if (status != SAI_STATUS_SUCCESS) { exit_with_sai_failure("Failed to create a switch", status); } status = sai_dbg_generate_dump(fileName.c_str()); if (status != SAI_STATUS_SUCCESS) { exit_with_sai_failure("Failed to generate SAI dump", status); } SWSS_LOG_NOTICE("The SAI dump is generated to %s .", fileName.c_str()); std::cout << "The SAI dump is generated to " << fileName << std::endl; status = switch_api->remove_switch(switch_id); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("remove switch 0x%lx failed: 0x%x", switch_id, status); } status = sai_api_uninitialize(); if (status != SAI_STATUS_SUCCESS) { exit_with_sai_failure("SAI api uninitialize failed", status); } return EXIT_SUCCESS; }