Skip to content

Arti processes cannot share a cache_dir

According to the config docs

# Multiple processes can share the same cache_dir.  If they do, one of them
# will download directory information for all of the others.

but in practice, if you start multiple arti processes configured with the same empty or nonexistent cache_dir, many of them will fail on startup with errors like attempt to write a readonly database: Error code 8: Attempt to write a readonly database. This is because of a bug in the SqliteStore constructor:

  • if it finds that another process holds the lock, it will open a read-only DB connection
  • if it finds that the database doesn't exist, it will attempt to create it, even if it doesn't have read-write access

SqliteStore should only attempt to initialize the DB iff it's holding the lock (i.e. has write access).

/builds/gabi-250/arti/target/x86_64-unknown-linux-gnu/debug/arti: error: tor: internal error (bug): Error setting up the directory manager: Internal programming issue: internal error (bug) at crates/tor-dirmgr/src/err.rs:329:17: sqlite detected bug
   0: tor_error::internal::ie_backtrace::capture
             at /builds/gabi-250/arti/crates/tor-error/src/internal.rs:23:18
   1: tor_error::internal::Bug::new_inner
             at /builds/gabi-250/arti/crates/tor-error/src/internal.rs:107:24
   2: tor_error::internal::Bug::from_error
             at /builds/gabi-250/arti/crates/tor-error/src/internal.rs:123:9
   3: <tor_dirmgr::err::Error as core::convert::From<rusqlite::error::Error>>::from
             at /builds/gabi-250/arti/crates/tor-dirmgr/src/err.rs:329:17
   4: <core::result::Result<T,F> as core::ops::try_trait::FromResidual<core::result::Result<core::convert::Infallible,E>>>::from_residual
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/result.rs:2002:27
   5: tor_dirmgr::storage::sqlite::SqliteStore::check_schema
             at /builds/gabi-250/arti/crates/tor-dirmgr/src/storage/sqlite.rs:168:13
   6: tor_dirmgr::storage::sqlite::SqliteStore::from_conn
             at /builds/gabi-250/arti/crates/tor-dirmgr/src/storage/sqlite.rs:136:9
   7: tor_dirmgr::storage::sqlite::SqliteStore::from_path_and_mistrust
             at /builds/gabi-250/arti/crates/tor-dirmgr/src/storage/sqlite.rs:111:25
   8: tor_dirmgr::config::DirMgrConfig::open_store
             at /builds/gabi-250/arti/crates/tor-dirmgr/src/config.rs:269:13
   9: tor_dirmgr::DirMgrStore<R>::new
             at /builds/gabi-250/arti/crates/tor-dirmgr/src/lib.rs:135:41
  10: arti_client::client::TorClient<R>::create_inner
             at [CWD]-client/src/client.rs:611:13
  11: arti_client::builder::TorClientBuilder<R>::create_unbootstrapped_inner
             at [CWD]-client/src/builder.rs:245:44
  12: arti_client::builder::TorClientBuilder<R>::create_unbootstrapped
             at [CWD]-client/src/builder.rs:190:19
  13: arti::subcommands::hsc::prepare_service_discovery_key
             at src/subcommands/hsc.rs:104:18
  14: arti::subcommands::hsc::run
             at src/subcommands/hsc.rs:94:40
  15: arti::main_main
             at src/lib.rs:618:24
  16: arti::main
             at src/lib.rs:662:11
  17: arti::main
             at src/main.rs:47:5
  18: core::ops::function::FnOnce::call_once
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/ops/function.rs:250:5
  19: std::sys_common::backtrace::__rust_begin_short_backtrace
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/sys_common/backtrace.rs:134:18
  20: std::rt::lang_start::{{closure}}
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:166:18
  21: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/ops/function.rs:287:13
      std::panicking::try::do_call
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:485:40
      std::panicking::try
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:449:19
      std::panic::catch_unwind
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panic.rs:140:14
      std::rt::lang_start_internal::{{closure}}
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:148:48
      std::panicking::try::do_call
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:485:40
      std::panicking::try
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:449:19
      std::panic::catch_unwind
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panic.rs:140:14
      std::rt::lang_start_internal
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:148:20
  22: std::rt::lang_start
             at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:165:17
  23: main
  24: __libc_start_main
  25: _start
: attempt to write a readonly database: Error code 8: Attempt to write a readonly database

As a result, you can't reliably run multiple concurrent arti processes (see also #1496 (closed) and the test failures from !2275 (merged))

Edited by gabi-250