Skip to content

Commit

Permalink
add format version check before restore (prusik)
Browse files Browse the repository at this point in the history
  • Loading branch information
ban-nobuhiro committed Nov 30, 2023
1 parent e9addd1 commit 32f495a
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 1 deletion.
30 changes: 29 additions & 1 deletion src/limestone/datastore_restore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,35 @@ status datastore::restore(std::string_view from, bool keep_backup) const noexcep
// prusik era
status datastore::restore(std::string_view from, std::vector<file_set_entry>& entries) {
VLOG_LP(log_debug) << "restore (from prusik) begin, from directory = " << from;
auto from_dir = boost::filesystem::path(std::string(from));

// log_dir version check
int manifest_count = 0;
for (auto & ent : entries) {
if (ent.destination_path().string() != internal::manifest_file_name) {
continue;
}
boost::filesystem::path src{ent.source_path()};
if (src.is_absolute()) {
// use it
} else {
src = from_dir / src;
}
if (!boost::filesystem::exists(src) || !boost::filesystem::is_regular_file(src)) {
LOG_LP(ERROR) << "file not found : file = " << src.string();
return status::err_not_found;
}
std::string ver_err;
if (!internal::is_supported_version(src, ver_err)) {
LOG_LP(ERROR) << ver_err;
return status::err_broken_data;
}
manifest_count++;
}
if (manifest_count < 1) { // XXX: change to != 1 ??
LOG_LP(ERROR) << "no manifest file in backup";
return status::err_broken_data;
}

// purge logdir
// FIXME: copied this code from (old) restore(), fix duplicate
Expand All @@ -88,7 +117,6 @@ status datastore::restore(std::string_view from, std::vector<file_set_entry>& en
}
}

auto from_dir = boost::filesystem::path(std::string(from));
for (auto & ent : entries) {
boost::filesystem::path src{ent.source_path()};
boost::filesystem::path dst{ent.destination_path()};
Expand Down
54 changes: 54 additions & 0 deletions test/limestone/log/log_dir_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,58 @@ TEST_F(log_dir_test, rotate_old_rejects_v0_logdir_missing_manifest) {
EXPECT_EQ(datastore_->restore(bk_path.string(), true), limestone::status::err_broken_data);
}

TEST_F(log_dir_test, rotate_prusik_ok_v1_dir) {
// setup backups
boost::filesystem::path bk_path = boost::filesystem::path(location) / "bk";
if (!boost::filesystem::create_directory(bk_path)) {
LOG(FATAL) << "cannot make directory";
}
create_file(bk_path / "epoch", "\x04\x00\x00\x00\x00\x00\x00\x00\x00");
create_file(bk_path / std::string(limestone::internal::manifest_file_name),
"{ \"format_version\": \"1.0\", \"persistent_format_version\": 1 }");
// setup entries
std::vector<limestone::api::file_set_entry> entries;
entries.emplace_back("epoch", "epoch", false);
entries.emplace_back(std::string(limestone::internal::manifest_file_name), std::string(limestone::internal::manifest_file_name), false);

gen_datastore();

EXPECT_EQ(datastore_->restore(bk_path.string(), entries), limestone::status::ok);
}

TEST_F(log_dir_test, rotate_prusik_rejects_unsupported_data) {
// setup backups
boost::filesystem::path bk_path = boost::filesystem::path(location) / "bk";
if (!boost::filesystem::create_directory(bk_path)) {
LOG(FATAL) << "cannot make directory";
}
create_file(bk_path / "epoch", "\x04\x00\x00\x00\x00\x00\x00\x00\x00");
create_file(bk_path / std::string(limestone::internal::manifest_file_name),
"{ \"format_version\": \"1.0\", \"persistent_format_version\": 2 }");
// setup entries
std::vector<limestone::api::file_set_entry> entries;
entries.emplace_back("epoch", "epoch", false);
entries.emplace_back(std::string(limestone::internal::manifest_file_name), std::string(limestone::internal::manifest_file_name), false);

gen_datastore();

EXPECT_EQ(datastore_->restore(bk_path.string(), entries), limestone::status::err_broken_data);
}

TEST_F(log_dir_test, rotate_prusik_rejects_v0_logdir_missing_manifest) {
// setup backups
boost::filesystem::path bk_path = boost::filesystem::path(location) / "bk";
if (!boost::filesystem::create_directory(bk_path)) {
LOG(FATAL) << "cannot make directory";
}
create_file(bk_path / "epoch", "\x04\x00\x00\x00\x00\x00\x00\x00\x00");
// setup entries
std::vector<limestone::api::file_set_entry> entries;
entries.emplace_back("epoch", "epoch", false);

gen_datastore();

EXPECT_EQ(datastore_->restore(bk_path.string(), entries), limestone::status::err_broken_data);
}

} // namespace limestone::testing

0 comments on commit 32f495a

Please sign in to comment.