From 22c69f47b8848474d7cc040e1b771e2a008dbdf2 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 1 Dec 2025 02:51:37 +0300 Subject: [PATCH 1/4] libstore: Use makeTempPath in optimizePath_ This was intended to be cherry-picked in 6aed9d877cfbe1e649b69d2f15b6aeccbfbb0f3a, but was left hanging. This is actually important for fixing [^]. emilazy let me know of this bad cherry-pick and its significance. [^]: https://github.com/NixOS/nix/issues/7273 Originally fixed by Lily Ballard in https://gerrit.lix.systems/c/lix/+/2100. (cherry picked from commit d888846b68dd5fad998b84c5cb6246b1b63398cd) --- src/libstore/optimise-store.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index 8f2878136..cbf8524d8 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -234,7 +234,7 @@ void LocalStore::optimisePath_( its timestamp back to 0. */ MakeReadOnly makeReadOnly(mustToggle ? dirOfPath : ""); - std::filesystem::path tempLink = fmt("%1%/.tmp-link-%2%-%3%", config->realStoreDir, getpid(), rand()); + std::filesystem::path tempLink = makeTempPath(config->realStoreDir.get(), ".tmp-link"); try { std::filesystem::create_hard_link(linkPath, tempLink); From f5473c9624334f36ffcd26b7df8db6f18a4a1858 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 1 Dec 2025 02:56:44 +0300 Subject: [PATCH 2/4] libstore: Actually correctly call remove in case rename fails (cherry picked from commit 1cc337bb5f7363a711d7bd7f4e28e2ecc54aa975) --- src/libstore/optimise-store.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index cbf8524d8..403c1d375 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -255,8 +255,12 @@ void LocalStore::optimisePath_( try { std::filesystem::rename(tempLink, path); } catch (std::filesystem::filesystem_error & e) { - std::filesystem::remove(tempLink); - printError("unable to unlink %1%", tempLink); + { + std::error_code ec; + remove(tempLink, ec); /* Clean up after ourselves. */ + if (ec) + printError("unable to unlink %1%: %2%", tempLink, ec.message()); + } if (e.code() == std::errc::too_many_links) { /* Some filesystems generate too many links on the rename, rather than on the original link. (Probably it From 3c01ff3148f5fda0467f96de7a07360ecb5de4eb Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 1 Dec 2025 03:00:45 +0300 Subject: [PATCH 3/4] libutil: Propagate error code in createSymlink (cherry picked from commit bf7c53f2d3e665720c371167b8934d50e818656b) --- src/libutil/file-system.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index fba92dc8e..5cd702193 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -730,11 +730,10 @@ Path makeTempPath(const Path & root, const Path & suffix) void createSymlink(const Path & target, const Path & link) { - try { - std::filesystem::create_symlink(target, link); - } catch (std::filesystem::filesystem_error & e) { - throw SysError("creating symlink '%1%' -> '%2%'", link, target); - } + std::error_code ec; + std::filesystem::create_symlink(target, link, ec); + if (ec) + throw SysError(ec.value(), "creating symlink '%1%' -> '%2%'", link, target); } void replaceSymlink(const std::filesystem::path & target, const std::filesystem::path & link) From f67bdae6a64c271690a0c7ce6de70f6956976225 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Mon, 1 Dec 2025 03:09:20 +0300 Subject: [PATCH 4/4] libutil: Make AutoDelete non-copyable and non-movable This is a good precaution, since we don't want to delete directories twice accidentally. (cherry picked from commit 40e3f5c0a471075d02e258e950c0f2c931b36177) --- src/libutil/include/nix/util/file-system.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh index 98b992472..ec289cfbe 100644 --- a/src/libutil/include/nix/util/file-system.hh +++ b/src/libutil/include/nix/util/file-system.hh @@ -287,6 +287,10 @@ class AutoDelete public: AutoDelete(); AutoDelete(const std::filesystem::path & p, bool recursive = true); + AutoDelete(AutoDelete &&) = delete; + AutoDelete(const AutoDelete &) = delete; + AutoDelete & operator=(AutoDelete &&) = delete; + AutoDelete & operator=(const AutoDelete &) = delete; ~AutoDelete(); void cancel();