From 1a4ca831a4d20123ea3fc64a4b1b014f4365bc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Botond=20D=C3=A9nes?= Date: Fri, 19 Nov 2021 09:08:54 +0200 Subject: [PATCH 1/4] main: extract scylla specific code into scylla_main() main() now contains only generic setup and teardown code and it delegates to scylla_main(). In the next patches we want to wire in tool executables into the scylla one. This will require selecting the main to run at runtime. scylla_main() will be just one of those (the default). --- main.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/main.cc b/main.cc index 93ad0719b5..2fcc505ee9 100644 --- a/main.cc +++ b/main.cc @@ -399,7 +399,7 @@ sharded* the_database; sharded *the_stream_manager; } -int main(int ac, char** av) { +static int scylla_main(int ac, char** av) { // Allow core dumps. The would be disabled by default if // CAP_SYS_NICE was added to the binary, as is suggested by the // epoll backend. @@ -410,10 +410,6 @@ int main(int ac, char** av) { } try { - // early check to avoid triggering - if (!cpu_sanity()) { - _exit(71); - } runtime::init_uptime(); std::setvbuf(stdout, nullptr, _IOLBF, 1000); app_template::config app_cfg; @@ -1457,3 +1453,12 @@ int main(int ac, char** av) { return 7; // 1 has a special meaning for upstart } } + +int main(int ac, char** av) { + // early check to avoid triggering + if (!cpu_sanity()) { + _exit(71); + } + + return scylla_main(ac, av); +} From 972d789a274b043fee6fcbfd05da73482b1a99d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Botond=20D=C3=A9nes?= Date: Fri, 19 Nov 2021 10:45:25 +0200 Subject: [PATCH 2/4] main: add skeleton switching code on argv[1] To prepare for the scylla executable hosting more than one apps, switching between them using argv[1]. This is consistent with how most modern multi-app/multi-command programs work, one prominent example being git. For now only one app is present: scylla itself, called "server". If argv[1] is missing or unrecognized, this is what is used as the default for backward-compatibility. The scylla app also gets a description, which explains that scylla hosts multiple apps and lists all the available ones. --- main.cc | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/main.cc b/main.cc index 2fcc505ee9..2e0df46f3c 100644 --- a/main.cc +++ b/main.cc @@ -414,6 +414,18 @@ static int scylla_main(int ac, char** av) { std::setvbuf(stdout, nullptr, _IOLBF, 1000); app_template::config app_cfg; app_cfg.name = "Scylla"; + app_cfg.description = +R"(scylla - NoSQL data store using the seastar framework, compatible with Apache Cassandra + +For more information, see https://github.com/scylladb/scylla. + +The scylla executable hosts multiple apps: +* server (default) - the scylla server itself. + +Usage: scylla {app_name} [...] + +For more information about individual apps, run: scylla {app_name} --help +)"; app_cfg.default_task_quota = 500us; app_cfg.auto_handle_sigint_sigterm = false; app_cfg.max_networking_aio_io_control_blocks = 50000; @@ -1460,5 +1472,29 @@ int main(int ac, char** av) { _exit(71); } - return scylla_main(ac, av); + std::function main_func; + + std::string exec_name; + if (ac >= 2) { + exec_name = av[1]; + } + + bool recognized = true; + if (exec_name == "server") { + main_func = scylla_main; + } else { + fmt::print("Unrecognized or missing app name (argv[1]={}), assuming server\n", exec_name); + main_func = scylla_main; + recognized = false; + } + + if (recognized) { + // shift args to consume the recognized app name + --ac; + for (int i = 1; i < ac; ++i) { + std::swap(av[i], av[i + 1]); + } + } + + return main_func(ac, av); } From 0761113d8b633aad9e77cce3f7eb9431117e44d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Botond=20D=C3=A9nes?= Date: Fri, 19 Nov 2021 09:31:59 +0200 Subject: [PATCH 3/4] tools: prepare for inclusion in scylla's main Rename actual main to `${tool_name}_main` and have a proxy main call it. In the next patch we will get rid of these proxy mains and the tool mains will be invoked from scylla's main, if the `argv[0]` matches their name. The main functions are included in a new `tools/entry_point.hh` header. --- tools/entry_point.hh | 27 +++++++++++++++++++++++++++ tools/scylla-sstable.cc | 10 +++++++++- tools/scylla-types.cc | 10 +++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tools/entry_point.hh diff --git a/tools/entry_point.hh b/tools/entry_point.hh new file mode 100644 index 0000000000..3ecd5c48a5 --- /dev/null +++ b/tools/entry_point.hh @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021-present ScyllaDB + */ + +/* + * This file is part of Scylla. + * + * Scylla is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Scylla is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Scylla. If not, see . + */ + +namespace tools { + +int scylla_types_main(int argc, char** argv); +int scylla_sstable_main(int argc, char** argv); + +} // namespace tools diff --git a/tools/scylla-sstable.cc b/tools/scylla-sstable.cc index 72af395210..6b9e6e07b0 100644 --- a/tools/scylla-sstable.cc +++ b/tools/scylla-sstable.cc @@ -1110,7 +1110,9 @@ const std::vector operations{ } // anonymous namespace -int main(int argc, char** argv) { +namespace tools { + +int scylla_sstable_main(int argc, char** argv) { app_template::config app_cfg; app_cfg.name = app_name; @@ -1243,3 +1245,9 @@ $ scylla-sstable --validate /path/to/md-123456-big-Data.db /path/to/md-123457-bi }); }); } + +} // namespace tools + +int main(int argc, char** argv) { + return tools::scylla_sstable_main(argc, argv); +} diff --git a/tools/scylla-types.cc b/tools/scylla-types.cc index c06e304500..f87f5158b8 100644 --- a/tools/scylla-types.cc +++ b/tools/scylla-types.cc @@ -167,7 +167,9 @@ const std::vector action_handlers = { } -int main(int argc, char** argv) { +namespace tools { + +int scylla_types_main(int argc, char** argv) { namespace bpo = boost::program_options; app_template::config app_cfg; @@ -254,3 +256,9 @@ $ scylla-types --print --prefix-compound -t TimeUUIDType -t Int32Type 0010d00819 return make_ready_future<>(); }); } + +} // namespace tools + +int main(int argc, char** argv) { + return tools::scylla_types_main(argc, argv); +} From bb0874b28b4784f2c05a4eca470fe7e9e01c15d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Botond=20D=C3=A9nes?= Date: Fri, 19 Nov 2021 10:51:05 +0200 Subject: [PATCH 4/4] main,tools,configure.py: fold tools into scylla exec The infrastructure is now in place. Remove the proxy main of the tools, and add appropriate `else if` statements to the executable switch in main.cc. Also remove the tool applications from the `apps` list and add their respective sources as dependencies to the main scylla executable. With this, we now have all tool executables living inside the scylla main one. --- configure.py | 9 +++------ main.cc | 7 +++++++ tools/scylla-sstable.cc | 4 ---- tools/scylla-types.cc | 4 ---- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/configure.py b/configure.py index eb89f51f4a..928fb07983 100755 --- a/configure.py +++ b/configure.py @@ -569,8 +569,6 @@ raft_tests = set([ apps = set([ 'scylla', 'test/tools/cql_repl', - 'tools/scylla-types', - 'tools/scylla-sstable', ]) tests = scylla_tests | perf_tests | raft_tests @@ -1147,12 +1145,11 @@ scylla_tests_dependencies = scylla_core + idls + scylla_tests_generic_dependenci scylla_raft_dependencies = scylla_raft_core + ['utils/uuid.cc'] +scylla_tools = ['tools/scylla-types.cc', 'tools/scylla-sstable.cc', 'tools/schema_loader.cc'] + deps = { - 'scylla': idls + ['main.cc'] + scylla_core + api + alternator + redis, + 'scylla': idls + ['main.cc'] + scylla_core + api + alternator + redis + scylla_tools, 'test/tools/cql_repl': idls + ['test/tools/cql_repl.cc'] + scylla_core + scylla_tests_generic_dependencies, - #FIXME: we don't need all of scylla_core here, only the types module, need to modularize scylla_core. - 'tools/scylla-types': idls + ['tools/scylla-types.cc'] + scylla_core, - 'tools/scylla-sstable': idls + ['tools/scylla-sstable.cc', 'tools/schema_loader.cc'] + scylla_core, } pure_boost_tests = set([ diff --git a/main.cc b/main.cc index 2e0df46f3c..229e46774a 100644 --- a/main.cc +++ b/main.cc @@ -96,6 +96,7 @@ #include "service/storage_proxy.hh" #include "alternator/controller.hh" #include "alternator/ttl.hh" +#include "tools/entry_point.hh" #include "service/raft/raft_group_registry.hh" @@ -421,6 +422,8 @@ For more information, see https://github.com/scylladb/scylla. The scylla executable hosts multiple apps: * server (default) - the scylla server itself. +* types - a command-line tool to examine values belonging to scylla types. +* sstable - a multifunctional command-line tool to examine the content of sstables. Usage: scylla {app_name} [...] @@ -1482,6 +1485,10 @@ int main(int ac, char** av) { bool recognized = true; if (exec_name == "server") { main_func = scylla_main; + } else if (exec_name == "types") { + main_func = tools::scylla_types_main; + } else if (exec_name == "sstable") { + main_func = tools::scylla_sstable_main; } else { fmt::print("Unrecognized or missing app name (argv[1]={}), assuming server\n", exec_name); main_func = scylla_main; diff --git a/tools/scylla-sstable.cc b/tools/scylla-sstable.cc index 6b9e6e07b0..68ab8427cc 100644 --- a/tools/scylla-sstable.cc +++ b/tools/scylla-sstable.cc @@ -1247,7 +1247,3 @@ $ scylla-sstable --validate /path/to/md-123456-big-Data.db /path/to/md-123457-bi } } // namespace tools - -int main(int argc, char** argv) { - return tools::scylla_sstable_main(argc, argv); -} diff --git a/tools/scylla-types.cc b/tools/scylla-types.cc index f87f5158b8..f3a199dcf8 100644 --- a/tools/scylla-types.cc +++ b/tools/scylla-types.cc @@ -258,7 +258,3 @@ $ scylla-types --print --prefix-compound -t TimeUUIDType -t Int32Type 0010d00819 } } // namespace tools - -int main(int argc, char** argv) { - return tools::scylla_types_main(argc, argv); -}