From 535ffb70546eb10635e56bf266f38599f3034279 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Tue, 10 Sep 2024 17:07:06 +0200 Subject: validate oplog before opening - if invalid, warn and wipe oplog (#153) --- CHANGELOG.md | 1 + src/zenserver/projectstore/projectstore.cpp | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21bff4613..02d0201c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## - Bugfix: Fix race condition in zenserver during batched fetch of small cache chunks (<=1024b) resulting in missing rawhash/rawsize in the response. UE-223703 - Improvement: Don't add batch overhead if we are only going to put once cache value in a request +- Improvement: Validate oplog log file and wipe state if it is corrupt before attempting to open ## 5.5.6 - Bugfix: Make sure `noexcept` functions does not leak exceptions via ASSERT statements which causes crash via abort diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp index d5570e8d4..b0d2554d6 100644 --- a/src/zenserver/projectstore/projectstore.cpp +++ b/src/zenserver/projectstore/projectstore.cpp @@ -351,6 +351,8 @@ struct ProjectStore::OplogStorage : public RefCounted { return std::filesystem::exists(GetLogPath(BasePath)) && std::filesystem::exists(GetBlobsPath(BasePath)); } + [[nodiscard]] bool IsValid() const { return IsValid(m_OplogStoragePath); } + [[nodiscard]] static bool IsValid(const std::filesystem::path& BasePath) { return TCasLogFile::IsValid(BasePath); } static bool Delete(const std::filesystem::path& BasePath) { return DeleteDirectories(BasePath); } @@ -941,8 +943,16 @@ ProjectStore::Oplog::Oplog(std::string_view Id, { using namespace std::literals; - m_Storage = new OplogStorage(this, m_BasePath); - const bool StoreExists = m_Storage->Exists(); + m_Storage = new OplogStorage(this, m_BasePath); + bool StoreExists = m_Storage->Exists(); + if (StoreExists) + { + if (!m_Storage->IsValid()) + { + ZEN_WARN("Invalid oplog found at '{}'. Wiping state for oplog.", m_BasePath); + StoreExists = false; + } + } m_Storage->Open(/* IsCreate */ !StoreExists); m_TempPath = m_BasePath / "temp"sv; m_MetaPath = m_BasePath / "ops.meta"sv; -- cgit v1.2.3