From 3c817d5bb997a3aaf906be6a5b249a58f3afedfe Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Tue, 19 Oct 2021 16:33:27 +0200 Subject: cas: implemented manifest update/upgrade --- zenstore/CAS.cpp | 80 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/zenstore/CAS.cpp b/zenstore/CAS.cpp index a43759283..a71e251e5 100644 --- a/zenstore/CAS.cpp +++ b/zenstore/CAS.cpp @@ -5,6 +5,9 @@ #include "compactcas.h" #include "filecas.h" +#include +#include +#include #include #include #include @@ -14,9 +17,6 @@ #include #include #include -#include -#include -#include #include @@ -108,15 +108,17 @@ private: CasContainerStrategy m_TinyStrategy; CasContainerStrategy m_SmallStrategy; FileCasStrategy m_LargeStrategy; - CbObject m_ManifestObject; - + CbObject m_ManifestObject; + enum class StorageScheme { - Legacy = 0, + Legacy = 0, WithCbManifest = 1 }; - StorageScheme m_StorageScheme = StorageScheme::Legacy; + StorageScheme m_StorageScheme = StorageScheme::Legacy; + + void UpdateManifest(bool IsNewStore); }; CasImpl::CasImpl() : m_TinyStrategy(m_Config), m_SmallStrategy(m_Config), m_LargeStrategy(m_Config) @@ -150,49 +152,55 @@ CasImpl::Initialize(const CasStoreConfiguration& InConfig) ManifestPath /= ".ucas_root"; std::error_code Ec; - BasicFile Marker; - Marker.Open(ManifestPath.c_str(), /* IsCreate */ false, Ec); + BasicFile ManifestFile; + ManifestFile.Open(ManifestPath.c_str(), /* IsCreate */ false, Ec); + + bool ManifestIsOk = false; if (Ec) { if (Ec == std::errc::no_such_file_or_directory) { IsNewStore = true; - - CbObjectWriter Cbo; - - Cbo << "id" << zen::Oid::NewOid(); - - Marker.Open(ManifestPath.c_str(), /* IsCreate */ true); - m_ManifestObject = Cbo.Save(); - - Marker.Write(m_ManifestObject.GetBuffer(), 0); } } else { - IoBuffer ManifestBuffer = Marker.ReadAll(); + IoBuffer ManifestBuffer = ManifestFile.ReadAll(); + ManifestFile.Close(); if (ManifestBuffer.Size() > 0 && ManifestBuffer.Data()[0] == '#') { - // Old-style manifest, does not contain any useful information (so we may as well update it?) - m_StorageScheme = StorageScheme::Legacy; + // Old-style manifest, does not contain any useful information, so we may as well update it } else { - CbObject Manifest{SharedBuffer(ManifestBuffer)}; + CbObject Manifest{SharedBuffer(ManifestBuffer)}; CbValidateError ValidationResult = ValidateCompactBinary(ManifestBuffer, CbValidateMode::All); if (ValidationResult == CbValidateError::None) { - m_ManifestObject = std::move(Manifest); + if (Manifest["id"]) + { + ManifestIsOk = true; + } } else { - ZEN_ERROR("Store manifest validation failed: {:#x}", ValidationResult); + ZEN_ERROR("Store manifest validation failed: {:#x}, will generate new manifest to recover", ValidationResult); + } + + if (ManifestIsOk) + { + m_ManifestObject = std::move(Manifest); } } } + + if (!ManifestIsOk) + { + UpdateManifest(true); + } } // Initialize payload storage @@ -201,6 +209,30 @@ CasImpl::Initialize(const CasStoreConfiguration& InConfig) m_SmallStrategy.Initialize("sobs", 4096, IsNewStore); } +void +CasImpl::UpdateManifest(bool IsNewStore) +{ + if (!m_ManifestObject) + { + CbObjectWriter Cbo; + Cbo << "id" << zen::Oid::NewOid() << "created" << DateTime::Now(); + m_ManifestObject = Cbo.Save(); + } + + // Write manifest to file + + std::filesystem::path ManifestPath = m_Config.RootDirectory; + ManifestPath /= ".ucas_root"; + + // This will throw on failure + + ZEN_TRACE("Writing new manifest to '{}'", ManifestPath); + + BasicFile Marker; + Marker.Open(ManifestPath.c_str(), /* IsCreate */ true); + Marker.Write(m_ManifestObject.GetBuffer(), 0); +} + CasStore::InsertResult CasImpl::InsertChunk(IoBuffer Chunk, const IoHash& ChunkHash) { -- cgit v1.2.3