int main(int argc, char** argv) { if (argc < 2) { std::cerr << "USAGE: " << argv[0] << " <command> <params...>" << std::endl; dsn::service::repli_app::usage(); return -1; } std::string conf; char buf[4096]; int slen; # if defined(_WIN32) slen = ::GetModuleFileNameA(NULL, buf, sizeof(buf)); # else slen = readlink("/proc/self/exe", buf, sizeof(buf)); # endif if (slen != -1) { std::string dir = dsn::utils::filesystem::remove_file_name(buf); conf = dir + "/config.ini"; if (!dsn::utils::filesystem::file_exists(conf)) { std::cerr << "ERROR: config file not found: " << conf << std::endl; dsn::service::repli_app::usage(); return -1; } } dsn_core_init(); // register all possible service apps dsn::register_app< ::dsn::service::repli_app>("repli"); dsn::service::repli_app::set_args(argc - 1, argv + 1); // specify what services and tools will run in config file, then run dsn_run_config(conf.c_str(), false); while (!g_done) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return 0; }
int main(int argc, char** argv) { if (argc != 3) { std::cerr << "USGAE: " << argv[0] << " <config-file> <case-input>" << std::endl; std::cerr << " e.g.: " << argv[0] << " case-000.ini case-000.act" << std::endl; return -1; } dsn::replication::test::g_case_input = argv[2]; dsn_app_registration(); dsn_core_init(); // specify what services and tools will run in config file, then run dsn_run(argc - 1, argv, false); while (!dsn::replication::test::g_done) { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } ddebug("=== exiting ..."); dsn::replication::test::test_checker::instance().exit(); if (dsn::replication::test::g_fail) { #ifndef ENABLE_GCOV dsn_exit(-1); #endif return -1; } #ifndef ENABLE_GCOV dsn_exit(0); #endif return 0; }
bool run(const char* config_file, const char* config_arguments, bool sleep_after_init, std::string& app_list) { dsn_core_init(); ::dsn::task::set_tls_dsn_context(nullptr, nullptr, nullptr); dsn_all.engine_ready = false; dsn_all.config_completed = false; dsn_all.tool = nullptr; dsn_all.engine = &::dsn::service_engine::instance(); dsn_all.config.reset(new ::dsn::configuration()); dsn_all.memory = nullptr; dsn_all.magic = 0xdeadbeef; if (!dsn_all.config->load(config_file, config_arguments)) { printf("Fail to load config file %s\n", config_file); return false; } // pause when necessary if (dsn_all.config->get_value<bool>("core", "pause_on_start", false, "whether to pause at startup time for easier debugging")) { #if defined(_WIN32) printf("\nPause for debugging (pid = %d)...\n", static_cast<int>(::GetCurrentProcessId())); #else printf("\nPause for debugging (pid = %d)...\n", static_cast<int>(getpid())); #endif getchar(); } // regiser external app roles by loading all shared libraries // so all code and app factories are automatically registered dsn::service_spec::load_app_shared_libraries(dsn_all.config); for (int i = 0; i <= dsn_task_code_max(); i++) { dsn_all.task_specs.push_back(::dsn::task_spec::get(i)); } // initialize global specification from config file ::dsn::service_spec spec; spec.config = dsn_all.config; if (!spec.init()) { printf("error in config file %s, exit ...\n", config_file); return false; } dsn_all.config_completed = true; // setup data dir auto& data_dir = spec.data_dir; dassert(!dsn::utils::filesystem::file_exists(data_dir), "%s should not be a file.", data_dir.c_str()); if (!dsn::utils::filesystem::directory_exists(data_dir.c_str())) { if (!dsn::utils::filesystem::create_directory(data_dir)) { dassert(false, "Fail to create %s.", data_dir.c_str()); } } std::string cdir; if (!dsn::utils::filesystem::get_absolute_path(data_dir.c_str(), cdir)) { dassert(false, "Fail to get absolute path from %s.", data_dir.c_str()); } spec.data_dir = cdir; // setup coredump dir spec.dir_coredump = ::dsn::utils::filesystem::path_combine(cdir, "coredumps"); dsn::utils::filesystem::create_directory(spec.dir_coredump); ::dsn::utils::coredump::init(spec.dir_coredump.c_str()); // setup log dir spec.dir_log = ::dsn::utils::filesystem::path_combine(cdir, "logs"); dsn::utils::filesystem::create_directory(spec.dir_log); // init tools dsn_all.tool = ::dsn::utils::factory_store< ::dsn::tools::tool_app>::create(spec.tool.c_str(), ::dsn::PROVIDER_TYPE_MAIN, spec.tool.c_str()); dsn_all.tool->install(spec); // init app specs if (!spec.init_app_specs()) { printf("error in config file %s, exit ...\n", config_file); return false; } // init tool memory dsn_all.memory = ::dsn::utils::factory_store< ::dsn::memory_provider>::create( spec.tools_memory_factory_name.c_str(), ::dsn::PROVIDER_TYPE_MAIN); // prepare minimum necessary ::dsn::service_engine::fast_instance().init_before_toollets(spec); // init logging dsn_log_init(); // init toollets for (auto it = spec.toollets.begin(); it != spec.toollets.end(); ++it) { auto tlet = dsn::tools::internal_use_only::get_toollet(it->c_str(), ::dsn::PROVIDER_TYPE_MAIN); dassert(tlet, "toolet not found"); tlet->install(spec); } // init provider specific system inits dsn::tools::sys_init_before_app_created.execute(::dsn::service_engine::fast_instance().spec().config); // TODO: register sys_exit execution // init runtime ::dsn::service_engine::fast_instance().init_after_toollets(); dsn_all.engine_ready = true; // split app_name and app_index std::list<std::string> applistkvs; ::dsn::utils::split_args(app_list.c_str(), applistkvs, ';'); // init apps for (auto& sp : spec.app_specs) { if (!sp.run) continue; bool create_it = false; if (app_list == "") // create all apps { create_it = true; } else { for (auto &kv : applistkvs) { std::list<std::string> argskvs; ::dsn::utils::split_args(kv.c_str(), argskvs, '@'); if (std::string("apps.") + argskvs.front() == sp.config_section) { if (argskvs.size() < 2) create_it = true; else create_it = (std::stoi(argskvs.back()) == sp.index); break; } } } if (create_it) { ::dsn::service_engine::fast_instance().start_node(sp); } } if (::dsn::service_engine::fast_instance().get_all_nodes().size() == 0) { printf("no app are created, usually because \n" "app_name is not specified correctly, should be 'xxx' in [apps.xxx]\n" "or app_index (1-based) is greater than specified count in config file\n" ); exit(1); } // start cli if necessary if (dsn_all.config->get_value<bool>("core", "cli_local", true, "whether to enable local command line interface (cli)")) { ::dsn::command_manager::instance().start_local_cli(); } if (dsn_all.config->get_value<bool>("core", "cli_remote", true, "whether to enable remote command line interface (using dsn.cli)")) { ::dsn::command_manager::instance().start_remote_cli(); } // register local cli commands ::dsn::register_command("config-dump", "config-dump - dump configuration", "config-dump [to-this-config-file]", [](const std::vector<std::string>& args) { std::ostringstream oss; std::ofstream off; std::ostream* os = &oss; if (args.size() > 0) { off.open(args[0]); os = &off; oss << "config dump to file " << args[0] << std::endl; } dsn_all.config->dump(*os); return oss.str(); }); // invoke customized init after apps are created dsn::tools::sys_init_after_app_created.execute(::dsn::service_engine::fast_instance().spec().config); // start the tool dsn_all.tool->run(); // if (sleep_after_init) { while (true) { std::this_thread::sleep_for(std::chrono::hours(1)); } } // add this to allow mimic app call from this thread. memset((void*)&dsn::tls_dsn, 0, sizeof(dsn::tls_dsn)); return true; }