0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 08:12:37 +01:00

ircd: Support read-only and write-avoid modes via conf item / command line.

This commit is contained in:
Jason Volk 2019-04-15 11:08:40 -07:00
parent 726f131cc2
commit f9025cebb9
8 changed files with 57 additions and 11 deletions

View file

@ -34,6 +34,8 @@ bool nodirect;
bool noaio;
bool no6;
bool norun;
bool read_only;
bool write_avoid;
const char *execute;
lgetopt opts[] =
{
@ -52,6 +54,8 @@ lgetopt opts[] =
{ "noaio", &noaio, lgetopt::BOOL, "Disable the AIO interface in favor of traditional syscalls. " },
{ "no6", &no6, lgetopt::BOOL, "Disable IPv6 operations" },
{ "norun", &norun, lgetopt::BOOL, "[debug & testing only] Initialize but never run the event loop." },
{ "ro", &read_only, lgetopt::BOOL, "Read-only mode. No writes to database allowed." },
{ "wa", &write_avoid, lgetopt::BOOL, "Like read-only mode, but writes permitted if triggered." },
{ nullptr, nullptr, lgetopt::STRING, nullptr },
};
@ -257,6 +261,13 @@ enable_coredumps()
void
applyargs()
{
if(read_only)
ircd::read_only.set("true");
// read_only implies write_avoid.
if(write_avoid || read_only)
ircd::write_avoid.set("true");
if(debugmode)
ircd::debugmode.set("true");
else

View file

@ -74,4 +74,6 @@ namespace ircd
extern conf::item<bool> restart;
extern conf::item<bool> debugmode;
extern conf::item<bool> read_only;
extern conf::item<bool> write_avoid;
}

View file

@ -183,7 +183,12 @@ try
fs::path(fs::DB)
};
if(fs::mkdir(dbdir))
if(!fs::is_dir(dbdir) && (ircd::read_only || ircd::write_avoid))
log::warning
{
log, "Not creating database directory `%s' in read-only/write-avoid mode.", dbdir
};
else if(fs::mkdir(dbdir))
log::notice
{
log, "Created new database directory at `%s'", dbdir
@ -964,7 +969,7 @@ try
}
,read_only
{
false
ircd::read_only
}
,env
{
@ -1213,7 +1218,7 @@ try
// If the directory does not exist, though rocksdb will create it, we can
// avoid scaring the user with an error log message if we just do that..
if(opts->create_if_missing && !fs::is_dir(path))
if(opts->create_if_missing && !fs::is_dir(path) && !ircd::write_avoid)
fs::mkdir(path);
// Announce attempt before usual point where exceptions are thrown
@ -1225,6 +1230,14 @@ try
columns.size()
};
if(read_only)
log::warning
{
log, "Database \"%s\" @ `%s' will be opened in read-only mode.",
this->name,
path,
};
// Open DB into ptr
rocksdb::DB *ptr;
if(read_only)
@ -7285,14 +7298,14 @@ ircd::db::make_dbopts(std::string optstr,
// RocksDB doesn't parse a read_only option, so we allow that to be added
// to open the database as read_only and then remove that from the string.
if(read_only)
*read_only = optstr_find_and_remove(optstr, "read_only=true;"s);
*read_only |= optstr_find_and_remove(optstr, "read_only=true;"s);
else
optstr_find_and_remove(optstr, "read_only=true;"s);
// We also allow the user to specify fsck=true to run a repair operation on
// the db. This may be expensive to do by default every startup.
if(fsck)
*fsck = optstr_find_and_remove(optstr, "fsck=true;"s);
*fsck |= optstr_find_and_remove(optstr, "fsck=true;"s);
else
optstr_find_and_remove(optstr, "fsck=true;"s);

View file

@ -17,6 +17,22 @@ namespace ircd
void main() noexcept;
}
decltype(ircd::write_avoid)
ircd::write_avoid
{
{ "name", "ircd.write_avoid" },
{ "default", false },
{ "persist", false },
};
decltype(ircd::read_only)
ircd::read_only
{
{ "name", "ircd.read_only" },
{ "default", false },
{ "persist", false },
};
decltype(ircd::debugmode)
ircd::debugmode
{

View file

@ -109,6 +109,9 @@ ircd::log::init()
if(!ircd::debugmode)
console_disable(level::DEBUG);
if(ircd::write_avoid)
return;
mkdir();
}

View file

@ -48,7 +48,8 @@ try
std::make_unique<modules>()
}
{
presence::set(me, "online", me_online_status_msg);
if(!ircd::write_avoid)
presence::set(me, "online", me_online_status_msg);
if(room::state::disable_history)
log::warning
@ -83,7 +84,7 @@ noexcept try
{
m::sync::pool.join();
if(!std::current_exception())
if(!std::uncaught_exceptions() && !ircd::write_avoid)
presence::set(me, "offline", me_offline_status_msg);
}
catch(const m::error &e)

View file

@ -121,7 +121,7 @@ try
reinterpret_cast<char *>(key.get()), SK_SZ
};
if(!fs::exists(filename))
if(!fs::exists(filename) && !ircd::write_avoid)
{
throw_on_error
{

View file

@ -90,7 +90,7 @@ init_my_tls_crt()
fs::path_string(certificate_path_parts)
};
if(!fs::exists(private_key_file))
if(!fs::exists(private_key_file) && !ircd::write_avoid)
{
log::warning
{
@ -121,7 +121,7 @@ init_my_tls_crt()
*/
const json::object config{};
if(!fs::exists(cert_file))
if(!fs::exists(cert_file) && !ircd::write_avoid)
{
const json::object &certificate
{
@ -248,7 +248,7 @@ init_my_ed25519()
})
};
if(fs::exists(sk_file))
if(fs::exists(sk_file) || ircd::write_avoid)
log::info
{
m::log, "Using ed25519 secret key @ `%s'", sk_file