Skip to content

Commit

Permalink
Require that store is flush locked in order to restore.
Browse files Browse the repository at this point in the history
  • Loading branch information
evoskuil committed Mar 16, 2024
1 parent 97a2613 commit d1b18f9
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
6 changes: 3 additions & 3 deletions include/bitcoin/database/impl/store.ipp
Expand Up @@ -742,9 +742,9 @@ code CLASS::restore(const event_handler& handler) NOEXCEPT
return error::process_lock;
}

if (!flush_lock_.try_lock())
// Requires that the store is already flush locked (corrupted).
if (!flush_lock_.is_locked())
{
/* bool */ process_lock_.try_unlock();
transactor_mutex_.unlock();
return error::flush_lock;
}
Expand All @@ -770,7 +770,7 @@ code CLASS::restore(const event_handler& handler) NOEXCEPT
}
else if (file::is_directory(secondary))
{
// Clear invalid /heads and recover from /secondary.
// Clear invalid /heads, recover from /secondary, clone to /primary.
if (!file::clear_directory(heads)) ec = error::clear_directory;
else if (!file::remove(heads)) ec = error::remove_directory;
else if (!file::rename(secondary, heads)) ec = error::rename_directory;
Expand Down
19 changes: 17 additions & 2 deletions test/store.cpp
Expand Up @@ -44,6 +44,14 @@ BOOST_FIXTURE_TEST_SUITE(store_tests, store_setup_fixture)
// nop event handler.
const auto events = [](auto, auto){};

// flush lock file path from directory.
std::filesystem::path flush_lock_file(std::filesystem::path path)
{
path /= schema::locks::flush;
path += schema::ext::lock;
return path;
}

// construct
// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -441,12 +449,11 @@ BOOST_AUTO_TEST_CASE(store__restore__process_locked__success)
}
#endif

BOOST_AUTO_TEST_CASE(store__restore__flush_locked__flush_lock)
BOOST_AUTO_TEST_CASE(store__restore__no_flush_locked__flush_lock)
{
settings configuration{};
configuration.path = TEST_DIRECTORY;
test::map_store instance{ configuration };
BOOST_REQUIRE(test::create(instance.flush_lock_file()));
BOOST_REQUIRE_EQUAL(instance.restore(events), error::flush_lock);
}

Expand All @@ -456,6 +463,7 @@ BOOST_AUTO_TEST_CASE(store__restore__process_lock_file__missing_snapshot)
configuration.path = TEST_DIRECTORY;
test::map_store instance{ configuration };
BOOST_REQUIRE(test::create(instance.process_lock_file()));
BOOST_REQUIRE(test::create(flush_lock_file(configuration.path)));
BOOST_REQUIRE_EQUAL(instance.restore(events), error::missing_snapshot);
}

Expand All @@ -464,6 +472,7 @@ BOOST_AUTO_TEST_CASE(store__restore__failure__unlocks)
settings configuration{};
configuration.path = TEST_DIRECTORY;
test::map_store instance{ configuration };
BOOST_REQUIRE(test::create(flush_lock_file(configuration.path)));
BOOST_REQUIRE_NE(instance.restore(events), error::success);
BOOST_REQUIRE(!test::exists(instance.flush_lock_file()));
BOOST_REQUIRE(!test::exists(instance.process_lock_file()));
Expand All @@ -475,6 +484,7 @@ BOOST_AUTO_TEST_CASE(store__restore__no_backups__missing_snapshot)
settings configuration{};
configuration.path = TEST_DIRECTORY;
test::map_store instance{ configuration };
BOOST_REQUIRE(test::create(flush_lock_file(configuration.path)));
BOOST_REQUIRE_EQUAL(instance.restore_(), error::missing_snapshot);
}

Expand Down Expand Up @@ -513,6 +523,7 @@ BOOST_AUTO_TEST_CASE(store__restore__primary_closed__restore_table)
BOOST_REQUIRE(test::clear(configuration.path / schema::dir::primary));

// There are no backup index files to open.
BOOST_REQUIRE(test::create(flush_lock_file(configuration.path)));
BOOST_REQUIRE_EQUAL(instance.restore_(), error::restore_table);

// Rename /primary to /indexes and copy to /primary.
Expand All @@ -534,6 +545,7 @@ BOOST_AUTO_TEST_CASE(store__restore__secondary_closed__restore_table)
BOOST_REQUIRE(test::clear(configuration.path / schema::dir::secondary));

// There are no backup index files to open.
BOOST_REQUIRE(test::create(flush_lock_file(configuration.path)));
BOOST_REQUIRE_EQUAL(instance.restore_(), error::restore_table);

// No primary, so rename /secondary to /indexes.
Expand All @@ -555,6 +567,7 @@ BOOST_AUTO_TEST_CASE(store__restore__primary_secondary_loaded__restore_table)
BOOST_REQUIRE(test::clear(configuration.path / schema::dir::secondary));

// There are no backup index files to open.
BOOST_REQUIRE(test::create(flush_lock_file(configuration.path)));
BOOST_REQUIRE_EQUAL(instance.restore_(), error::restore_table);

// Rename /primary to /indexes and copy to /primary.
Expand All @@ -571,12 +584,14 @@ BOOST_AUTO_TEST_CASE(store__restore__snapshot__success_unlocks)
{
settings configuration{};
configuration.path = TEST_DIRECTORY;

test::map_store instance{ configuration };
BOOST_REQUIRE_EQUAL(instance.create(events), error::success);
BOOST_REQUIRE_EQUAL(instance.open(events), error::success);
BOOST_REQUIRE_EQUAL(instance.snapshot(events), error::success);
BOOST_REQUIRE(test::folder(configuration.path / schema::dir::primary));
BOOST_REQUIRE_EQUAL(instance.close(events), error::success);
BOOST_REQUIRE(test::create(flush_lock_file(configuration.path)));
BOOST_REQUIRE_EQUAL(instance.restore(events), error::success);
BOOST_REQUIRE(test::folder(configuration.path / schema::dir::primary));
////BOOST_REQUIRE(!test::folder(configuration.path / schema::dir::primary));
Expand Down

0 comments on commit d1b18f9

Please sign in to comment.