From b0776fd0f8086ab272075262006358660a915024 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sun, 10 May 2020 00:05:52 -0700 Subject: [PATCH] ircd::m::homeserver: Preliminary bootstrap from event vector. --- construct/construct.cc | 3 ++ include/ircd/m/homeserver.h | 6 +++ matrix/homeserver.cc | 75 ++++++++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/construct/construct.cc b/construct/construct.cc index 4ff4f39aa..fd3a9ed9b 100644 --- a/construct/construct.cc +++ b/construct/construct.cc @@ -41,6 +41,7 @@ bool soft_assert; bool nomatrix; bool matrix {true}; // matrix server by default. bool defaults; +const char *bootstrap; lgetopt opts[] { @@ -70,6 +71,7 @@ lgetopt opts[] { "nomatrix", &nomatrix, lgetopt::BOOL, "Prevent loading the matrix application module" }, { "matrix", &matrix, lgetopt::BOOL, "Allow loading the matrix application module" }, { "defaults", &defaults, lgetopt::BOOL, "Use configuration defaults without database load for this execution" }, + { "bootstrap", &bootstrap, lgetopt::STRING, "Bootstrap fresh database from event vector" }, { nullptr, nullptr, lgetopt::STRING, nullptr }, }; @@ -203,6 +205,7 @@ noexcept try struct ircd::m::homeserver::opts opts; opts.origin = origin; opts.server_name = server_name; + opts.bootstrap_vector_path = bootstrap; const ircd::custom_ptr homeserver { // 6.1 diff --git a/include/ircd/m/homeserver.h b/include/ircd/m/homeserver.h index 72ea5f359..b41c34aaf 100644 --- a/include/ircd/m/homeserver.h +++ b/include/ircd/m/homeserver.h @@ -143,4 +143,10 @@ struct ircd::m::homeserver::opts /// be the origin itself; otherwise, SRV/well-known indirection is required /// to reach the servername starting from the origin. string_view server_name; + + /// When instantiating a homeserver with a fresh database, the file found + /// at this path can supplement for any initial bootstrapping. This vector + /// may contain additional events as well; the server will continue its + /// operation after having processed these events. + string_view bootstrap_vector_path; }; diff --git a/matrix/homeserver.cc b/matrix/homeserver.cc index 06e10a683..71082d574 100644 --- a/matrix/homeserver.cc +++ b/matrix/homeserver.cc @@ -10,6 +10,7 @@ namespace ircd::m { + static void bootstrap_event_vector(homeserver &); static void bootstrap(homeserver &); static void signon(homeserver &), signoff(homeserver &) noexcept; @@ -260,7 +261,12 @@ try }}; if(dbs::events && sequence(*dbs::events) == 0) - bootstrap(*this); + { + if(opts->bootstrap_vector_path) + bootstrap_event_vector(*this); + else + bootstrap(*this); + } if(key && !key->verify_keys.empty()) m::keys::cache::set(key->verify_keys); @@ -830,9 +836,74 @@ catch(...) } // -// bootstrap +// bootstrap_vector // +void +ircd::m::bootstrap_event_vector(homeserver &homeserver) +try +{ + const string_view &path + { + homeserver.opts->bootstrap_vector_path + }; + + fs::fd::opts fileopts(std::ios::in); + fileopts.sequential = true; + const fs::fd file + { + path, fileopts + }; + + log::notice + { + log, "Bootstrapping database from event vector @ `%s'", + path, + }; + + const unique_mutable_buffer mb + { + 512_KiB + }; + + size_t events(0); + const_buffer buf; + fs::read_opts ropts; do + { + buf = read(file, mb, ropts); + + + ropts.offset += size(buf); + } + while(!!buf); + + log::info + { + log, "Bootstrapped %zu events in %zu bytes from `%s'", + events, + ropts.offset, + path, + }; +} +catch(const std::exception &e) +{ + log::logf + { + log, log::level::CRITICAL, + "Failed to start server '%s' on network '%s'", + server_name(homeserver), + origin(homeserver), + e.what() + }; + + throw ircd::error + { + "bootstrap %s error :%s", + server_name(homeserver), + e.what() + }; +} + void ircd::m::bootstrap(homeserver &homeserver) try