aboutsummaryrefslogtreecommitdiff
path: root/src/zenstore
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-03-13 10:33:40 +0100
committerGitHub Enterprise <[email protected]>2024-03-13 10:33:40 +0100
commit5fd1bdfafcd1e44162a1a4a978de775660c378a6 (patch)
treeb92b9cc595477075bd02320d0948c2f11e0c0717 /src/zenstore
parentupdates to signing (diff)
downloadzen-5fd1bdfafcd1e44162a1a4a978de775660c378a6.tar.xz
zen-5fd1bdfafcd1e44162a1a4a978de775660c378a6.zip
fix potential partially written files (#2)
* Make sure WriteFile() does not leave incomplete files * use TemporaryFile and MoveTemporaryIntoPlace to avoid leaving partial files on error
Diffstat (limited to 'src/zenstore')
-rw-r--r--src/zenstore/cas.cpp14
-rw-r--r--src/zenstore/compactcas.cpp15
-rw-r--r--src/zenstore/filecas.cpp15
3 files changed, 36 insertions, 8 deletions
diff --git a/src/zenstore/cas.cpp b/src/zenstore/cas.cpp
index f1a141ca0..4f137744b 100644
--- a/src/zenstore/cas.cpp
+++ b/src/zenstore/cas.cpp
@@ -214,9 +214,19 @@ CasImpl::UpdateManifest()
ZEN_TRACE("Writing new manifest to '{}'", ManifestPath);
- BasicFile Marker;
- Marker.Open(ManifestPath.c_str(), BasicFile::Mode::kTruncate);
+ TemporaryFile Marker;
+ std::error_code Ec;
+ Marker.CreateTemporary(ManifestPath.parent_path(), Ec);
+ if (Ec)
+ {
+ throw std::system_error(Ec, fmt::format("Failed to create temp file for cas manifest at '{}'", ManifestPath));
+ }
Marker.Write(m_ManifestObject.GetBuffer(), 0);
+ Marker.MoveTemporaryIntoPlace(ManifestPath, Ec);
+ if (Ec)
+ {
+ throw std::system_error(Ec, fmt::format("Failed to move temp file '{}' to '{}'", Marker.GetPath(), ManifestPath));
+ }
}
CasStore::InsertResult
diff --git a/src/zenstore/compactcas.cpp b/src/zenstore/compactcas.cpp
index c8fb41ffc..17cf20e35 100644
--- a/src/zenstore/compactcas.cpp
+++ b/src/zenstore/compactcas.cpp
@@ -910,8 +910,13 @@ CasContainerStrategy::MakeIndexSnapshot()
}
}
- BasicFile ObjectIndexFile;
- ObjectIndexFile.Open(IndexPath, BasicFile::Mode::kTruncate);
+ TemporaryFile ObjectIndexFile;
+ std::error_code Ec;
+ ObjectIndexFile.CreateTemporary(IndexPath.parent_path(), Ec);
+ if (Ec)
+ {
+ throw std::system_error(Ec, fmt::format("Failed to create temp file for index snapshot at '{}'", IndexPath));
+ }
CasDiskIndexHeader Header = {.EntryCount = Entries.size(),
.LogPosition = IndexLogPosition,
.PayloadAlignment = gsl::narrow<uint32_t>(m_PayloadAlignment)};
@@ -921,7 +926,11 @@ CasContainerStrategy::MakeIndexSnapshot()
ObjectIndexFile.Write(&Header, sizeof(CasDiskIndexHeader), 0);
ObjectIndexFile.Write(Entries.data(), Entries.size() * sizeof(CasDiskIndexEntry), sizeof(CasDiskIndexHeader));
ObjectIndexFile.Flush();
- ObjectIndexFile.Close();
+ ObjectIndexFile.MoveTemporaryIntoPlace(IndexPath, Ec);
+ if (Ec)
+ {
+ throw std::system_error(Ec, fmt::format("Failed to move temp file '{}' to '{}'", ObjectIndexFile.GetPath(), IndexPath));
+ }
EntryCount = Entries.size();
m_LogFlushPosition = IndexLogPosition;
}
diff --git a/src/zenstore/filecas.cpp b/src/zenstore/filecas.cpp
index af0a3a176..428183827 100644
--- a/src/zenstore/filecas.cpp
+++ b/src/zenstore/filecas.cpp
@@ -1179,8 +1179,13 @@ FileCasStrategy::MakeIndexSnapshot()
}
}
- BasicFile ObjectIndexFile;
- ObjectIndexFile.Open(IndexPath, BasicFile::Mode::kTruncate);
+ TemporaryFile ObjectIndexFile;
+ std::error_code Ec;
+ ObjectIndexFile.CreateTemporary(IndexPath.parent_path(), Ec);
+ if (Ec)
+ {
+ throw std::system_error(Ec, fmt::format("Failed to create temp file for index snapshot at '{}'", IndexPath));
+ }
filecas::impl::FileCasIndexHeader Header = {.EntryCount = Entries.size(), .LogPosition = IndexLogPosition};
Header.Checksum = filecas::impl::FileCasIndexHeader::ComputeChecksum(Header);
@@ -1188,7 +1193,11 @@ FileCasStrategy::MakeIndexSnapshot()
ObjectIndexFile.Write(&Header, sizeof(filecas::impl::FileCasIndexHeader), 0);
ObjectIndexFile.Write(Entries.data(), Entries.size() * sizeof(FileCasIndexEntry), sizeof(filecas::impl::FileCasIndexHeader));
ObjectIndexFile.Flush();
- ObjectIndexFile.Close();
+ ObjectIndexFile.MoveTemporaryIntoPlace(IndexPath, Ec);
+ if (Ec)
+ {
+ throw std::system_error(Ec, fmt::format("Failed to move temp file '{}' to '{}'", ObjectIndexFile.GetPath(), IndexPath));
+ }
EntryCount = Entries.size();
m_LogFlushPosition = IndexLogPosition;
}