From 034f59bbb9a8c6a5febfed042fa9119410a3f123 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Wed, 26 Mar 2025 01:06:03 +0100 Subject: [PATCH] libutil: writeFile variant for file descriptors `writeFile` lose its `sync` boolean flag to make things simpler. A new `writeFileAndSync` function is created and all call sites are converted to it. Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192 Signed-off-by: Raito Bezarius --- src/libstore/local-store.cc | 4 +-- src/libutil/file-system.cc | 35 ++++++++++++++++----- src/libutil/include/nix/util/file-system.hh | 13 ++++++-- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index e53cab2dc..00c1ac6dd 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -247,7 +247,7 @@ LocalStore::LocalStore(ref config) else if (curSchema == 0) { /* new store */ curSchema = nixSchemaVersion; openDB(*state, true); - writeFile(schemaPath, fmt("%1%", curSchema), 0666, true); + writeFileAndSync(schemaPath, fmt("%1%", curSchema), 0666); } else if (curSchema < nixSchemaVersion) { @@ -298,7 +298,7 @@ LocalStore::LocalStore(ref config) txn.commit(); } - writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true); + writeFileAndSync(schemaPath, fmt("%1%", nixSchemaVersion), 0666); lockFile(globalLock.get(), ltRead, true); } diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index fee2945ff..4c3a56e65 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -304,7 +304,7 @@ void readFile(const Path & path, Sink & sink, bool memory_map) } -void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync) +void writeFile(const Path & path, std::string_view s, mode_t mode) { AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT // TODO @@ -314,20 +314,39 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync) , mode)); if (!fd) throw SysError("opening file '%1%'", path); + + writeFile(fd, s, mode); + + /* Close explicitly to propagate the exceptions. */ + fd.close(); +} + +void writeFile(AutoCloseFD & fd, std::string_view s, mode_t mode) +{ + assert(fd); try { writeFull(fd.get(), s); } catch (Error & e) { - e.addTrace({}, "writing file '%1%'", path); + e.addTrace({}, "writing file '%1%'", fd.guessOrInventPath()); throw; } - if (sync) - fd.fsync(); - // Explicitly close to make sure exceptions are propagated. - fd.close(); - if (sync) - syncParent(path); } +void writeFileAndSync(const Path & path, std::string_view s, mode_t mode) +{ + { + AutoCloseFD fd{open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode)}; + if (!fd) + throw SysError("opening file '%1%'", path); + + writeFile(fd, s, mode); + fd.fsync(); + /* Close explicitly to ensure that exceptions are propagated. */ + fd.close(); + } + + syncParent(path); +} void writeFile(const Path & path, Source & source, mode_t mode, bool sync) { diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh index 0121745ab..77d5f2aa1 100644 --- a/src/libutil/include/nix/util/file-system.hh +++ b/src/libutil/include/nix/util/file-system.hh @@ -172,10 +172,10 @@ void readFile(const Path & path, Sink & sink, bool memory_map = true); /** * Write a string to a file. */ -void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false); -static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, bool sync = false) +void writeFile(const Path & path, std::string_view s, mode_t mode = 0666); +static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666) { - return writeFile(path.string(), s, mode, sync); + return writeFile(path.string(), s, mode); } void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false); @@ -184,6 +184,13 @@ static inline void writeFile(const std::filesystem::path & path, Source & source return writeFile(path.string(), source, mode, sync); } +void writeFile(AutoCloseFD & fd, std::string_view s, mode_t mode = 0666 ); + +/** + * Write a string to a file and flush the file and its parents direcotry to disk. + */ +void writeFileAndSync(const Path & path, std::string_view s, mode_t mode = 0666); + /** * Flush a path's parent directory to disk. */